Changes in uspace/srv/hid/fb/fb.c [c6f08726:9934f7d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/fb.c
rc6f08726 r9934f7d 49 49 #include <ipc/ns.h> 50 50 #include <ipc/services.h> 51 #include < errno.h>52 #include < abi/fb/visuals.h>51 #include <kernel/errno.h> 52 #include <kernel/genarch/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>62 61 #include "font-8x16.h" 63 62 #include "fb.h" 64 63 #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 < abi/ipc/methods.h>69 #include <kernel/ipc/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_ IMGMAPS 256 /**< Maximum number of saved imagemaps */78 #define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */ 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 imgmaps[MAX_ANIM_LEN];162 unsigned int pixmaps[MAX_ANIM_LEN]; 163 163 } animation_t; 164 164 … … 166 166 static bool anims_enabled; 167 167 168 static imgmap_t *imgmaps[MAX_IMGMAPS]; 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]; 169 175 static viewport_t viewports[128]; 170 176 … … 206 212 static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, 207 213 unsigned int row); 214 208 215 209 216 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) … … 868 875 } 869 876 877 870 878 /** Show cursor if cursor showing is enabled 871 879 * … … 880 888 } 881 889 890 882 891 /** Invert cursor, if it is enabled 883 892 * … … 890 899 cursor_show(vport); 891 900 } 901 892 902 893 903 /** Draw character at given position relative to viewport … … 971 981 } 972 982 973 static void putpixel(viewport_t *vport, unsigned int x, unsigned int y, 974 uint32_t color) 975 { 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; 976 997 unsigned int dx = vport->x + x; 977 998 unsigned int dy = vport->y + y; … … 980 1001 } 981 1002 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) 1003 1004 /** Return first free pixmap 1005 * 1006 */ 1007 static int find_free_pixmap(void) 1008 { 1009 unsigned int i; 1010 1011 for (i = 0; i < MAX_PIXMAPS; i++) 1012 if (!pixmaps[i].data) 1013 return i; 1014 1015 return -1; 1016 } 1017 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) 1029 return ELIMIT; 1030 1031 pmap = &pixmaps[pm]; 1032 1033 if (ppm_get_data(shm, size, &pmap->width, &pmap->height)) 998 1034 return EINVAL; 999 1035 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) 1023 { 1024 unsigned int i; 1025 1026 for (i = 0; i < MAX_IMGMAPS; i++) 1027 if (!imgmaps[i]) 1028 return i; 1029 1030 return -1; 1031 } 1032 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) 1040 return ELIMIT; 1041 1042 imgmap_t *imap = malloc(size); 1043 if (!imap) 1036 pmap->data = malloc(pmap->width * pmap->height * screen.pixelbytes); 1037 if (!pmap->data) 1044 1038 return ENOMEM; 1045 1039 1046 memcpy(imap, shm, size); 1047 imgmaps[im] = imap; 1048 return im; 1049 } 1040 ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, putpixel_pixmap, (void *) &pm); 1041 1042 return pm; 1043 } 1044 1050 1045 1051 1046 /** Handle shared memory communication calls 1052 1047 * 1053 * Protocol for drawing imagemaps:1048 * Protocol for drawing pixmaps: 1054 1049 * - FB_PREPARE_SHM(client shm identification) 1055 1050 * - IPC_M_AS_AREA_SEND 1056 * - FB_DRAW_ IMGMAP(startx, starty)1051 * - FB_DRAW_PPM(startx, starty) 1057 1052 * - FB_DROP_SHM 1058 1053 * … … 1076 1071 static size_t intersize = 0; 1077 1072 1078 static imgmap_t*shm = NULL;1073 static unsigned char *shm = NULL; 1079 1074 static sysarg_t shm_id = 0; 1080 1075 static size_t shm_size; … … 1098 1093 return false; 1099 1094 } 1095 shm = dest; 1100 1096 1101 shm = dest; 1097 if (shm[0] != 'P') 1098 return false; 1099 1102 1100 return true; 1103 1101 } else { … … 1109 1107 if (shm_id) 1110 1108 retval = EBUSY; 1111 else 1109 else 1112 1110 shm_id = IPC_GET_ARG1(*call); 1113 1111 break; 1112 1114 1113 case FB_DROP_SHM: 1115 1114 if (shm) { … … 1119 1118 shm_id = 0; 1120 1119 break; 1121 case FB_SHM2IMGMAP: 1120 1121 case FB_SHM2PIXMAP: 1122 1122 if (!shm) { 1123 1123 retval = EINVAL; 1124 1124 break; 1125 1125 } 1126 retval = shm2 imgmap(shm, shm_size);1127 break; 1128 case FB_DRAW_ IMGMAP:1126 retval = shm2pixmap(shm, shm_size); 1127 break; 1128 case FB_DRAW_PPM: 1129 1129 if (!shm) { 1130 1130 retval = EINVAL; 1131 1131 break; 1132 1132 } 1133 1134 1133 x = IPC_GET_ARG1(*call); 1135 1134 y = IPC_GET_ARG2(*call); … … 1140 1139 } 1141 1140 1142 imgmap_draw(shm, IPC_GET_ARG1(*call), IPC_GET_ARG2(*call),1143 vport->width - x, vport->height - y,vport);1141 ppm_draw(shm, shm_size, IPC_GET_ARG1(*call), 1142 IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *) vport); 1144 1143 break; 1145 1144 case FB_DRAW_TEXT_DATA: … … 1168 1167 if (handled) 1169 1168 async_answer_0(callid, retval); 1170 1171 1169 return handled; 1172 1170 } 1173 1171 1174 static void copy_vp_to_imgmap(viewport_t *vport, imgmap_t *imap) 1172 1173 static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap) 1175 1174 { 1176 1175 unsigned int width = vport->width; … … 1179 1178 if (width + vport->x > screen.xres) 1180 1179 width = screen.xres - vport->x; 1181 1182 1180 if (height + vport->y > screen.yres) 1183 1181 height = screen.yres - vport->y; 1184 1182 1185 unsigned int realwidth = imap->width <= width ? imap->width : width;1186 unsigned int realheight = imap->height <= height ? imap->height : height;1183 unsigned int realwidth = pmap->width <= width ? pmap->width : width; 1184 unsigned int realheight = pmap->height <= height ? pmap->height : height; 1187 1185 1188 1186 unsigned int srcrowsize = vport->width * screen.pixelbytes; … … 1192 1190 for (y = 0; y < realheight; y++) { 1193 1191 unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; 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) 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) 1205 1207 return ELIMIT; 1206 1208 1207 size_t size = screen.pixelbytes * vport->width * vport->height;1208 imgmap_t *imap = malloc(sizeof(imgmap_t) + size);1209 if (! imap)1209 pmap = &pixmaps[pm]; 1210 pmap->data = malloc(screen.pixelbytes * vport->width * vport->height); 1211 if (!pmap->data) 1210 1212 return ENOMEM; 1211 1213 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 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]; 1234 1232 viewport_t *vport = &viewports[vp]; 1235 1233 … … 1239 1237 if (width + vport->x > screen.xres) 1240 1238 width = screen.xres - vport->x; 1241 1242 1239 if (height + vport->y > screen.yres) 1243 1240 height = screen.yres - vport->y; 1244 1241 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 } else1258 imgmap_draw(imap, 0, 0, realwidth, realheight, vport);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 } 1259 1256 1260 1257 return EOK; 1261 1258 } 1259 1262 1260 1263 1261 /** Tick animation one step forward … … 1279 1277 continue; 1280 1278 1281 draw_ imgmap(animations[i].vp, animations[i].imgmaps[animations[i].pos]);1279 draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]); 1282 1280 animations[i].pos = (animations[i].pos + 1) % animations[i].animlen; 1283 1281 } … … 1289 1287 static bool pointer_shown, pointer_enabled; 1290 1288 static int pointer_vport = -1; 1291 static int pointer_ imgmap = -1;1289 static int pointer_pixmap = -1; 1292 1290 1293 1291 … … 1312 1310 } 1313 1311 1314 if (pointer_ imgmap == -1)1315 pointer_ imgmap = save_vp_to_imgmap(&viewports[pointer_vport]);1312 if (pointer_pixmap == -1) 1313 pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]); 1316 1314 else 1317 copy_vp_to_ imgmap(&viewports[pointer_vport], imgmaps[pointer_imgmap]);1315 copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]); 1318 1316 1319 1317 /* Draw mouse pointer. */ … … 1340 1338 /* Restore image under the pointer. */ 1341 1339 if (pointer_shown) { 1342 draw_ imgmap(pointer_vport, pointer_imgmap);1340 draw_pixmap(pointer_vport, pointer_pixmap); 1343 1341 pointer_shown = 0; 1344 1342 } … … 1395 1393 animations[i].initialized = 0; 1396 1394 break; 1397 case FB_ANIM_ADD IMGMAP:1395 case FB_ANIM_ADDPIXMAP: 1398 1396 i = IPC_GET_ARG1(*call); 1399 1397 if (i >= MAX_ANIMATIONS || i < 0 || … … 1407 1405 } 1408 1406 newval = IPC_GET_ARG2(*call); 1409 if (newval < 0 || newval > MAX_ IMGMAPS ||1410 ! imgmaps[newval]) {1407 if (newval < 0 || newval > MAX_PIXMAPS || 1408 !pixmaps[newval].data) { 1411 1409 retval = EINVAL; 1412 1410 break; 1413 1411 } 1414 animations[i]. imgmaps[animations[i].animlen++] = newval;1412 animations[i].pixmaps[animations[i].animlen++] = newval; 1415 1413 break; 1416 1414 case FB_ANIM_CHGVP: … … 1451 1449 } 1452 1450 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) 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) 1457 1456 { 1458 1457 bool handled = true; … … 1461 1460 1462 1461 switch (IPC_GET_IMETHOD(*call)) { 1463 case FB_VP_DRAW_ IMGMAP:1462 case FB_VP_DRAW_PIXMAP: 1464 1463 nvp = IPC_GET_ARG1(*call); 1465 1464 if (nvp == -1) 1466 1465 nvp = vp; 1467 1468 1466 if (nvp < 0 || nvp >= MAX_VIEWPORTS || 1469 1467 !viewports[nvp].initialized) { 1470 1468 retval = EINVAL; 1471 1469 break; 1472 1470 } 1473 1474 1471 i = IPC_GET_ARG2(*call); 1475 retval = draw_ imgmap(nvp, i);1476 break; 1477 case FB_VP2 IMGMAP:1472 retval = draw_pixmap(nvp, i); 1473 break; 1474 case FB_VP2PIXMAP: 1478 1475 nvp = IPC_GET_ARG1(*call); 1479 1476 if (nvp == -1) 1480 1477 nvp = vp; 1481 1482 1478 if (nvp < 0 || nvp >= MAX_VIEWPORTS || 1483 !viewports[nvp].initialized) {1479 !viewports[nvp].initialized) 1484 1480 retval = EINVAL; 1485 break; 1486 } 1487 1488 retval = save_vp_to_imgmap(&viewports[nvp]); 1489 break; 1490 case FB_DROP_IMGMAP: 1481 else 1482 retval = save_vp_to_pixmap(&viewports[nvp]); 1483 break; 1484 case FB_DROP_PIXMAP: 1491 1485 i = IPC_GET_ARG1(*call); 1492 if (i >= MAX_ IMGMAPS) {1486 if (i >= MAX_PIXMAPS) { 1493 1487 retval = EINVAL; 1494 1488 break; 1495 1489 } 1496 1497 if (imgmaps[i]) { 1498 free(imgmaps[i]); 1499 imgmaps[i] = NULL; 1500 } 1501 1490 if (pixmaps[i].data) { 1491 free(pixmaps[i].data); 1492 pixmaps[i].data = NULL; 1493 } 1502 1494 break; 1503 1495 default: … … 1624 1616 continue; 1625 1617 1626 if ( imgmap_handle(callid, &call, vp))1618 if (pixmap_handle(callid, &call, vp)) 1627 1619 continue; 1628 1620
Note:
See TracChangeset
for help on using the changeset viewer.