Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/fb/fb.c

    r9934f7d rc6f08726  
    4949#include <ipc/ns.h>
    5050#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>
    5353#include <io/color.h>
    5454#include <io/style.h>
     
    5959#include <byteorder.h>
    6060#include <io/screenbuffer.h>
     61#include <imgmap.h>
    6162#include "font-8x16.h"
    6263#include "fb.h"
    6364#include "main.h"
    64 #include "ppm.h"
    6565#include "pointer.xbm"
    6666#include "pointer_mask.xbm"
    6767
    6868// FIXME: remove this header
    69 #include <kernel/ipc/ipc_methods.h>
     69#include <abi/ipc/methods.h>
    7070
    7171#define DEFAULT_BGCOLOR  0xf0f0f0
     
    7676#define MAX_ANIM_LEN    8
    7777#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 */
    7979#define MAX_VIEWPORTS   128  /**< Viewport is a rectangular area on the screen */
    8080
     
    160160        unsigned int pos;
    161161        unsigned int animlen;
    162         unsigned int pixmaps[MAX_ANIM_LEN];
     162        unsigned int imgmaps[MAX_ANIM_LEN];
    163163} animation_t;
    164164
     
    166166static bool anims_enabled;
    167167
    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];
     168static imgmap_t *imgmaps[MAX_IMGMAPS];
    175169static viewport_t viewports[128];
    176170
     
    212206static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
    213207    unsigned int row);
    214 
    215208
    216209#define RED(x, bits)                 (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
     
    875868}
    876869
    877 
    878870/** Show cursor if cursor showing is enabled
    879871 *
     
    888880}
    889881
    890 
    891882/** Invert cursor, if it is enabled
    892883 *
     
    899890                cursor_show(vport);
    900891}
    901 
    902892
    903893/** Draw character at given position relative to viewport
     
    981971}
    982972
    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;
     973static void putpixel(viewport_t *vport, unsigned int x, unsigned int y,
     974    uint32_t color)
     975{
    997976        unsigned int dx = vport->x + x;
    998977        unsigned int dy = vport->y + y;
     
    1001980}
    1002981
    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 */
     994static 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 */
     1022static int find_free_imgmap(void)
    10081023{
    10091024        unsigned int i;
    10101025       
    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])
    10131028                        return i;
    10141029       
     
    10161031}
    10171032
    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 */
     1036static int shm2imgmap(imgmap_t *shm, size_t size)
     1037{
     1038        int im = find_free_imgmap();
     1039        if (im == -1)
    10291040                return ELIMIT;
    10301041       
    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)
    10381044                return ENOMEM;
    10391045       
    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}
    10451050
    10461051/** Handle shared memory communication calls
    10471052 *
    1048  * Protocol for drawing pixmaps:
     1053 * Protocol for drawing image maps:
    10491054 * - FB_PREPARE_SHM(client shm identification)
    10501055 * - IPC_M_AS_AREA_SEND
    1051  * - FB_DRAW_PPM(startx, starty)
     1056 * - FB_DRAW_IMGMAP(startx, starty)
    10521057 * - FB_DROP_SHM
    10531058 *
     
    10711076        static size_t intersize = 0;
    10721077       
    1073         static unsigned char *shm = NULL;
     1078        static imgmap_t *shm = NULL;
    10741079        static sysarg_t shm_id = 0;
    10751080        static size_t shm_size;
     
    10931098                                return false;
    10941099                        }
     1100                       
    10951101                        shm = dest;
    1096                        
    1097                         if (shm[0] != 'P')
    1098                                 return false;
    1099                        
    11001102                        return true;
    11011103                } else {
     
    11071109                if (shm_id)
    11081110                        retval = EBUSY;
    1109                 else 
     1111                else
    11101112                        shm_id = IPC_GET_ARG1(*call);
    11111113                break;
    1112                
    11131114        case FB_DROP_SHM:
    11141115                if (shm) {
     
    11181119                shm_id = 0;
    11191120                break;
    1120                
    1121         case FB_SHM2PIXMAP:
     1121        case FB_SHM2IMGMAP:
    11221122                if (!shm) {
    11231123                        retval = EINVAL;
    11241124                        break;
    11251125                }
    1126                 retval = shm2pixmap(shm, shm_size);
    1127                 break;
    1128         case FB_DRAW_PPM:
     1126                retval = shm2imgmap(shm, shm_size);
     1127                break;
     1128        case FB_DRAW_IMGMAP:
    11291129                if (!shm) {
    11301130                        retval = EINVAL;
    11311131                        break;
    11321132                }
     1133               
    11331134                x = IPC_GET_ARG1(*call);
    11341135                y = IPC_GET_ARG2(*call);
     
    11391140                }
    11401141               
    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);
    11431144                break;
    11441145        case FB_DRAW_TEXT_DATA:
     
    11671168        if (handled)
    11681169                async_answer_0(callid, retval);
     1170       
    11691171        return handled;
    11701172}
    11711173
    1172 
    1173 static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
     1174static void copy_vp_to_imgmap(viewport_t *vport, imgmap_t *imap)
    11741175{
    11751176        unsigned int width = vport->width;
     
    11781179        if (width + vport->x > screen.xres)
    11791180                width = screen.xres - vport->x;
     1181       
    11801182        if (height + vport->y > screen.yres)
    11811183                height = screen.yres - vport->y;
    11821184       
    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;
    11851187       
    11861188        unsigned int srcrowsize = vport->width * screen.pixelbytes;
     
    11901192        for (y = 0; y < realheight; y++) {
    11911193                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 */
     1201static int save_vp_to_imgmap(viewport_t *vport)
     1202{
     1203        int im = find_free_imgmap();
     1204        if (im == -1)
    12071205                return ELIMIT;
    12081206       
    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)
    12121210                return ENOMEM;
    12131211       
    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 */
     1228static int draw_imgmap(int vp, int im)
     1229{
     1230        imgmap_t *imap = imgmaps[im];
     1231        if (!imap)
     1232                return EINVAL;
     1233       
    12321234        viewport_t *vport = &viewports[vp];
    12331235       
     
    12371239        if (width + vport->x > screen.xres)
    12381240                width = screen.xres - vport->x;
     1241       
    12391242        if (height + vport->y > screen.yres)
    12401243                height = screen.yres - vport->y;
    12411244       
    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);
    12561259       
    12571260        return EOK;
    12581261}
    1259 
    12601262
    12611263/** Tick animation one step forward
     
    12771279                        continue;
    12781280               
    1279                 draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]);
     1281                draw_imgmap(animations[i].vp, animations[i].imgmaps[animations[i].pos]);
    12801282                animations[i].pos = (animations[i].pos + 1) % animations[i].animlen;
    12811283        }
     
    12871289static bool pointer_shown, pointer_enabled;
    12881290static int pointer_vport = -1;
    1289 static int pointer_pixmap = -1;
     1291static int pointer_imgmap = -1;
    12901292
    12911293
     
    13101312        }
    13111313       
    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]);
    13141316        else
    1315                 copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
     1317                copy_vp_to_imgmap(&viewports[pointer_vport], imgmaps[pointer_imgmap]);
    13161318       
    13171319        /* Draw mouse pointer. */
     
    13381340        /* Restore image under the pointer. */
    13391341        if (pointer_shown) {
    1340                 draw_pixmap(pointer_vport, pointer_pixmap);
     1342                draw_imgmap(pointer_vport, pointer_imgmap);
    13411343                pointer_shown = 0;
    13421344        }
     
    13931395                animations[i].initialized = 0;
    13941396                break;
    1395         case FB_ANIM_ADDPIXMAP:
     1397        case FB_ANIM_ADDIMGMAP:
    13961398                i = IPC_GET_ARG1(*call);
    13971399                if (i >= MAX_ANIMATIONS || i < 0 ||
     
    14051407                }
    14061408                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]) {
    14091411                        retval = EINVAL;
    14101412                        break;
    14111413                }
    1412                 animations[i].pixmaps[animations[i].animlen++] = newval;
     1414                animations[i].imgmaps[animations[i].animlen++] = newval;
    14131415                break;
    14141416        case FB_ANIM_CHGVP:
     
    14491451}
    14501452
    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 */
     1456static int imgmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    14561457{
    14571458        bool handled = true;
     
    14601461       
    14611462        switch (IPC_GET_IMETHOD(*call)) {
    1462         case FB_VP_DRAW_PIXMAP:
     1463        case FB_VP_DRAW_IMGMAP:
    14631464                nvp = IPC_GET_ARG1(*call);
    14641465                if (nvp == -1)
    14651466                        nvp = vp;
     1467               
    14661468                if (nvp < 0 || nvp >= MAX_VIEWPORTS ||
    1467                         !viewports[nvp].initialized) {
     1469                    !viewports[nvp].initialized) {
    14681470                        retval = EINVAL;
    14691471                        break;
    14701472                }
     1473               
    14711474                i = IPC_GET_ARG2(*call);
    1472                 retval = draw_pixmap(nvp, i);
    1473                 break;
    1474         case FB_VP2PIXMAP:
     1475                retval = draw_imgmap(nvp, i);
     1476                break;
     1477        case FB_VP2IMGMAP:
    14751478                nvp = IPC_GET_ARG1(*call);
    14761479                if (nvp == -1)
    14771480                        nvp = vp;
     1481               
    14781482                if (nvp < 0 || nvp >= MAX_VIEWPORTS ||
    1479                         !viewports[nvp].initialized)
     1483                    !viewports[nvp].initialized) {
    14801484                        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:
    14851491                i = IPC_GET_ARG1(*call);
    1486                 if (i >= MAX_PIXMAPS) {
     1492                if (i >= MAX_IMGMAPS) {
    14871493                        retval = EINVAL;
    14881494                        break;
    14891495                }
    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               
    14941502                break;
    14951503        default:
     
    16161624                        continue;
    16171625               
    1618                 if (pixmap_handle(callid, &call, vp))
     1626                if (imgmap_handle(callid, &call, vp))
    16191627                        continue;
    16201628               
Note: See TracChangeset for help on using the changeset viewer.