From 02c20b1e4c9268075c8594e0d80e492b811ca9da Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 29 Aug 2007 16:33:24 +0000 Subject: [PATCH] Fixed mixed colour depths --- gtk-vnc-0.1.0-colour-depth.patch | 226 +++++++++++++++++++++++++++++++ gtk-vnc.spec | 7 +- 2 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 gtk-vnc-0.1.0-colour-depth.patch diff --git a/gtk-vnc-0.1.0-colour-depth.patch b/gtk-vnc-0.1.0-colour-depth.patch new file mode 100644 index 0000000..8f98b8a --- /dev/null +++ b/gtk-vnc-0.1.0-colour-depth.patch @@ -0,0 +1,226 @@ +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; + + diff --git a/gtk-vnc.spec b/gtk-vnc.spec index 8d7f8e4..4e941dc 100644 --- a/gtk-vnc.spec +++ b/gtk-vnc.spec @@ -3,13 +3,14 @@ Summary: A GTK widget for VNC clients Name: gtk-vnc Version: 0.1.0 -Release: 4%{?dist} +Release: 5%{?dist} License: LGPLv2+ Group: Development/Libraries Source: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz Patch1: %{name}-%{version}-clear-area.patch Patch2: %{name}-%{version}-endian-bgr.patch Patch3: %{name}-%{version}-python-demo.patch +Patch4: %{name}-%{version}-colour-depth.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) URL: http://gtk-vnc.sf.net/ BuildRequires: gtk2-devel pygtk2-devel python-devel gnutls-devel @@ -47,6 +48,7 @@ A module allowing use of the GTK-VNC widget from python %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 %build %configure @@ -86,6 +88,9 @@ rm -fr %{buildroot} %{_libdir}/python*/site-packages/gtkvnc.so %changelog +* Wed Aug 29 2007 Daniel P. Berrange - 0.1.0-5.fc8 +- Fixed handling of mis-matched client/server colour depths + * Wed Aug 22 2007 Daniel P. Berrange - 0.1.0-4.fc8 - Fix mixed endian handling & BGR pixel format (rhbz #253597) - Clear widget areas outside of framebuffer (rhbz #253599)