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

Changeset 2c9f6dd3 in mainline


Ignore:
Timestamp:
2013-09-12T10:43:38Z (8 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master
Children:
38c822e
Parents:
0d23cc0
Message:

rfb: Add a basic support for pallete-based pixel mode

Location:
uspace/srv/hid/rfb
Files:
2 edited

Legend:

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

    r0d23cc0 r2c9f6dd3  
    3535#include <str_error.h>
    3636#include <byteorder.h>
     37#include <macros.h>
    3738
    3839#include <net/in.h>
     
    214215}
    215216
    216 static void rfb_encode_pixel(void *buf, rfb_pixel_format_t *pf, uint8_t r, uint8_t g,
    217     uint8_t b)
     217static void rfb_encode_index(rfb_t *rfb, uint8_t *buf, pixel_t pixel)
     218{
     219        int first_free_index = -1;
     220        for (size_t i = 0; i < 256; i++) {
     221                bool free = ALPHA(rfb->palette[i]) == 0;
     222                if (free && first_free_index == -1) {
     223                        first_free_index = i;
     224                }
     225                else if (!free && RED(rfb->palette[i]) == RED(pixel) &&
     226                    GREEN(rfb->palette[i]) == GREEN(pixel) &&
     227                    BLUE(rfb->palette[i]) == BLUE(pixel)) {
     228                        *buf = i;
     229                        return;
     230                }
     231        }
     232       
     233        if (first_free_index != -1) {
     234                rfb->palette[first_free_index] = PIXEL(255, RED(pixel), GREEN(pixel),
     235                    BLUE(pixel));
     236                rfb->palette_used = max(rfb->palette_used, (unsigned) first_free_index + 1);
     237                *buf = first_free_index;
     238                return;
     239        }
     240       
     241        /* TODO find nearest color index. We are lazy so return index 0 for now */
     242        *buf = 0;
     243}
     244
     245static void rfb_encode_true_color(rfb_pixel_format_t *pf, void *buf,
     246    pixel_t pixel)
    218247{
    219248        uint32_t pix = 0;
    220         pix |= rfb_scale_channel(r, pf->r_max) << pf->r_shift;
    221         pix |= rfb_scale_channel(g, pf->g_max) << pf->g_shift;
    222         pix |= rfb_scale_channel(b, pf->b_max) << pf->b_shift;
     249        pix |= rfb_scale_channel(RED(pixel), pf->r_max) << pf->r_shift;
     250        pix |= rfb_scale_channel(GREEN(pixel), pf->g_max) << pf->g_shift;
     251        pix |= rfb_scale_channel(BLUE(pixel), pf->b_max) << pf->b_shift;
    223252       
    224253        if (pf->bpp == 8) {
     
    245274                memcpy(buf, &pix, 4);
    246275        }
     276}
     277
     278static void rfb_encode_pixel(rfb_t *rfb, void *buf, pixel_t pixel)
     279{
     280        if (rfb->pixel_format.true_color) {
     281                rfb_encode_true_color(&rfb->pixel_format, buf, pixel);
     282        }
     283        else {
     284                rfb_encode_index(rfb, buf, pixel);
     285        }
     286}
     287
     288static void rfb_set_color_map_entries_to_be(rfb_set_color_map_entries_t *src,
     289    rfb_set_color_map_entries_t *dst)
     290{
     291        dst->first_color = host2uint16_t_be(src->first_color);
     292        dst->color_count = host2uint16_t_be(src->color_count);
     293}
     294
     295static void rfb_color_map_entry_to_be(rfb_color_map_entry_t *src,
     296    rfb_color_map_entry_t *dst)
     297{
     298        dst->red = host2uint16_t_be(src->red);
     299        dst->green = host2uint16_t_be(src->green);
     300        dst->blue = host2uint16_t_be(src->blue);
     301}
     302
     303static int rfb_send_palette(int conn_sd, rfb_t *rfb)
     304{
     305        size_t size = sizeof(rfb_set_color_map_entries_t) +
     306            rfb->palette_used * sizeof(rfb_color_map_entry_t);
     307       
     308        void *buf = malloc(size);
     309        if (buf == NULL)
     310                return ENOMEM;
     311       
     312        void *pos = buf;
     313       
     314        rfb_set_color_map_entries_t *scme = pos;
     315        scme->message_type = RFB_SMSG_SET_COLOR_MAP_ENTRIES;
     316        scme->first_color = 0;
     317        scme->color_count = rfb->palette_used;
     318        rfb_set_color_map_entries_to_be(scme, scme);
     319        pos += sizeof(rfb_set_color_map_entries_t);
     320       
     321        rfb_color_map_entry_t *entries = pos;
     322        for (unsigned i = 0; i < rfb->palette_used; i++) {
     323                entries[i].red = 65535 * RED(rfb->palette[i]) / 255;
     324                entries[i].green = 65535 * GREEN(rfb->palette[i]) / 255;
     325                entries[i].blue = 65535 * BLUE(rfb->palette[i]) / 255;
     326                rfb_color_map_entry_to_be(&entries[i], &entries[i]);
     327        }
     328       
     329        int rc = send(conn_sd, buf, size, 0);
     330        free(buf);
     331       
     332        return rc;
    247333}
    248334
     
    286372                        pixel_t pixel = pixelmap_get_pixel(&rfb->framebuffer,
    287373                            x + rfb->damage_rect.x, y + rfb->damage_rect.y);
    288                         rfb_encode_pixel(pos, &rfb->pixel_format, RED(pixel), GREEN(pixel), BLUE(pixel));
     374                        rfb_encode_pixel(rfb, pos, pixel);
    289375                        pos += pixel_size;
     376                }
     377        }
     378       
     379        if (!rfb->pixel_format.true_color) {
     380                int rc = rfb_send_palette(conn_sd, rfb);
     381                if (rc != EOK) {
     382                        free(buf);
     383                        return rc;
    290384                }
    291385        }
     
    293387        int rc = send(conn_sd, buf, buf_size, 0);
    294388        free(buf);
    295        
    296389        rfb->damage_valid = false;
    297390        return rc;
     391}
     392
     393static int rfb_set_pixel_format(rfb_t *rfb, rfb_pixel_format_t *pixel_format)
     394{
     395        rfb->pixel_format = *pixel_format;
     396        if (rfb->pixel_format.true_color) {
     397                free(rfb->palette);
     398                rfb->palette = NULL;
     399                rfb->palette_used = 0;
     400        }
     401        else {
     402                if (rfb->palette == NULL) {
     403                        rfb->palette = malloc(sizeof(pixel_t) * 256);
     404                        if (rfb->palette == NULL)
     405                                return ENOMEM;
     406                        memset(rfb->palette, 0, sizeof(pixel_t) * 256);
     407                        rfb->palette_used = 0;
     408                }
     409        }
     410        return EOK;
    298411}
    299412
     
    377490                        rfb_pixel_format_to_host(&spf.pixel_format, &spf.pixel_format);
    378491                        fibril_mutex_lock(&rfb->lock);
    379                         rfb->pixel_format = spf.pixel_format;
     492                        rc = rfb_set_pixel_format(rfb, &spf.pixel_format);
    380493                        fibril_mutex_unlock(&rfb->lock);
     494                        if (rc != EOK)
     495                                return;
    381496                        printf("set pixel format\n");
    382497                        break;
  • uspace/srv/hid/rfb/rfb.h

    r0d23cc0 r2c9f6dd3  
    130130
    131131typedef struct {
     132        uint8_t message_type;
     133        uint8_t pad;
     134        uint16_t first_color;
     135        uint16_t color_count;
     136} __attribute((packed)) rfb_set_color_map_entries_t;
     137
     138typedef struct {
     139        uint16_t red;
     140        uint16_t green;
     141        uint16_t blue;
     142} __attribute__((packed)) rfb_color_map_entry_t;
     143
     144typedef struct {
    132145        uint16_t width;
    133146        uint16_t height;
     
    139152        bool damage_valid;
    140153        fibril_mutex_t lock;
     154        pixel_t *palette;
     155        size_t palette_used;
    141156} rfb_t;
    142157
Note: See TracChangeset for help on using the changeset viewer.