Ignore:
File:
1 edited

Legend:

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

    rc6f08726 r9934f7d  
    4949#include <ipc/ns.h>
    5050#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>
    5353#include <io/color.h>
    5454#include <io/style.h>
     
    5959#include <byteorder.h>
    6060#include <io/screenbuffer.h>
    61 #include <imgmap.h>
    6261#include "font-8x16.h"
    6362#include "fb.h"
    6463#include "main.h"
     64#include "ppm.h"
    6565#include "pointer.xbm"
    6666#include "pointer_mask.xbm"
    6767
    6868// FIXME: remove this header
    69 #include <abi/ipc/methods.h>
     69#include <kernel/ipc/ipc_methods.h>
    7070
    7171#define DEFAULT_BGCOLOR  0xf0f0f0
     
    7676#define MAX_ANIM_LEN    8
    7777#define MAX_ANIMATIONS  4
    78 #define MAX_IMGMAPS     256  /**< Maximum number of saved image maps */
     78#define MAX_PIXMAPS     256  /**< Maximum number of saved pixmaps */
    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 imgmaps[MAX_ANIM_LEN];
     162        unsigned int pixmaps[MAX_ANIM_LEN];
    163163} animation_t;
    164164
     
    166166static bool anims_enabled;
    167167
    168 static imgmap_t *imgmaps[MAX_IMGMAPS];
     168typedef struct {
     169        unsigned int width;
     170        unsigned int height;
     171        uint8_t *data;
     172} pixmap_t;
     173
     174static pixmap_t pixmaps[MAX_PIXMAPS];
    169175static viewport_t viewports[128];
    170176
     
    206212static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
    207213    unsigned int row);
     214
    208215
    209216#define RED(x, bits)                 (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
     
    868875}
    869876
     877
    870878/** Show cursor if cursor showing is enabled
    871879 *
     
    880888}
    881889
     890
    882891/** Invert cursor, if it is enabled
    883892 *
     
    890899                cursor_show(vport);
    891900}
     901
    892902
    893903/** Draw character at given position relative to viewport
     
    971981}
    972982
    973 static void putpixel(viewport_t *vport, unsigned int x, unsigned int y,
    974     uint32_t color)
    975 {
     983
     984static 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
     994static void putpixel(void *data, unsigned int x, unsigned int y, uint32_t color)
     995{
     996        viewport_t *vport = (viewport_t *) data;
    976997        unsigned int dx = vport->x + x;
    977998        unsigned int dy = vport->y + y;
     
    9801001}
    9811002
    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 */
     1007static 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 */
     1022static 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))
    9981034                return EINVAL;
    9991035       
    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)
    10441038                return ENOMEM;
    10451039       
    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
    10501045
    10511046/** Handle shared memory communication calls
    10521047 *
    1053  * Protocol for drawing image maps:
     1048 * Protocol for drawing pixmaps:
    10541049 * - FB_PREPARE_SHM(client shm identification)
    10551050 * - IPC_M_AS_AREA_SEND
    1056  * - FB_DRAW_IMGMAP(startx, starty)
     1051 * - FB_DRAW_PPM(startx, starty)
    10571052 * - FB_DROP_SHM
    10581053 *
     
    10761071        static size_t intersize = 0;
    10771072       
    1078         static imgmap_t *shm = NULL;
     1073        static unsigned char *shm = NULL;
    10791074        static sysarg_t shm_id = 0;
    10801075        static size_t shm_size;
     
    10981093                                return false;
    10991094                        }
     1095                        shm = dest;
    11001096                       
    1101                         shm = dest;
     1097                        if (shm[0] != 'P')
     1098                                return false;
     1099                       
    11021100                        return true;
    11031101                } else {
     
    11091107                if (shm_id)
    11101108                        retval = EBUSY;
    1111                 else
     1109                else 
    11121110                        shm_id = IPC_GET_ARG1(*call);
    11131111                break;
     1112               
    11141113        case FB_DROP_SHM:
    11151114                if (shm) {
     
    11191118                shm_id = 0;
    11201119                break;
    1121         case FB_SHM2IMGMAP:
     1120               
     1121        case FB_SHM2PIXMAP:
    11221122                if (!shm) {
    11231123                        retval = EINVAL;
    11241124                        break;
    11251125                }
    1126                 retval = shm2imgmap(shm, shm_size);
    1127                 break;
    1128         case FB_DRAW_IMGMAP:
     1126                retval = shm2pixmap(shm, shm_size);
     1127                break;
     1128        case FB_DRAW_PPM:
    11291129                if (!shm) {
    11301130                        retval = EINVAL;
    11311131                        break;
    11321132                }
    1133                
    11341133                x = IPC_GET_ARG1(*call);
    11351134                y = IPC_GET_ARG2(*call);
     
    11401139                }
    11411140               
    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);
    11441143                break;
    11451144        case FB_DRAW_TEXT_DATA:
     
    11681167        if (handled)
    11691168                async_answer_0(callid, retval);
    1170        
    11711169        return handled;
    11721170}
    11731171
    1174 static void copy_vp_to_imgmap(viewport_t *vport, imgmap_t *imap)
     1172
     1173static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
    11751174{
    11761175        unsigned int width = vport->width;
     
    11791178        if (width + vport->x > screen.xres)
    11801179                width = screen.xres - vport->x;
    1181        
    11821180        if (height + vport->y > screen.yres)
    11831181                height = screen.yres - vport->y;
    11841182       
    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;
    11871185       
    11881186        unsigned int srcrowsize = vport->width * screen.pixelbytes;
     
    11921190        for (y = 0; y < realheight; y++) {
    11931191                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 */
     1200static 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)
    12051207                return ELIMIT;
    12061208       
    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)
    12101212                return ENOMEM;
    12111213       
    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 */
     1229static int draw_pixmap(int vp, int pm)
     1230{
     1231        pixmap_t *pmap = &pixmaps[pm];
    12341232        viewport_t *vport = &viewports[vp];
    12351233       
     
    12391237        if (width + vport->x > screen.xres)
    12401238                width = screen.xres - vport->x;
    1241        
    12421239        if (height + vport->y > screen.yres)
    12431240                height = screen.yres - vport->y;
    12441241       
    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);
     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        }
    12591256       
    12601257        return EOK;
    12611258}
     1259
    12621260
    12631261/** Tick animation one step forward
     
    12791277                        continue;
    12801278               
    1281                 draw_imgmap(animations[i].vp, animations[i].imgmaps[animations[i].pos]);
     1279                draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]);
    12821280                animations[i].pos = (animations[i].pos + 1) % animations[i].animlen;
    12831281        }
     
    12891287static bool pointer_shown, pointer_enabled;
    12901288static int pointer_vport = -1;
    1291 static int pointer_imgmap = -1;
     1289static int pointer_pixmap = -1;
    12921290
    12931291
     
    13121310        }
    13131311       
    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]);
    13161314        else
    1317                 copy_vp_to_imgmap(&viewports[pointer_vport], imgmaps[pointer_imgmap]);
     1315                copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
    13181316       
    13191317        /* Draw mouse pointer. */
     
    13401338        /* Restore image under the pointer. */
    13411339        if (pointer_shown) {
    1342                 draw_imgmap(pointer_vport, pointer_imgmap);
     1340                draw_pixmap(pointer_vport, pointer_pixmap);
    13431341                pointer_shown = 0;
    13441342        }
     
    13951393                animations[i].initialized = 0;
    13961394                break;
    1397         case FB_ANIM_ADDIMGMAP:
     1395        case FB_ANIM_ADDPIXMAP:
    13981396                i = IPC_GET_ARG1(*call);
    13991397                if (i >= MAX_ANIMATIONS || i < 0 ||
     
    14071405                }
    14081406                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) {
    14111409                        retval = EINVAL;
    14121410                        break;
    14131411                }
    1414                 animations[i].imgmaps[animations[i].animlen++] = newval;
     1412                animations[i].pixmaps[animations[i].animlen++] = newval;
    14151413                break;
    14161414        case FB_ANIM_CHGVP:
     
    14511449}
    14521450
    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 */
     1455static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    14571456{
    14581457        bool handled = true;
     
    14611460       
    14621461        switch (IPC_GET_IMETHOD(*call)) {
    1463         case FB_VP_DRAW_IMGMAP:
     1462        case FB_VP_DRAW_PIXMAP:
    14641463                nvp = IPC_GET_ARG1(*call);
    14651464                if (nvp == -1)
    14661465                        nvp = vp;
    1467                
    14681466                if (nvp < 0 || nvp >= MAX_VIEWPORTS ||
    1469                     !viewports[nvp].initialized) {
     1467                        !viewports[nvp].initialized) {
    14701468                        retval = EINVAL;
    14711469                        break;
    14721470                }
    1473                
    14741471                i = IPC_GET_ARG2(*call);
    1475                 retval = draw_imgmap(nvp, i);
    1476                 break;
    1477         case FB_VP2IMGMAP:
     1472                retval = draw_pixmap(nvp, i);
     1473                break;
     1474        case FB_VP2PIXMAP:
    14781475                nvp = IPC_GET_ARG1(*call);
    14791476                if (nvp == -1)
    14801477                        nvp = vp;
    1481                
    14821478                if (nvp < 0 || nvp >= MAX_VIEWPORTS ||
    1483                     !viewports[nvp].initialized) {
     1479                        !viewports[nvp].initialized)
    14841480                        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:
    14911485                i = IPC_GET_ARG1(*call);
    1492                 if (i >= MAX_IMGMAPS) {
     1486                if (i >= MAX_PIXMAPS) {
    14931487                        retval = EINVAL;
    14941488                        break;
    14951489                }
    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                }
    15021494                break;
    15031495        default:
     
    16241616                        continue;
    16251617               
    1626                 if (imgmap_handle(callid, &call, vp))
     1618                if (pixmap_handle(callid, &call, vp))
    16271619                        continue;
    16281620               
Note: See TracChangeset for help on using the changeset viewer.