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