Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 182401 Details for
Bug 253598
No cursor connecting to OSX server
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch to add RichCursor + XCursor extensions
gtk-vnc-cursor-2.patch (text/plain), 11.18 KB, created by
Daniel Berrangé
on 2007-08-31 02:08:08 UTC
(
hide
)
Description:
Patch to add RichCursor + XCursor extensions
Filename:
MIME Type:
Creator:
Daniel Berrangé
Created:
2007-08-31 02:08:08 UTC
Size:
11.18 KB
patch
obsolete
>diff -r b1c48ddc01d9 src/gvnc.c >--- a/src/gvnc.c Wed Aug 22 15:10:12 2007 -0400 >+++ b/src/gvnc.c Thu Aug 30 21:33:56 2007 -0400 >@@ -1057,6 +1057,119 @@ static void gvnc_shared_memory_rmid(stru > if (!gvnc->ops.shared_memory_rmid(gvnc->ops_data, shmid)) > gvnc->has_error = TRUE; > } >+ >+#define RICH_CURSOR_BLIT(gvnc, pixbuf, image, mask, pitch, width, height, src_pixel_t) \ >+ do { \ >+ int x, y; \ >+ uint8_t *src = image; \ >+ uint32_t *dst = (uint32_t*)pixbuf; \ >+ uint8_t *alpha = mask; \ >+ for (y = 0; y < height; y++) { \ >+ src_pixel_t *sp = (src_pixel_t *)src; \ >+ uint8_t *mp = alpha; \ >+ for (x = 0; x < width; x++) { \ >+ *dst++ = (((mp[x/8] >> (7-(x % 8))) &1) ? (255 << 24) : 0) \ >+ | (((*sp >> gvnc->fmt.red_shift) & (gvnc->fmt.red_max)) << 16) \ >+ | (((*sp >> gvnc->fmt.green_shift) & (gvnc->fmt.green_max)) << 8) \ >+ | (((*sp >> gvnc->fmt.blue_shift) & (gvnc->fmt.blue_max)) << 0); \ >+ sp++; \ >+ } \ >+ src += pitch; \ >+ alpha += ((width+7)/8); \ >+ } \ >+ } while(0) >+ >+static void gvnc_rich_cursor(struct gvnc *gvnc, int x, int y, int width, int height) >+{ >+ uint8_t *pixbuf = NULL; >+ >+ if (width && height) { >+ uint8_t *image, *mask; >+ int imagelen, masklen; >+ >+ imagelen = width * height * (gvnc->fmt.bits_per_pixel / 8); >+ masklen = ((width + 7)/8) * height; >+ >+ image = malloc(imagelen); >+ mask = malloc(masklen); >+ pixbuf = malloc(width * height * 4); /* RGB-A 8bit */ >+ gvnc_read(gvnc, image, imagelen); >+ gvnc_read(gvnc, mask, masklen); >+ >+ if (gvnc->fmt.bits_per_pixel == 8) { >+ RICH_CURSOR_BLIT(gvnc, pixbuf, image, mask, width * (gvnc->fmt.bits_per_pixel/8), width, height, uint8_t); >+ } else if (gvnc->fmt.bits_per_pixel == 16) { >+ RICH_CURSOR_BLIT(gvnc, pixbuf, image, mask, width * (gvnc->fmt.bits_per_pixel/8), width, height, uint16_t); >+ } else if (gvnc->fmt.bits_per_pixel == 24 || gvnc->fmt.bits_per_pixel == 32) { >+ RICH_CURSOR_BLIT(gvnc, pixbuf, image, mask, width * (gvnc->fmt.bits_per_pixel/8), width, height, uint32_t); >+ } >+ free(image); >+ free(mask); >+ } >+ >+ if (gvnc->has_error || !gvnc->ops.local_cursor) >+ return; >+ if (!gvnc->ops.local_cursor(gvnc->ops_data, x, y, width, height, pixbuf)) >+ gvnc->has_error = TRUE; >+ >+ free(pixbuf); >+} >+ >+ >+static void gvnc_xcursor(struct gvnc *gvnc, int x, int y, int width, int height) >+{ >+ uint8_t *pixbuf = NULL; >+ >+ if (width && height) { >+ uint8_t *data, *mask, *datap, *maskp; >+ uint32_t *pixp; >+ int rowlen; >+ int x1, y1; >+ uint8_t fgrgb[3], bgrgb[3]; >+ uint32_t fg, bg; >+ gvnc_read(gvnc, fgrgb, 3); >+ gvnc_read(gvnc, bgrgb, 3); >+ fg = (255 << 24) | (fgrgb[0] << 16) | (fgrgb[1] << 8) | fgrgb[2]; >+ bg = (255 << 24) | (bgrgb[0] << 16) | (bgrgb[1] << 8) | bgrgb[2]; >+ >+ rowlen = ((width + 7)/8); >+ if (!(data = malloc(rowlen*height))) { >+ gvnc->has_error = TRUE; >+ return; >+ } >+ if (!(mask = malloc(rowlen*height))) { >+ free(data); >+ gvnc->has_error = TRUE; >+ return; >+ } >+ pixbuf = malloc(width * height * 4); /* RGB-A 8bit */ >+ gvnc_read(gvnc, data, rowlen*height); >+ gvnc_read(gvnc, mask, rowlen*height); >+ datap = data; >+ maskp = mask; >+ pixp = (uint32_t*)pixbuf; >+ for (y1 = 0; y1 < height; y1++) { >+ for (x1 = 0; x1 < width; x1++) { >+ *pixp++ = ((maskp[x1 / 8] >> (7-(x1 % 8))) & 1) ? >+ (((datap[x1 / 8] >> (7-(x1 % 8))) & 1) ? fg : bg) : 0; >+ } >+ datap += rowlen; >+ maskp += rowlen; >+ } >+ free(data); >+ free(mask); >+ } >+ >+ >+ >+ if (gvnc->has_error || !gvnc->ops.local_cursor) >+ return; >+ if (!gvnc->ops.local_cursor(gvnc->ops_data, x, y, width, height, pixbuf)) >+ gvnc->has_error = TRUE; >+ >+ free(pixbuf); >+} >+ > > static void gvnc_framebuffer_update(struct gvnc *gvnc, int32_t etype, > uint16_t x, uint16_t y, >@@ -1096,6 +1209,12 @@ static void gvnc_framebuffer_update(stru > break; > } > break; >+ case GVNC_ENCODING_RICH_CURSOR: >+ gvnc_rich_cursor(gvnc, x, y, width, height); >+ break; >+ case GVNC_ENCODING_XCURSOR: >+ gvnc_xcursor(gvnc, x, y, width, height); >+ break; > default: > gvnc->has_error = TRUE; > break; >diff -r b1c48ddc01d9 src/gvnc.h >--- a/src/gvnc.h Wed Aug 22 15:10:12 2007 -0400 >+++ b/src/gvnc.h Thu Aug 30 21:26:43 2007 -0400 >@@ -18,6 +18,7 @@ struct gvnc_ops > gboolean (*resize)(void *, int, int); > gboolean (*pointer_type_change)(void *, int); > gboolean (*shared_memory_rmid)(void *, int); >+ gboolean (*local_cursor)(void *, int, int, int, int, uint8_t *); > }; > > struct gvnc_pixel_format >@@ -68,7 +69,7 @@ typedef enum { > GVNC_ENCODING_DESKTOP_RESIZE = -223, > GVNC_ENCODING_CURSOR_POS = -232, > GVNC_ENCODING_RICH_CURSOR = -239, >- GVNC_ENCODING_XCUSOR = -240, >+ GVNC_ENCODING_XCURSOR = -240, > > GVNC_ENCODING_POINTER_CHANGE = -257, > GVNC_ENCODING_SHARED_MEMORY = -258, >diff -r b1c48ddc01d9 src/vncdisplay.c >--- a/src/vncdisplay.c Wed Aug 22 15:10:12 2007 -0400 >+++ b/src/vncdisplay.c Thu Aug 30 21:32:29 2007 -0400 >@@ -35,6 +35,7 @@ struct _VncDisplayPrivate > GdkGC *gc; > VncShmImage *shm_image; > GdkCursor *null_cursor; >+ GdkCursor *remote_cursor; > > struct gvnc_framebuffer fb; > struct coroutine coroutine; >@@ -140,7 +141,7 @@ static gboolean expose_event(GtkWidget * > return TRUE; > } > >-static void do_keyboard_grab(VncDisplay *obj) >+static void do_keyboard_grab(VncDisplay *obj, gboolean quiet) > { > VncDisplayPrivate *priv = obj->priv; > >@@ -148,27 +149,29 @@ static void do_keyboard_grab(VncDisplay > FALSE, > GDK_CURRENT_TIME); > priv->in_keyboard_grab = TRUE; >- g_signal_emit(obj, signals[VNC_KEYBOARD_GRAB], 0); >-} >- >- >-static void do_keyboard_ungrab(VncDisplay *obj) >+ if (!quiet) >+ g_signal_emit(obj, signals[VNC_KEYBOARD_GRAB], 0); >+} >+ >+ >+static void do_keyboard_ungrab(VncDisplay *obj, gboolean quiet) > { > VncDisplayPrivate *priv = obj->priv; > > gdk_keyboard_ungrab(GDK_CURRENT_TIME); > priv->in_keyboard_grab = FALSE; >- g_signal_emit(obj, signals[VNC_KEYBOARD_UNGRAB], 0); >-} >- >- >-static void do_pointer_grab(VncDisplay *obj) >+ if (!quiet) >+ g_signal_emit(obj, signals[VNC_KEYBOARD_UNGRAB], 0); >+} >+ >+ >+static void do_pointer_grab(VncDisplay *obj, gboolean quiet) > { > VncDisplayPrivate *priv = obj->priv; > > /* If we're not already grabbing keyboard, grab it now */ > if (!priv->grab_keyboard) >- do_keyboard_grab(obj); >+ do_keyboard_grab(obj, quiet); > > gdk_pointer_grab(GTK_WIDGET(obj)->window, > TRUE, >@@ -178,36 +181,39 @@ static void do_pointer_grab(VncDisplay * > GDK_BUTTON_MOTION_MASK | > GDK_SCROLL_MASK, > GTK_WIDGET(obj)->window, >- priv->null_cursor, >+ priv->remote_cursor ? priv->remote_cursor : priv->null_cursor, > GDK_CURRENT_TIME); > priv->in_pointer_grab = TRUE; >- g_signal_emit(obj, signals[VNC_POINTER_GRAB], 0); >-} >- >-static void do_pointer_ungrab(VncDisplay *obj) >+ if (!quiet) >+ g_signal_emit(obj, signals[VNC_POINTER_GRAB], 0); >+} >+ >+static void do_pointer_ungrab(VncDisplay *obj, gboolean quiet) > { > VncDisplayPrivate *priv = obj->priv; > > /* If we grabed keyboard upon pointer grab, then ungrab it now */ > if (!priv->grab_keyboard) >- do_keyboard_ungrab(obj); >+ do_keyboard_ungrab(obj, quiet); > > gdk_pointer_ungrab(GDK_CURRENT_TIME); > priv->in_pointer_grab = FALSE; >- g_signal_emit(obj, signals[VNC_POINTER_UNGRAB], 0); >+ if (!quiet) >+ g_signal_emit(obj, signals[VNC_POINTER_UNGRAB], 0); > } > > static void do_pointer_hide(VncDisplay *obj) > { > VncDisplayPrivate *priv = obj->priv; > gdk_window_set_cursor(GTK_WIDGET(obj)->window, >- priv->null_cursor); >+ priv->remote_cursor ? priv->remote_cursor : priv->null_cursor); > } > > static void do_pointer_show(VncDisplay *obj) > { >+ VncDisplayPrivate *priv = obj->priv; > gdk_window_set_cursor(GTK_WIDGET(obj)->window, >- NULL); >+ priv->remote_cursor); > } > > >@@ -223,7 +229,7 @@ static gboolean button_event(GtkWidget * > if ((priv->grab_pointer || !priv->absolute) && > !priv->in_pointer_grab && > button->button == 1 && button->type == GDK_BUTTON_PRESS) >- do_pointer_grab(VNC_DISPLAY(widget)); >+ do_pointer_grab(VNC_DISPLAY(widget), FALSE); > > n = 1 << (button->button - 1); > if (button->type == GDK_BUTTON_PRESS) >@@ -369,9 +375,9 @@ static gboolean key_event(GtkWidget *wid > ((keyval == GDK_Control_L && (key->state & GDK_MOD1_MASK)) || > (keyval == GDK_Alt_L && (key->state & GDK_CONTROL_MASK)))) { > if (priv->in_pointer_grab) >- do_pointer_ungrab(VNC_DISPLAY(widget)); >+ do_pointer_ungrab(VNC_DISPLAY(widget), FALSE); > else >- do_pointer_grab(VNC_DISPLAY(widget)); >+ do_pointer_grab(VNC_DISPLAY(widget), FALSE); > } > > return TRUE; >@@ -389,7 +395,7 @@ static gboolean enter_event(GtkWidget *w > return TRUE; > > if (priv->grab_keyboard) >- do_keyboard_grab(VNC_DISPLAY(widget)); >+ do_keyboard_grab(VNC_DISPLAY(widget), FALSE); > > return TRUE; > } >@@ -406,7 +412,7 @@ static gboolean leave_event(GtkWidget *w > return TRUE; > > if (priv->grab_keyboard) >- do_keyboard_ungrab(VNC_DISPLAY(widget)); >+ do_keyboard_ungrab(VNC_DISPLAY(widget), FALSE); > > return TRUE; > } >@@ -482,7 +488,7 @@ static gboolean on_pointer_type_change(v > VncDisplayPrivate *priv = obj->priv; > > if (absolute && priv->in_pointer_grab && !priv->grab_pointer) >- do_pointer_ungrab(obj); >+ do_pointer_ungrab(obj, FALSE); > > priv->absolute = absolute; > return TRUE; >@@ -570,6 +576,35 @@ static gboolean on_auth_subtype(void *op > gvnc_set_auth_subtype(priv->gvnc, types[0]); > > return TRUE; >+} >+ >+static gboolean on_local_cursor(void *opaque, int x, int y, int width, int height, uint8_t *image) >+{ >+ VncDisplay *obj = VNC_DISPLAY(opaque); >+ VncDisplayPrivate *priv = obj->priv; >+ >+ if (priv->remote_cursor) { >+ gdk_cursor_unref(priv->remote_cursor); >+ priv->remote_cursor = NULL; >+ } >+ >+ if (width && height) { >+ GdkDisplay *display = gdk_drawable_get_display(GDK_DRAWABLE(GTK_WIDGET(obj)->window)); >+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(image, GDK_COLORSPACE_RGB, >+ TRUE, 8, width, height, >+ width * 4, NULL, NULL); >+ priv->remote_cursor = gdk_cursor_new_from_pixbuf(display, >+ pixbuf, >+ x, y); >+ gdk_pixbuf_unref(pixbuf); >+ } >+ >+ if (priv->in_pointer_grab) { >+ do_pointer_ungrab(obj, TRUE); >+ do_pointer_grab(obj, TRUE); >+ } else { >+ do_pointer_hide(obj); >+ } > } > > >@@ -581,6 +616,7 @@ static const struct gvnc_ops vnc_display > .resize = on_resize, > .pointer_type_change = on_pointer_type_change, > .shared_memory_rmid = on_shared_memory_rmid, >+ .local_cursor = on_local_cursor, > }; > > static void *vnc_coroutine(void *opaque) >@@ -588,6 +624,8 @@ static void *vnc_coroutine(void *opaque) > VncDisplay *obj = VNC_DISPLAY(opaque); > VncDisplayPrivate *priv = obj->priv; > int32_t encodings[] = { GVNC_ENCODING_DESKTOP_RESIZE, >+ GVNC_ENCODING_RICH_CURSOR, >+ GVNC_ENCODING_XCURSOR, > GVNC_ENCODING_SHARED_MEMORY, > GVNC_ENCODING_POINTER_CHANGE, > GVNC_ENCODING_HEXTILE, >@@ -966,7 +1004,7 @@ void vnc_display_set_pointer_grab(VncDis > > priv->grab_pointer = enable; > if (!enable && priv->absolute && priv->in_pointer_grab) >- do_pointer_ungrab(obj); >+ do_pointer_ungrab(obj, FALSE); > } > > void vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable) >@@ -975,7 +1013,7 @@ void vnc_display_set_keyboard_grab(VncDi > > priv->grab_keyboard = enable; > if (!enable && priv->in_keyboard_grab && !priv->in_pointer_grab) >- do_keyboard_ungrab(obj); >+ do_keyboard_ungrab(obj, FALSE); > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 253598
:
182241
| 182401