Changes in uspace/srv/hid/fb/fb.c [9934f7d:c6f08726] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/fb.c
r9934f7d rc6f08726 49 49 #include <ipc/ns.h> 50 50 #include <ipc/services.h> 51 #include < kernel/errno.h>52 #include < kernel/genarch/fb/visuals.h>51 #include <errno.h> 52 #include <abi/fb/visuals.h> 53 53 #include <io/color.h> 54 54 #include <io/style.h> … … 59 59 #include <byteorder.h> 60 60 #include <io/screenbuffer.h> 61 #include <imgmap.h> 61 62 #include "font-8x16.h" 62 63 #include "fb.h" 63 64 #include "main.h" 64 #include "ppm.h"65 65 #include "pointer.xbm" 66 66 #include "pointer_mask.xbm" 67 67 68 68 // FIXME: remove this header 69 #include < kernel/ipc/ipc_methods.h>69 #include <abi/ipc/methods.h> 70 70 71 71 #define DEFAULT_BGCOLOR 0xf0f0f0 … … 76 76 #define MAX_ANIM_LEN 8 77 77 #define MAX_ANIMATIONS 4 78 #define MAX_ PIXMAPS 256 /**< Maximum number of saved pixmaps */78 #define MAX_IMGMAPS 256 /**< Maximum number of saved image maps */ 79 79 #define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */ 80 80 … … 160 160 unsigned int pos; 161 161 unsigned int animlen; 162 unsigned int pixmaps[MAX_ANIM_LEN];162 unsigned int imgmaps[MAX_ANIM_LEN]; 163 163 } animation_t; 164 164 … … 166 166 static bool anims_enabled; 167 167 168 typedef struct { 169 unsigned int width; 170 unsigned int height; 171 uint8_t *data; 172 } pixmap_t; 173 174 static pixmap_t pixmaps[MAX_PIXMAPS]; 168 static imgmap_t *imgmaps[MAX_IMGMAPS]; 175 169 static viewport_t viewports[128]; 176 170 … … 212 206 static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, 213 207 unsigned int row); 214 215 208 216 209 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) … … 875 868 } 876 869 877 878 870 /** Show cursor if cursor showing is enabled 879 871 * … … 888 880 } 889 881 890 891 882 /** Invert cursor, if it is enabled 892 883 * … … 899 890 cursor_show(vport); 900 891 } 901 902 892 903 893 /** Draw character at given position relative to viewport … … 981 971 } 982 972 983 984 static void putpixel_pixmap(void *data, unsigned int x, unsigned int y, uint32_t color) 985 { 986 int pm = *((int *) data); 987 pixmap_t *pmap = &pixmaps[pm]; 988 unsigned int pos = (y * pmap->width + x) * screen.pixelbytes; 989 990 screen.rgb_conv(&pmap->data[pos], color); 991 } 992 993 994 static void putpixel(void *data, unsigned int x, unsigned int y, uint32_t color) 995 { 996 viewport_t *vport = (viewport_t *) data; 973 static void putpixel(viewport_t *vport, unsigned int x, unsigned int y, 974 uint32_t color) 975 { 997 976 unsigned int dx = vport->x + x; 998 977 unsigned int dy = vport->y + y; … … 1001 980 } 1002 981 1003 1004 /** Return first free pixmap 1005 * 1006 */ 1007 static int find_free_pixmap(void) 982 /** Draw image map 983 * 984 * @param[in] img Image map. 985 * @param[in] sx Coordinate of upper left corner. 986 * @param[in] sy Coordinate of upper left corner. 987 * @param[in] maxwidth Maximum allowed width for picture. 988 * @param[in] maxheight Maximum allowed height for picture. 989 * @param[in] vport Viewport. 990 * 991 * @return EOK on success. 992 * 993 */ 994 static int imgmap_draw(imgmap_t *img, unsigned int sx, unsigned int sy, 995 unsigned int maxwidth, unsigned int maxheight, void *vport) 996 { 997 if (img->visual != VISUAL_BGR_8_8_8) 998 return EINVAL; 999 1000 uint8_t *data = (uint8_t *) img->data; 1001 1002 for (sysarg_t y = 0; y < img->height; y++) { 1003 for (sysarg_t x = 0; x < img->width; x++) { 1004 if ((x > maxwidth) || (y > maxheight)) { 1005 data += 3; 1006 continue; 1007 } 1008 1009 uint32_t color = (data[2] << 16) + (data[1] << 8) + data[0]; 1010 1011 putpixel(vport, sx + x, sy + y, color); 1012 data += 3; 1013 } 1014 } 1015 1016 return EOK; 1017 } 1018 1019 /** Return first free image map 1020 * 1021 */ 1022 static int find_free_imgmap(void) 1008 1023 { 1009 1024 unsigned int i; 1010 1025 1011 for (i = 0; i < MAX_ PIXMAPS; i++)1012 if (! pixmaps[i].data)1026 for (i = 0; i < MAX_IMGMAPS; i++) 1027 if (!imgmaps[i]) 1013 1028 return i; 1014 1029 … … 1016 1031 } 1017 1032 1018 1019 /** Create a new pixmap and return appropriate ID 1020 * 1021 */ 1022 static int shm2pixmap(unsigned char *shm, size_t size) 1023 { 1024 int pm; 1025 pixmap_t *pmap; 1026 1027 pm = find_free_pixmap(); 1028 if (pm == -1) 1033 /** Create a new image map and return appropriate ID 1034 * 1035 */ 1036 static int shm2imgmap(imgmap_t *shm, size_t size) 1037 { 1038 int im = find_free_imgmap(); 1039 if (im == -1) 1029 1040 return ELIMIT; 1030 1041 1031 pmap = &pixmaps[pm]; 1032 1033 if (ppm_get_data(shm, size, &pmap->width, &pmap->height)) 1034 return EINVAL; 1035 1036 pmap->data = malloc(pmap->width * pmap->height * screen.pixelbytes); 1037 if (!pmap->data) 1042 imgmap_t *imap = malloc(size); 1043 if (!imap) 1038 1044 return ENOMEM; 1039 1045 1040 ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, putpixel_pixmap, (void *) &pm); 1041 1042 return pm; 1043 } 1044 1046 memcpy(imap, shm, size); 1047 imgmaps[im] = imap; 1048 return im; 1049 } 1045 1050 1046 1051 /** Handle shared memory communication calls 1047 1052 * 1048 * Protocol for drawing pixmaps:1053 * Protocol for drawing image maps: 1049 1054 * - FB_PREPARE_SHM(client shm identification) 1050 1055 * - IPC_M_AS_AREA_SEND 1051 * - FB_DRAW_ PPM(startx, starty)1056 * - FB_DRAW_IMGMAP(startx, starty) 1052 1057 * - FB_DROP_SHM 1053 1058 * … … 1071 1076 static size_t intersize = 0; 1072 1077 1073 static unsigned char*shm = NULL;1078 static imgmap_t *shm = NULL; 1074 1079 static sysarg_t shm_id = 0; 1075 1080 static size_t shm_size; … … 1093 1098 return false; 1094 1099 } 1100 1095 1101 shm = dest; 1096 1097 if (shm[0] != 'P')1098 return false;1099 1100 1102 return true; 1101 1103 } else { … … 1107 1109 if (shm_id) 1108 1110 retval = EBUSY; 1109 else 1111 else 1110 1112 shm_id = IPC_GET_ARG1(*call); 1111 1113 break; 1112 1113 1114 case FB_DROP_SHM: 1114 1115 if (shm) { … … 1118 1119 shm_id = 0; 1119 1120 break; 1120 1121 case FB_SHM2PIXMAP: 1121 case FB_SHM2IMGMAP: 1122 1122 if (!shm) { 1123 1123 retval = EINVAL; 1124 1124 break; 1125 1125 } 1126 retval = shm2 pixmap(shm, shm_size);1127 break; 1128 case FB_DRAW_ PPM:1126 retval = shm2imgmap(shm, shm_size); 1127 break; 1128 case FB_DRAW_IMGMAP: 1129 1129 if (!shm) { 1130 1130 retval = EINVAL; 1131 1131 break; 1132 1132 } 1133 1133 1134 x = IPC_GET_ARG1(*call); 1134 1135 y = IPC_GET_ARG2(*call); … … 1139 1140 } 1140 1141 1141 ppm_draw(shm, shm_size, IPC_GET_ARG1(*call),1142 IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *)vport);1142 imgmap_draw(shm, IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), 1143 vport->width - x, vport->height - y, vport); 1143 1144 break; 1144 1145 case FB_DRAW_TEXT_DATA: … … 1167 1168 if (handled) 1168 1169 async_answer_0(callid, retval); 1170 1169 1171 return handled; 1170 1172 } 1171 1173 1172 1173 static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap) 1174 static void copy_vp_to_imgmap(viewport_t *vport, imgmap_t *imap) 1174 1175 { 1175 1176 unsigned int width = vport->width; … … 1178 1179 if (width + vport->x > screen.xres) 1179 1180 width = screen.xres - vport->x; 1181 1180 1182 if (height + vport->y > screen.yres) 1181 1183 height = screen.yres - vport->y; 1182 1184 1183 unsigned int realwidth = pmap->width <= width ? pmap->width : width;1184 unsigned int realheight = pmap->height <= height ? pmap->height : height;1185 unsigned int realwidth = imap->width <= width ? imap->width : width; 1186 unsigned int realheight = imap->height <= height ? imap->height : height; 1185 1187 1186 1188 unsigned int srcrowsize = vport->width * screen.pixelbytes; … … 1190 1192 for (y = 0; y < realheight; y++) { 1191 1193 unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; 1192 memcpy(pmap->data + srcrowsize * y, screen.fb_addr + tmp, realrowsize); 1193 } 1194 } 1195 1196 1197 /** Save viewport to pixmap 1198 * 1199 */ 1200 static int save_vp_to_pixmap(viewport_t *vport) 1201 { 1202 int pm; 1203 pixmap_t *pmap; 1204 1205 pm = find_free_pixmap(); 1206 if (pm == -1) 1194 memcpy(imap->data + srcrowsize * y, screen.fb_addr + tmp, realrowsize); 1195 } 1196 } 1197 1198 /** Save viewport to image map 1199 * 1200 */ 1201 static int save_vp_to_imgmap(viewport_t *vport) 1202 { 1203 int im = find_free_imgmap(); 1204 if (im == -1) 1207 1205 return ELIMIT; 1208 1206 1209 pmap = &pixmaps[pm];1210 pmap->data = malloc(screen.pixelbytes * vport->width * vport->height);1211 if (! pmap->data)1207 size_t size = screen.pixelbytes * vport->width * vport->height; 1208 imgmap_t *imap = malloc(sizeof(imgmap_t) + size); 1209 if (!imap) 1212 1210 return ENOMEM; 1213 1211 1214 pmap->width = vport->width; 1215 pmap->height = vport->height; 1216 1217 copy_vp_to_pixmap(vport, pmap); 1218 1219 return pm; 1220 } 1221 1222 1223 /** Draw pixmap on screen 1224 * 1225 * @param vp Viewport to draw on 1226 * @param pm Pixmap identifier 1227 * 1228 */ 1229 static int draw_pixmap(int vp, int pm) 1230 { 1231 pixmap_t *pmap = &pixmaps[pm]; 1212 imap->size = sizeof(imgmap_t) + size; 1213 imap->width = vport->width; 1214 imap->height = vport->height; 1215 imap->visual = (visual_t) -1; 1216 1217 copy_vp_to_imgmap(vport, imap); 1218 imgmaps[im] = imap; 1219 return im; 1220 } 1221 1222 /** Draw image map to screen 1223 * 1224 * @param vp Viewport to draw to 1225 * @param im Image map identifier 1226 * 1227 */ 1228 static int draw_imgmap(int vp, int im) 1229 { 1230 imgmap_t *imap = imgmaps[im]; 1231 if (!imap) 1232 return EINVAL; 1233 1232 1234 viewport_t *vport = &viewports[vp]; 1233 1235 … … 1237 1239 if (width + vport->x > screen.xres) 1238 1240 width = screen.xres - vport->x; 1241 1239 1242 if (height + vport->y > screen.yres) 1240 1243 height = screen.yres - vport->y; 1241 1244 1242 if (!pmap->data)1243 return EINVAL;1244 1245 unsigned int realwidth = pmap->width <= width ? pmap->width : width;1246 unsigned int realheight = pmap->height <= height ? pmap->height : height;1247 1248 unsigned int srcrowsize = vport->width * screen.pixelbytes;1249 unsigned int realrowsize = realwidth * screen.pixelbytes;1250 1251 unsigned int y;1252 for (y = 0; y < realheight; y++) {1253 unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;1254 memcpy(screen.fb_addr + tmp, pmap->data + y * srcrowsize, realrowsize);1255 }1245 unsigned int realwidth = imap->width <= width ? imap->width : width; 1246 unsigned int realheight = imap->height <= height ? imap->height : height; 1247 1248 if (imap->visual == (visual_t) -1) { 1249 unsigned int srcrowsize = vport->width * screen.pixelbytes; 1250 unsigned int realrowsize = realwidth * screen.pixelbytes; 1251 1252 unsigned int y; 1253 for (y = 0; y < realheight; y++) { 1254 unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; 1255 memcpy(screen.fb_addr + tmp, imap->data + y * srcrowsize, realrowsize); 1256 } 1257 } else 1258 imgmap_draw(imap, 0, 0, realwidth, realheight, vport); 1256 1259 1257 1260 return EOK; 1258 1261 } 1259 1260 1262 1261 1263 /** Tick animation one step forward … … 1277 1279 continue; 1278 1280 1279 draw_ pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]);1281 draw_imgmap(animations[i].vp, animations[i].imgmaps[animations[i].pos]); 1280 1282 animations[i].pos = (animations[i].pos + 1) % animations[i].animlen; 1281 1283 } … … 1287 1289 static bool pointer_shown, pointer_enabled; 1288 1290 static int pointer_vport = -1; 1289 static int pointer_ pixmap = -1;1291 static int pointer_imgmap = -1; 1290 1292 1291 1293 … … 1310 1312 } 1311 1313 1312 if (pointer_ pixmap == -1)1313 pointer_ pixmap = save_vp_to_pixmap(&viewports[pointer_vport]);1314 if (pointer_imgmap == -1) 1315 pointer_imgmap = save_vp_to_imgmap(&viewports[pointer_vport]); 1314 1316 else 1315 copy_vp_to_ pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);1317 copy_vp_to_imgmap(&viewports[pointer_vport], imgmaps[pointer_imgmap]); 1316 1318 1317 1319 /* Draw mouse pointer. */ … … 1338 1340 /* Restore image under the pointer. */ 1339 1341 if (pointer_shown) { 1340 draw_ pixmap(pointer_vport, pointer_pixmap);1342 draw_imgmap(pointer_vport, pointer_imgmap); 1341 1343 pointer_shown = 0; 1342 1344 } … … 1393 1395 animations[i].initialized = 0; 1394 1396 break; 1395 case FB_ANIM_ADD PIXMAP:1397 case FB_ANIM_ADDIMGMAP: 1396 1398 i = IPC_GET_ARG1(*call); 1397 1399 if (i >= MAX_ANIMATIONS || i < 0 || … … 1405 1407 } 1406 1408 newval = IPC_GET_ARG2(*call); 1407 if (newval < 0 || newval > MAX_ PIXMAPS ||1408 ! pixmaps[newval].data) {1409 if (newval < 0 || newval > MAX_IMGMAPS || 1410 !imgmaps[newval]) { 1409 1411 retval = EINVAL; 1410 1412 break; 1411 1413 } 1412 animations[i]. pixmaps[animations[i].animlen++] = newval;1414 animations[i].imgmaps[animations[i].animlen++] = newval; 1413 1415 break; 1414 1416 case FB_ANIM_CHGVP: … … 1449 1451 } 1450 1452 1451 1452 /** Handler for messages concerning pixmap handling 1453 * 1454 */ 1455 static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp) 1453 /** Handler for messages concerning image map handling 1454 * 1455 */ 1456 static int imgmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp) 1456 1457 { 1457 1458 bool handled = true; … … 1460 1461 1461 1462 switch (IPC_GET_IMETHOD(*call)) { 1462 case FB_VP_DRAW_ PIXMAP:1463 case FB_VP_DRAW_IMGMAP: 1463 1464 nvp = IPC_GET_ARG1(*call); 1464 1465 if (nvp == -1) 1465 1466 nvp = vp; 1467 1466 1468 if (nvp < 0 || nvp >= MAX_VIEWPORTS || 1467 1469 !viewports[nvp].initialized) { 1468 1470 retval = EINVAL; 1469 1471 break; 1470 1472 } 1473 1471 1474 i = IPC_GET_ARG2(*call); 1472 retval = draw_ pixmap(nvp, i);1473 break; 1474 case FB_VP2 PIXMAP:1475 retval = draw_imgmap(nvp, i); 1476 break; 1477 case FB_VP2IMGMAP: 1475 1478 nvp = IPC_GET_ARG1(*call); 1476 1479 if (nvp == -1) 1477 1480 nvp = vp; 1481 1478 1482 if (nvp < 0 || nvp >= MAX_VIEWPORTS || 1479 !viewports[nvp].initialized)1483 !viewports[nvp].initialized) { 1480 1484 retval = EINVAL; 1481 else 1482 retval = save_vp_to_pixmap(&viewports[nvp]); 1483 break; 1484 case FB_DROP_PIXMAP: 1485 break; 1486 } 1487 1488 retval = save_vp_to_imgmap(&viewports[nvp]); 1489 break; 1490 case FB_DROP_IMGMAP: 1485 1491 i = IPC_GET_ARG1(*call); 1486 if (i >= MAX_ PIXMAPS) {1492 if (i >= MAX_IMGMAPS) { 1487 1493 retval = EINVAL; 1488 1494 break; 1489 1495 } 1490 if (pixmaps[i].data) { 1491 free(pixmaps[i].data); 1492 pixmaps[i].data = NULL; 1493 } 1496 1497 if (imgmaps[i]) { 1498 free(imgmaps[i]); 1499 imgmaps[i] = NULL; 1500 } 1501 1494 1502 break; 1495 1503 default: … … 1616 1624 continue; 1617 1625 1618 if ( pixmap_handle(callid, &call, vp))1626 if (imgmap_handle(callid, &call, vp)) 1619 1627 continue; 1620 1628
Note:
See TracChangeset
for help on using the changeset viewer.