changeset: 55:ccee737658e4 tag: tip user: "Daniel P. Berrange " date: Fri Aug 24 17:19:37 2007 -0400 files: src/blt.h src/gvnc.c src/gvnc.h src/vncdisplay.c description: Fixed adjustment for mis-matched colour depths local vs remote diff -r b1c48ddc01d9 -r ccee737658e4 src/blt.h --- a/src/blt.h Wed Aug 22 15:10:12 2007 -0400 +++ b/src/blt.h Fri Aug 24 17:19:37 2007 -0400 @@ -32,7 +32,6 @@ static void FILL(struct gvnc *gvnc, src_ int x, int y, int width, int height) { uint8_t *dst = gvnc_get_local(gvnc, x, y); - struct gvnc_pixel_format *f = &gvnc->fmt; int i; for (i = 0; i < 1; i++) { @@ -40,9 +39,9 @@ static void FILL(struct gvnc *gvnc, src_ int j; for (j = 0; j < width; j++) { - *dp = ((*sp >> f->red_shift) & gvnc->rm) << gvnc->local.red_shift - | ((*sp >> f->green_shift) & gvnc->gm) << gvnc->local.green_shift - | ((*sp >> f->blue_shift) & gvnc->bm) << gvnc->local.blue_shift; + *dp = (((uint32_t)*sp >> gvnc->rrs) & gvnc->rm) << gvnc->rls + | (((uint32_t)*sp >> gvnc->grs) & gvnc->gm) << gvnc->gls + | (((uint32_t)*sp >> gvnc->brs) & gvnc->bm) << gvnc->bls; dp++; } dst += gvnc->local.linesize; @@ -56,7 +55,6 @@ static void BLIT(struct gvnc *gvnc, uint static void BLIT(struct gvnc *gvnc, uint8_t *src, int pitch, int x, int y, int w, int h) { uint8_t *dst = gvnc_get_local(gvnc, x, y); - struct gvnc_pixel_format *f = &gvnc->fmt; int i; for (i = 0; i < h; i++) { @@ -65,9 +63,9 @@ static void BLIT(struct gvnc *gvnc, uint int j; for (j = 0; j < w; j++) { - *dp = ((*sp >> f->red_shift) & gvnc->rm) << gvnc->local.red_shift - | ((*sp >> f->green_shift) & gvnc->gm) << gvnc->local.green_shift - | ((*sp >> f->blue_shift) & gvnc->bm) << gvnc->local.blue_shift; + *dp = (((uint32_t)*sp >> gvnc->rrs) & gvnc->rm) << gvnc->rls + | (((uint32_t)*sp >> gvnc->grs) & gvnc->gm) << gvnc->gls + | (((uint32_t)*sp >> gvnc->brs) & gvnc->bm) << gvnc->bls; dp++; sp++; } @@ -146,3 +144,12 @@ static void SUBRECT(struct gvnc *gvnc, u #undef BLIT #undef dst_pixel_t #undef src_pixel_t + + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r b1c48ddc01d9 -r ccee737658e4 src/gvnc.c --- a/src/gvnc.c Wed Aug 22 15:10:12 2007 -0400 +++ b/src/gvnc.c Fri Aug 24 17:19:37 2007 -0400 @@ -104,6 +104,8 @@ struct gvnc struct gvnc_framebuffer local; int rm, gm, bm; + int rrs, grs, brs; + int rls, gls, bls; gvnc_blt_func *blt; gvnc_hextile_func *hextile; @@ -673,7 +675,7 @@ static void gvnc_read_pixel_format(struc fmt->bits_per_pixel = gvnc_read_u8(gvnc); fmt->depth = gvnc_read_u8(gvnc); - fmt->big_endian_flag = gvnc_read_u8(gvnc); + fmt->byte_order = gvnc_read_u8(gvnc) ? __BIG_ENDIAN : __LITTLE_ENDIAN; fmt->true_color_flag = gvnc_read_u8(gvnc); fmt->red_max = gvnc_read_u16(gvnc); @@ -686,23 +688,12 @@ static void gvnc_read_pixel_format(struc gvnc_read(gvnc, pad, 3); - GVNC_DEBUG("Pixel format BPP: %d, Depth: %d, Endian: %d, True color: %d\n" + GVNC_DEBUG("Pixel format BPP: %d, Depth: %d, Byte order: %d, True color: %d\n" " Mask red: %3d, green: %3d, blue: %3d\n" " Shift red: %3d, green: %3d, blue: %3d\n", - fmt->bits_per_pixel, fmt->depth, fmt->big_endian_flag, fmt->true_color_flag, + fmt->bits_per_pixel, fmt->depth, fmt->byte_order, fmt->true_color_flag, fmt->red_max, fmt->green_max, fmt->blue_max, fmt->red_shift, fmt->green_shift, fmt->blue_shift); - - - if (((__BYTE_ORDER == __BIG_ENDIAN) && !fmt->big_endian_flag) || - ((__BYTE_ORDER == __LITTLE_ENDIAN) && fmt->big_endian_flag)) { - fmt->red_shift = fmt->bits_per_pixel - fmt->red_shift - (fmt->bits_per_pixel - fmt->depth); - fmt->green_shift = fmt->bits_per_pixel - fmt->green_shift - (fmt->bits_per_pixel - fmt->depth); - fmt->blue_shift = fmt->bits_per_pixel - fmt->blue_shift - (fmt->bits_per_pixel - fmt->depth); - - GVNC_DEBUG("Flipped shifts Shift red: %3d, green: %3d, blue: %3d\n", - fmt->red_shift, fmt->green_shift, fmt->blue_shift); - } } /* initialize function */ @@ -722,7 +713,7 @@ gboolean gvnc_set_pixel_format(struct gv gvnc_write_u8(gvnc, fmt->bits_per_pixel); gvnc_write_u8(gvnc, fmt->depth); - gvnc_write_u8(gvnc, fmt->big_endian_flag); + gvnc_write_u8(gvnc, fmt->byte_order == __BIG_ENDIAN ? 1 : 0); gvnc_write_u8(gvnc, fmt->true_color_flag); gvnc_write_u16(gvnc, fmt->red_max); @@ -1985,7 +1976,7 @@ gboolean gvnc_set_credential_x509_cert(s gboolean gvnc_set_local(struct gvnc *gvnc, struct gvnc_framebuffer *fb) { - int i, j; + int i, j, n; int depth; memcpy(&gvnc->local, fb, sizeof(*fb)); @@ -1997,8 +1988,7 @@ gboolean gvnc_set_local(struct gvnc *gvn fb->red_shift == gvnc->fmt.red_shift && fb->green_shift == gvnc->fmt.green_shift && fb->blue_shift == gvnc->fmt.blue_shift && - ((gvnc->fmt.big_endian_flag && (__BYTE_ORDER == __BIG_ENDIAN)) || - (!gvnc->fmt.big_endian_flag && (__BYTE_ORDER == __LITTLE_ENDIAN)))) + __BYTE_ORDER == gvnc->fmt.byte_order) gvnc->perfect_match = TRUE; else gvnc->perfect_match = FALSE; @@ -2016,6 +2006,47 @@ gboolean gvnc_set_local(struct gvnc *gvn gvnc->local.red_mask, gvnc->local.green_mask, gvnc->local.blue_mask, gvnc->fmt.red_max, gvnc->fmt.green_max, gvnc->fmt.blue_max, gvnc->rm, gvnc->gm, gvnc->bm); + + /* Setup shifts assuming matched bpp (but not neccessarily match rgb order)*/ + gvnc->rrs = gvnc->fmt.red_shift; + gvnc->grs = gvnc->fmt.green_shift; + gvnc->brs = gvnc->fmt.blue_shift; + + gvnc->rls = gvnc->local.red_shift; + gvnc->gls = gvnc->local.green_shift; + gvnc->bls = gvnc->local.blue_shift; + + + /* This adjusts for server/client endianness mismatch */ + if (__BYTE_ORDER != gvnc->fmt.byte_order) { + gvnc->rrs = gvnc->fmt.bits_per_pixel - gvnc->rrs - (gvnc->fmt.bits_per_pixel - gvnc->fmt.depth); + gvnc->grs = gvnc->fmt.bits_per_pixel - gvnc->grs - (gvnc->fmt.bits_per_pixel - gvnc->fmt.depth); + gvnc->brs = gvnc->fmt.bits_per_pixel - gvnc->brs - (gvnc->fmt.bits_per_pixel - gvnc->fmt.depth); + + GVNC_DEBUG("Flipped shifts red: %3d, green: %3d, blue: %3d\n", + gvnc->rrs, gvnc->grs, gvnc->brs); + } + + + /* This adjusts for remote having more bpp than local */ + for (n = gvnc->fmt.red_max; n > gvnc->local.red_mask ; n>>= 1) + gvnc->rrs++; + for (n = gvnc->fmt.green_max; n > gvnc->local.green_mask ; n>>= 1) + gvnc->grs++; + for (n = gvnc->fmt.blue_max; n > gvnc->local.blue_mask ; n>>= 1) + gvnc->brs++; + + /* This adjusts for remote having less bpp than remote */ + for (n = gvnc->local.red_mask ; n > gvnc->fmt.red_max ; n>>= 1) + gvnc->rls++; + for (n = gvnc->local.green_mask ; n > gvnc->fmt.green_max ; n>>= 1) + gvnc->gls++; + for (n = gvnc->local.blue_mask ; n > gvnc->fmt.blue_max ; n>>= 1) + gvnc->bls++; + GVNC_DEBUG("Pixel shifts\n right: %3d %3d %3d\n left: %3d %3d %3d\n", + gvnc->rrs, gvnc->grs, gvnc->brs, + gvnc->rls, gvnc->gls, gvnc->bls); + i = gvnc->fmt.bits_per_pixel / 8; j = gvnc->local.bpp; diff -r b1c48ddc01d9 -r ccee737658e4 src/gvnc.h --- a/src/gvnc.h Wed Aug 22 15:10:12 2007 -0400 +++ b/src/gvnc.h Fri Aug 24 17:19:37 2007 -0400 @@ -24,7 +24,7 @@ struct gvnc_pixel_format { uint8_t bits_per_pixel; uint8_t depth; - uint8_t big_endian_flag; + uint16_t byte_order; uint8_t true_color_flag; uint16_t red_max; uint16_t green_max; diff -r b1c48ddc01d9 -r ccee737658e4 src/vncdisplay.c --- a/src/vncdisplay.c Wed Aug 22 15:10:12 2007 -0400 +++ b/src/vncdisplay.c Fri Aug 24 17:19:37 2007 -0400 @@ -426,7 +426,6 @@ static gboolean on_resize(void *opaque, VncDisplay *obj = VNC_DISPLAY(opaque); VncDisplayPrivate *priv = obj->priv; GdkVisual *visual; - int depth; if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc)) return TRUE; @@ -446,9 +445,8 @@ static gboolean on_resize(void *opaque, priv->gc = gdk_gc_new(GTK_WIDGET(obj)->window); } - depth = gdk_drawable_get_depth(GTK_WIDGET(obj)->window); - visual = gdk_visual_get_best_with_depth(depth); - + visual = gdk_drawable_get_visual(GTK_WIDGET(obj)->window); + priv->shm_image = vnc_shm_image_new(visual, width, height, priv->use_shm); priv->fb.shm_id = priv->shm_image->shmid;