Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset c6f08726 in mainline


Ignore:
Timestamp:
2011-08-11T14:14:53Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
8d8eeb9
Parents:
67b05ff
Message:

eradicate PPMs and pixmaps completely
make TGA and image map code more robust

Files:
8 added
10 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • tools/mkarray.py

    r67b05ff rc6f08726  
    6969                cnt = 0
    7070               
    71                 while (len(src_data[offset:]) > item_size):
     71                while (len(src_data[offset:]) >= item_size):
    7272                        byte = struct.unpack_from(fmt, src_data, offset)
    7373                       
     
    8383               
    8484                data_rec += "\n};\n"
     85                data_ctx.append(data_rec)
     86               
     87                header_rec = "extern size_t %s_size;" % symbol
     88                header_ctx.append(header_rec)
     89               
     90                data_rec = "size_t %s_size = %u;\n" % (symbol, offset)
    8591                data_ctx.append(data_rec)
    8692       
  • uspace/Makefile

    r67b05ff rc6f08726  
    8181        srv/fs/devfs \
    8282        srv/fs/ext2fs \
     83        srv/hid/console \
    8384        srv/hid/s3c24xx_ts \
    8485        srv/hid/fb \
     
    121122#
    122123
    123 ifneq ($(UARCH),abs32le)
    124         DIRS += srv/hid/console
    125 endif
    126 
    127124ifeq ($(UARCH),amd64)
    128125        DIRS += \
  • uspace/lib/c/include/ipc/fb.h

    r67b05ff rc6f08726  
    5555        FB_DRAW_TEXT_DATA,
    5656        FB_FLUSH,
    57         FB_DRAW_PPM,
     57        FB_DRAW_IMGMAP,
    5858        FB_PREPARE_SHM,
    5959        FB_DROP_SHM,
    60         FB_SHM2PIXMAP,
    61         FB_VP_DRAW_PIXMAP,
    62         FB_VP2PIXMAP,
    63         FB_DROP_PIXMAP,
     60        FB_SHM2IMGMAP,
     61        FB_VP_DRAW_IMGMAP,
     62        FB_VP2IMGMAP,
     63        FB_DROP_IMGMAP,
    6464        FB_ANIM_CREATE,
    6565        FB_ANIM_DROP,
    66         FB_ANIM_ADDPIXMAP,
     66        FB_ANIM_ADDIMGMAP,
    6767        FB_ANIM_CHGVP,
    6868        FB_ANIM_START,
  • uspace/lib/imgmap/imgmap.c

    r67b05ff rc6f08726  
    6969        IMG_CMAP = 1,
    7070        IMG_BGRA = 2,
    71         IMG_BW = 3,
     71        IMG_GRAY = 3,
    7272        IMG_CMAP_RLE = 9,
    7373        IMG_BGRA_RLE = 10,
    74         IMG_BW_RLE = 11
     74        IMG_GRAY_RLE = 11
    7575} img_type_t;
    7676
     
    104104 *
    105105 * @param[in]  data Memory representation of TGA.
     106 * @param[in]  size Size of the representation (in bytes).
    106107 * @param[out] tga  Decoded TGA.
    107108 *
     
    110111 *
    111112 */
    112 static bool decode_tga_header(void *data, tga_t *tga)
     113static bool decode_tga_header(void *data, size_t size, tga_t *tga)
    113114{
     115        /* Header sanity check */
     116        if (size < sizeof(tga_header_t))
     117                return false;
     118       
    114119        tga_header_t *head = (tga_header_t *) data;
    115120       
     
    117122        tga->id_data = data + sizeof(tga_header_t);
    118123        tga->id_length = head->id_length;
     124       
     125        if (size < sizeof(tga_header_t) + tga->id_length)
     126                return false;
    119127       
    120128        /* Color map type */
     
    130138        tga->cmap_data = tga->id_data + tga->id_length;
    131139        tga->cmap_length = ALIGN_UP(tga->cmap_entries * tga->cmap_bpp, 8) >> 3;
     140       
     141        if (size < sizeof(tga_header_t) + tga->id_length +
     142            tga->cmap_length)
     143                return false;
    132144       
    133145        /* Image specification */
     
    142154        tga->img_length = ALIGN_UP(tga->width * tga->height * tga->img_bpp, 8) >> 3;
    143155       
     156        if (size < sizeof(tga_header_t) + tga->id_length +
     157            tga->cmap_length + tga->img_length)
     158                return false;
     159       
    144160        return true;
    145161}
     
    152168 * alpha channel.
    153169 *
    154  * @param data[in] Memory representation of TGA.
     170 * @param[in] data Memory representation of TGA.
     171 * @param[in] size Size of the representation (in bytes).
    155172 *
    156173 * @return Newly allocated image map.
     
    158175 *
    159176 */
    160 imgmap_t *imgmap_decode_tga(void *data)
     177imgmap_t *imgmap_decode_tga(void *data, size_t size)
    161178{
    162179        tga_t tga;
    163         if (!decode_tga_header(data, &tga))
     180        if (!decode_tga_header(data, size, &tga))
    164181                return NULL;
    165182       
     
    178195        switch (tga.img_type) {
    179196        case IMG_BGRA:
     197                if (tga.img_bpp != 24)
     198                        return NULL;
     199                break;
     200        case IMG_GRAY:
     201                if (tga.img_bpp != 8)
     202                        return NULL;
    180203                break;
    181204        default:
     
    184207        }
    185208       
    186         if (tga.img_bpp != 24)
    187                 return NULL;
    188        
    189209        if (tga.img_alpha_bpp != 0)
    190210                return NULL;
     
    192212        sysarg_t twidth = tga.startx + tga.width;
    193213        sysarg_t theight = tga.starty + tga.height;
    194         size_t size = twidth * theight * 3;
    195        
    196         imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + size);
     214        size_t bsize = twidth * theight * 3;
     215       
     216        imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + bsize);
    197217        if (imgmap == NULL)
    198218                return NULL;
    199219       
    200         imgmap->tag = 'I';
    201         imgmap->size = sizeof(imgmap_t) + size;
     220        imgmap->size = sizeof(imgmap_t) + bsize;
    202221        imgmap->width = twidth;
    203222        imgmap->height = theight;
    204223        imgmap->visual = VISUAL_BGR_8_8_8;
    205224       
    206         memset(imgmap->data, 0, size);
    207        
    208         for (sysarg_t y = tga.starty; y < theight; y++) {
    209                 size_t src_offset = (y - tga.starty) * tga.width * 3;
    210                 size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
    211                
    212                 memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
    213                     tga.width * 3);
     225        memset(imgmap->data, 0, bsize);
     226       
     227        /*
     228         * TGA is encoded in a bottom-up manner.
     229         */
     230       
     231        switch (tga.img_type) {
     232        case IMG_BGRA:
     233                for (sysarg_t y = tga.starty; y < theight; y++) {
     234                        size_t src_offset = (y - tga.starty) * tga.width * 3;
     235                        size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
     236                       
     237                        memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
     238                            tga.width * 3);
     239                }
     240                break;
     241        case IMG_GRAY:
     242                for (sysarg_t y = tga.starty; y < theight; y++) {
     243                        for (sysarg_t x = tga.startx; x < twidth; x++) {
     244                                uint8_t val =
     245                                    ((uint8_t *) tga.img_data)[(y - tga.starty) * tga.width + (x - tga.startx)];
     246                                size_t dst_offset = ((theight - y - 1) * twidth + x) * 3;
     247                                memset(imgmap->data + dst_offset, val, 3);
     248                        }
     249                }
     250                break;
     251        default:
     252                break;
    214253        }
    215254       
  • uspace/lib/imgmap/imgmap.h

    r67b05ff rc6f08726  
    4141
    4242typedef struct {
    43         uint8_t tag;
    4443        size_t size;
    4544        sysarg_t width;
     
    4948} imgmap_t;
    5049
    51 extern imgmap_t *imgmap_decode_tga(void *);
     50extern imgmap_t *imgmap_decode_tga(void *, size_t);
    5251
    5352#endif
  • uspace/srv/hid/console/Makefile

    r67b05ff rc6f08726  
    3333BINARY = console
    3434
    35 GENERIC_SOURCES = \
     35SOURCES = \
    3636        console.c \
    3737        keybuffer.c \
     
    3939        gcons.c
    4040
    41 IMAGES_OLD = \
    42         gfx/cons_selected.ppm \
    43         gfx/cons_idle.ppm \
    44         gfx/cons_has_data.ppm \
    45         gfx/cons_kernel.ppm \
    46         gfx/anim_1.ppm \
    47         gfx/anim_2.ppm \
    48         gfx/anim_3.ppm \
    49         gfx/anim_4.ppm
    50 
    5141IMAGES = \
    5242        gfx/helenos.tga \
    53         gfx/nameic.tga
    54 
    55 SOURCES = \
    56         $(GENERIC_SOURCES) \
    57         $(IMAGES_OLD)
     43        gfx/nameic.tga \
     44        gfx/cons_selected.tga \
     45        gfx/cons_idle.tga \
     46        gfx/cons_has_data.tga \
     47        gfx/cons_kernel.tga \
     48        gfx/anim_1.tga \
     49        gfx/anim_2.tga \
     50        gfx/anim_3.tga \
     51        gfx/anim_4.tga
    5852
    5953PRE_DEPEND = images.c images.h
     
    6256include $(USPACE_PREFIX)/Makefile.common
    6357
    64 %.o: %.ppm
    65         $(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) $< $@
    66 
    6758images.c images.h: $(IMAGES)
    6859        $(ROOT_PATH)/tools/mkarray.py images CONSOLE_IMAGES $^
  • uspace/srv/hid/console/gcons.c

    r67b05ff rc6f08726  
    6060#define COLOR_BACKGROUND  0xffffff
    6161
    62 extern char _binary_gfx_anim_1_ppm_start[0];
    63 extern int _binary_gfx_anim_1_ppm_size;
    64 extern char _binary_gfx_anim_2_ppm_start[0];
    65 extern int _binary_gfx_anim_2_ppm_size;
    66 extern char _binary_gfx_anim_3_ppm_start[0];
    67 extern int _binary_gfx_anim_3_ppm_size;
    68 extern char _binary_gfx_anim_4_ppm_start[0];
    69 extern int _binary_gfx_anim_4_ppm_size;
    70 
    71 extern char _binary_gfx_cons_selected_ppm_start[0];
    72 extern int _binary_gfx_cons_selected_ppm_size;
    73 extern char _binary_gfx_cons_idle_ppm_start[0];
    74 extern int _binary_gfx_cons_idle_ppm_size;
    75 extern char _binary_gfx_cons_has_data_ppm_start[0];
    76 extern int _binary_gfx_cons_has_data_ppm_size;
    77 extern char _binary_gfx_cons_kernel_ppm_start[0];
    78 extern int _binary_gfx_cons_kernel_ppm_size;
    79 
    8062static bool use_gcons = false;
    8163static sysarg_t xres;
     
    8466static imgmap_t *helenos_img;
    8567static imgmap_t *nameic_img;
     68
     69static imgmap_t *anim_1_img;
     70static imgmap_t *anim_2_img;
     71static imgmap_t *anim_3_img;
     72static imgmap_t *anim_4_img;
     73
     74static imgmap_t *cons_has_data_img;
     75static imgmap_t *cons_idle_img;
     76static imgmap_t *cons_kernel_img;
     77static imgmap_t *cons_selected_img;
    8678
    8779enum butstate {
     
    10193static int fbphone;
    10294
    103 /** List of pixmaps identifying these icons */
    104 static int ic_pixmaps[CONS_LAST] = {-1, -1, -1, -1, -1, -1};
     95/** List of image maps identifying these icons */
     96static int ic_imgmaps[CONS_LAST] = {-1, -1, -1, -1, -1, -1};
    10597static int animation = -1;
    10698
     
    149141        enum butstate state = console_state[index];
    150142       
    151         if (ic_pixmaps[state] != -1)
    152                 async_obsolete_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
    153                     ic_pixmaps[state]);
     143        if (ic_imgmaps[state] != -1)
     144                async_obsolete_msg_2(fbphone, FB_VP_DRAW_IMGMAP, cstatus_vp[index],
     145                    ic_imgmaps[state]);
    154146       
    155147        if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
     
    388380       
    389381        /* Draw logo */
    390         async_obsolete_msg_2(fbphone, FB_DRAW_PPM, x, y);
     382        async_obsolete_msg_2(fbphone, FB_DRAW_IMGMAP, x, y);
    391383       
    392384drop:
     
    418410}
    419411
    420 /** Creates a pixmap on framebuffer
    421  *
    422  * @param data PPM data
    423  * @param size PPM data size
    424  *
    425  * @return Pixmap identification
    426  *
    427  */
    428 static int make_pixmap(char *data, size_t size)
    429 {
     412/** Create an image map on framebuffer
     413 *
     414 * @param img Image map.
     415 *
     416 * @return Image map identification
     417 *
     418 */
     419static int make_imgmap(imgmap_t *img)
     420{
     421        if (img == NULL)
     422                return -1;
     423       
    430424        /* Create area */
    431         char *shm = mmap(NULL, size, PROTO_READ | PROTO_WRITE, MAP_SHARED |
    432             MAP_ANONYMOUS, 0, 0);
     425        char *shm = mmap(NULL, img->size, PROTO_READ | PROTO_WRITE,
     426            MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    433427        if (shm == MAP_FAILED)
    434428                return -1;
    435429       
    436         memcpy(shm, data, size);
    437        
    438         int pxid = -1;
     430        memcpy(shm, img, img->size);
     431       
     432        int id = -1;
    439433       
    440434        /* Send area */
     
    447441                goto drop;
    448442       
    449         /* Obtain pixmap */
    450         rc = async_obsolete_req_0_0(fbphone, FB_SHM2PIXMAP);
     443        /* Obtain image map identifier */
     444        rc = async_obsolete_req_0_0(fbphone, FB_SHM2IMGMAP);
    451445        if (rc < 0)
    452446                goto drop;
    453447       
    454         pxid = rc;
     448        id = rc;
    455449       
    456450drop:
     
    460454exit:
    461455        /* Remove area */
    462         munmap(shm, size);
    463        
    464         return pxid;
     456        munmap(shm, img->size);
     457       
     458        return id;
    465459}
    466460
     
    472466                return;
    473467       
    474         int pm = make_pixmap(_binary_gfx_anim_1_ppm_start,
    475             (size_t) &_binary_gfx_anim_1_ppm_size);
    476         async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    477        
    478         pm = make_pixmap(_binary_gfx_anim_2_ppm_start,
    479             (size_t) &_binary_gfx_anim_2_ppm_size);
    480         async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    481        
    482         pm = make_pixmap(_binary_gfx_anim_3_ppm_start,
    483             (size_t) &_binary_gfx_anim_3_ppm_size);
    484         async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
    485        
    486         pm = make_pixmap(_binary_gfx_anim_4_ppm_start,
    487             (size_t) &_binary_gfx_anim_4_ppm_size);
    488         async_obsolete_msg_2(fbphone, FB_ANIM_ADDPIXMAP, an, pm);
     468        int pm = make_imgmap(anim_1_img);
     469        async_obsolete_msg_2(fbphone, FB_ANIM_ADDIMGMAP, an, pm);
     470       
     471        pm = make_imgmap(anim_2_img);
     472        async_obsolete_msg_2(fbphone, FB_ANIM_ADDIMGMAP, an, pm);
     473       
     474        pm = make_imgmap(anim_3_img);
     475        async_obsolete_msg_2(fbphone, FB_ANIM_ADDIMGMAP, an, pm);
     476       
     477        pm = make_imgmap(anim_4_img);
     478        async_obsolete_msg_2(fbphone, FB_ANIM_ADDIMGMAP, an, pm);
    489479       
    490480        async_obsolete_msg_1(fbphone, FB_ANIM_START, an);
     
    506496       
    507497        /* Create image maps */
    508         helenos_img = imgmap_decode_tga((void *) helenos_tga);
    509         nameic_img = imgmap_decode_tga((void *) nameic_tga);
     498        helenos_img = imgmap_decode_tga((void *) helenos_tga,
     499            helenos_tga_size);
     500        nameic_img = imgmap_decode_tga((void *) nameic_tga,
     501            nameic_tga_size);
     502       
     503        anim_1_img = imgmap_decode_tga((void *) anim_1_tga,
     504            anim_1_tga_size);
     505        anim_2_img = imgmap_decode_tga((void *) anim_2_tga,
     506            anim_2_tga_size);
     507        anim_3_img = imgmap_decode_tga((void *) anim_3_tga,
     508            anim_3_tga_size);
     509        anim_4_img = imgmap_decode_tga((void *) anim_4_tga,
     510            anim_4_tga_size);
     511       
     512        cons_has_data_img = imgmap_decode_tga((void *) cons_has_data_tga,
     513            cons_has_data_tga_size);
     514        cons_idle_img = imgmap_decode_tga((void *) cons_idle_tga,
     515            cons_idle_tga_size);
     516        cons_kernel_img = imgmap_decode_tga((void *) cons_kernel_tga,
     517            cons_kernel_tga_size);
     518        cons_selected_img = imgmap_decode_tga((void *) cons_selected_tga,
     519            cons_selected_tga_size);
    510520       
    511521        /* Create console viewport */
     
    535545       
    536546        /* Initialize icons */
    537         ic_pixmaps[CONS_SELECTED] =
    538             make_pixmap(_binary_gfx_cons_selected_ppm_start,
    539             (size_t) &_binary_gfx_cons_selected_ppm_size);
    540         ic_pixmaps[CONS_IDLE] =
    541             make_pixmap(_binary_gfx_cons_idle_ppm_start,
    542             (size_t) &_binary_gfx_cons_idle_ppm_size);
    543         ic_pixmaps[CONS_HAS_DATA] =
    544             make_pixmap(_binary_gfx_cons_has_data_ppm_start,
    545             (size_t) &_binary_gfx_cons_has_data_ppm_size);
    546         ic_pixmaps[CONS_DISCONNECTED] =
    547             make_pixmap(_binary_gfx_cons_idle_ppm_start,
    548             (size_t) &_binary_gfx_cons_idle_ppm_size);
    549         ic_pixmaps[CONS_KERNEL] =
    550             make_pixmap(_binary_gfx_cons_kernel_ppm_start,
    551             (size_t) &_binary_gfx_cons_kernel_ppm_size);
    552         ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
     547        ic_imgmaps[CONS_SELECTED] = make_imgmap(cons_selected_img);
     548        ic_imgmaps[CONS_IDLE] = make_imgmap(cons_idle_img);
     549        ic_imgmaps[CONS_HAS_DATA] = make_imgmap(cons_has_data_img);
     550        ic_imgmaps[CONS_DISCONNECTED] = make_imgmap(cons_idle_img);
     551        ic_imgmaps[CONS_KERNEL] = make_imgmap(cons_kernel_img);
     552        ic_imgmaps[CONS_DISCONNECTED_SEL] = ic_imgmaps[CONS_SELECTED];
    553553       
    554554        make_anim();
  • uspace/srv/hid/fb/Makefile

    r67b05ff rc6f08726  
    4040
    4141SOURCES = \
    42         main.c \
    43         ppm.c
     42        main.c
    4443
    4544ifneq ($(UARCH),ia64)
  • uspace/srv/hid/fb/ega.c

    r67b05ff rc6f08726  
    414414                        retval = 0;
    415415                        break;
    416                 case FB_VP_DRAW_PIXMAP:
     416                case FB_VP_DRAW_IMGMAP:
    417417                        scr = IPC_GET_ARG2(call);
    418418                        retval = print_screen(scr);
    419419                        break;
    420                 case FB_VP2PIXMAP:
     420                case FB_VP2IMGMAP:
    421421                        retval = save_screen();
    422422                        break;
    423                 case FB_DROP_PIXMAP:
     423                case FB_DROP_IMGMAP:
    424424                        scr = IPC_GET_ARG1(call);
    425425                       
  • uspace/srv/hid/fb/fb.c

    r67b05ff rc6f08726  
    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"
     
    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') || (shm[0] != 'I'))
    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               
  • uspace/srv/hid/fb/fb.h

    r67b05ff rc6f08726  
    3939#include <stdint.h>
    4040
    41 typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, uint32_t);
    42 
    4341extern int fb_init(void);
    4442
Note: See TracChangeset for help on using the changeset viewer.