Re: [gtk-vnc-devel] Mouse pointer patch, take 2



yep!

i think that bettere "attach" this patch in mail, and not paste and de body of email.

[]s

On Thu, Apr 10, 2008 at 2:51 PM, Rob Stoddard <rstoddard telanetix com> wrote:
Sorry about tarring and gzipping a set of patches...  first time submitting patches as such.   I usually don't make changes to libraries.  Here's the combined patch.  I really don't consider it a complete fix for everybody's needs, it's a good start to getting the pointer motion in Tight.  OpenGL works,   wasn't able to get the Gdk image to draw...  I don't know Gdk well enough and don't have the time to figure out what's going on in there.   I hope somebody can make the Gdk portion work.

What I've implemented is a software cursor.  The reason for this is because I intend to use more than one VNC per computer, so the mouse pointer will bounce around between the VNC displays.  I also think that scaling wouldn't look very good with a "hardware" cursor...  The cursor wouldn't scale with the rest of the display.  I also fixed up the OpenGL code a little; the vertecies and projection was based upon the texture size, not the framebuffer size... that caused some rather interesting issues with the mouse pointer position.

Have fun,

Rob Stoddard

diff -uNr gtk-vnc-0.3.5/src/gvnc.c gtk-vnc-mine/src/gvnc.c
--- gtk-vnc-0.3.5/src/gvnc.c    2008-04-06 15:35:22.000000000 -0700
+++ gtk-vnc-mine/src/gvnc.c     2008-04-08 15:59:54.000000000 -0700
@@ -1858,6 +1858,18 @@
       }
 }

+
+static void gvnc_pointer_pos_change(struct gvnc *gvnc, int x, int y)
+{
+       if(gvnc->has_error || !gvnc->ops.pointer_pos_change)
+                return;
+       if (!gvnc->ops.pointer_pos_change(gvnc->ops_data, x, y))
+       {
+                GVNC_DEBUG("Closing the connection: gvnc_pointer_pos_change\n");
+                gvnc->has_error = TRUE;
+        }
+}
+
 static void gvnc_rich_cursor_blt(struct gvnc *gvnc, uint8_t *pixbuf,
                                uint8_t *image, uint8_t *mask,
                                int pitch, uint16_t width, uint16_t height)
@@ -1865,6 +1877,8 @@
       gvnc->rich_cursor_blt(gvnc, pixbuf, image, mask, pitch, width, height);
 }

+
+
 static void gvnc_rich_cursor(struct gvnc *gvnc, int x, int y, int width, int height)
 {
       uint8_t *pixbuf = NULL;
@@ -2021,6 +2035,9 @@
       case GVNC_ENCODING_EXT_KEY_EVENT:
               gvnc->has_ext_key_event = TRUE;
               break;
+       case GVNC_ENCODING_CURSOR_POS:
+               gvnc_pointer_pos_change(gvnc, x, y);
+               break;
       default:
               GVNC_DEBUG("Received an unknown encoding type: %d\n", etype);
               gvnc->has_error = TRUE;
@@ -2046,6 +2063,8 @@
               }
       } while ((ret = gvnc_read_u8_interruptable(gvnc, &msg)) == -EAGAIN);

+       GVNC_DEBUG("Got char %d for message type.\n", msg);
+
       if (ret < 0) {
               GVNC_DEBUG("Aborting message processing on error\n");
               return !gvnc_has_error(gvnc);
@@ -2056,7 +2075,7 @@
               uint8_t pad[1];
               uint16_t n_rects;
               int i;
-
+GVNC_DEBUG("Framebuffer update.");
               gvnc_read(gvnc, pad, 1);
               n_rects = gvnc_read_u16(gvnc);
               for (i = 0; i < n_rects; i++) {
@@ -2077,7 +2096,7 @@
               uint16_t n_colors;
               uint8_t pad[1];
               int i;
-
+GVNC_DEBUG("Colormap entries");
               gvnc_read(gvnc, pad, 1);
               first_color = gvnc_read_u16(gvnc);
               n_colors = gvnc_read_u16(gvnc);
@@ -2095,13 +2114,14 @@
               }
       }       break;
       case 2: /* Bell */
+GVNC_DEBUG("Bell.");
               gvnc_bell(gvnc);
               break;
       case 3: { /* ServerCutText */
               uint8_t pad[3];
               uint32_t n_text;
               char *data;
-
+GVNC_DEBUG("Server cut text.");
               gvnc_read(gvnc, pad, 3);
               n_text = gvnc_read_u32(gvnc);
               if (n_text > (32 << 20)) {
diff -uNr gtk-vnc-0.3.5/src/gvnc.h gtk-vnc-mine/src/gvnc.h
--- gtk-vnc-0.3.5/src/gvnc.h    2008-03-11 09:26:04.000000000 -0700
+++ gtk-vnc-mine/src/gvnc.h     2008-04-08 15:41:03.000000000 -0700
@@ -23,6 +23,7 @@
       gboolean (*resize)(void *, int, int);
        gboolean (*pixel_format)(void *, struct gvnc_pixel_format *);
       gboolean (*pointer_type_change)(void *, int);
+       gboolean (*pointer_pos_change)(void*, int, int);
       gboolean (*local_cursor)(void *, int, int, int, int, uint8_t *);
       gboolean (*auth_unsupported)(void *, unsigned int);
       gboolean (*render_jpeg)(void *, rgb24_render_func *render, void *,
@@ -90,6 +91,7 @@
       GVNC_ENCODING_DESKTOP_RESIZE = -223,
        GVNC_ENCODING_WMVi = 0x574D5669,

+
       GVNC_ENCODING_CURSOR_POS = -232,
       GVNC_ENCODING_RICH_CURSOR = -239,
       GVNC_ENCODING_XCURSOR = -240,
diff -uNr gtk-vnc-0.3.5/src/vncdisplay.c gtk-vnc-mine/src/vncdisplay.c
--- gtk-vnc-0.3.5/src/vncdisplay.c      2008-04-06 15:35:22.000000000 -0700
+++ gtk-vnc-mine/src/vncdisplay.c       2008-04-09 09:51:57.000000000 -0700
@@ -41,6 +41,7 @@
       char *port;
       GdkGC *gc;
       GdkImage *image;
+       GdkPixbuf *ptr_image;
       GdkCursor *null_cursor;
       GdkCursor *remote_cursor;

@@ -55,6 +56,11 @@
       int gl_width;
       int gl_height;
       GLuint gl_tex;
+       GLuint gl_ptr_tex;
+       int ptr_width;
+       int ptr_height;
+       int ptr_x;
+       int ptr_y;
 #endif

       struct gvnc_framebuffer fb;
@@ -292,7 +298,15 @@
       if (priv->gl_enabled) {
               float rx, ry;
               int wx = 0, wy = 0;
-               int ww = priv->gl_width, wh = priv->gl_height;
+               int ww = priv->fb.width;
+               int wh = priv->fb.height;
+
+               int px = priv->last_x - priv->ptr_x;
+               int py = priv->fb.height - priv->last_y + priv->ptr_y - priv->ptr_height;
+
+               int pw = priv->ptr_width;
+               int ph = priv->ptr_height;
+
               double scale_x, scale_y;

               scale_x = (double)priv->gl_width / priv->fb.width;
@@ -320,7 +334,10 @@
               w -= x;
               h -= y;

+
               gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
+               glEnable(GL_TEXTURE_2D);
+               glDisable(GL_DEPTH_TEST);
               glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
               glPixelStorei(GL_UNPACK_ROW_LENGTH, priv->fb.width);
               glTexSubImage2D(GL_TEXTURE_2D, 0,
@@ -332,16 +349,30 @@
                               x * 4);
               rx = (float)priv->fb.width  / priv->gl_texture_width;
               ry = (float)priv->fb.height / priv->gl_texture_height;
-
-               glEnable(GL_TEXTURE_2D);
-               glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+               glEnable(GL_BLEND);
+               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+               /*  Draw the screen  */
               glBegin(GL_QUADS);
               glTexCoord2f(0,ry);  glVertex3f(wx, wy, 0);
               glTexCoord2f(0,0);  glVertex3f(wx, wy+wh, 0);
               glTexCoord2f(rx,0);  glVertex3f(wx+ww, wy+wh, 0);
               glTexCoord2f(rx,ry);  glVertex3f(wx+ww, wy, 0);
-               glEnd();
+               glEnd();
+
+               glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+               /*  Draw the pointer  */
+               glBindTexture(GL_TEXTURE_2D, priv->gl_ptr_tex);
+
+               glBegin(GL_QUADS);
+                glTexCoord2f(0.0f, 1.0f);  glVertex3f(px, py, 0.0f);
+                glTexCoord2f(0.0f, 0.0f);  glVertex3f(px, py+ph, 0.0f);
+                glTexCoord2f(1.0f, 0.0f);  glVertex3f(px+pw, py+ph, 0.0f);
+                glTexCoord2f(1.0f, 1.0f);  glVertex3f(px+pw, py, 0.0f);
+                glEnd();
+               glEnable(GL_DEPTH_TEST);
               glDisable(GL_TEXTURE_2D);
+               glDisable(GL_BLEND);
               glFlush();
               gdk_gl_drawable_gl_end(priv->gl_drawable);
       } else
@@ -378,9 +409,16 @@
               gdk_region_subtract(clear, copy);

               gdk_gc_set_clip_region(priv->gc, copy);
+
+               /*  Draw the screen  */
               gdk_draw_image(widget->window, priv->gc, priv->image,
                              x, y, x + mx, y + my, w, h);

+               /* draw the pointer image */
+               if(priv->ptr_image)
+                       gdk_draw_pixbuf(widget->window, priv->gc, priv->ptr_image,
+                               0, 0, priv->last_x, priv->fb.height - priv->last_y, priv->ptr_width, priv->ptr_height, GDK_RGB_DITHER_NONE, 0, 0);
+
               gdk_gc_set_clip_region(priv->gc, clear);
               gdk_draw_rectangle(widget->window, priv->gc, TRUE, expose->area.x, expose->area.y,
                                  expose->area.width, expose->area.height);
@@ -900,6 +938,10 @@
       gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);

       glGenTextures(1, &priv->gl_tex);
+       glGenTextures(1, &priv->gl_ptr_tex);
+       glBindTexture(GL_TEXTURE_2D, priv->gl_ptr_tex);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glBindTexture(GL_TEXTURE_2D, priv->gl_tex);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -1160,7 +1202,7 @@
       glViewport(0, 0, priv->gl_width, priv->gl_height);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
-       glOrtho(0.0, priv->gl_width, 0.0, priv->gl_height, -1, 1);
+       glOrtho(0.0, priv->fb.width, 0.0, priv->fb.height, -1, 1);
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
       gdk_gl_drawable_gl_end(priv->gl_drawable);
@@ -1224,6 +1266,20 @@
       return TRUE;
 }

+
+static gboolean on_pointer_pos_change(void *opaque, int x, int y)
+{
+       GtkWidget *widget = GTK_WIDGET(opaque);
+       VncDisplay *obj = VNC_DISPLAY(opaque);
+        VncDisplayPrivate *priv = obj->priv;
+
+       priv->last_x = x;
+       priv->last_y = y;
+
+       gtk_widget_queue_draw_area(widget, x, priv->fb.height - y, 32, 32);
+}
+
+
 static gboolean on_auth_cred(void *opaque)
 {
       VncDisplay *obj = VNC_DISPLAY(opaque);
@@ -1345,17 +1401,28 @@
               priv->remote_cursor = NULL;
       }

-       if (width && height) {
+       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,
+               priv->ptr_image = 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 WITH_GTKGLEXT
+        if (priv->gl_enabled)
+       {
+               priv->ptr_width = width;
+               priv->ptr_height = height;
+               priv->ptr_x = x;
+               priv->ptr_y = y;
+               gdk_gl_drawable_gl_begin(priv->gl_drawable, priv->gl_context);
+               glEnable(GL_TEXTURE_2D);
+               glBindTexture(GL_TEXTURE_2D, priv->gl_ptr_tex);
+               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+               glDisable(GL_TEXTURE_2D);
+               gdk_gl_drawable_gl_end(priv->gl_drawable);
+       }
+#endif
       if (priv->in_pointer_grab) {
               do_pointer_ungrab(obj, TRUE);
               do_pointer_grab(obj, TRUE);
@@ -1420,6 +1487,7 @@
       .resize = on_resize,
        .pixel_format = on_pixel_format,
       .pointer_type_change = on_pointer_type_change,
+       .pointer_pos_change = on_pointer_pos_change,
       .local_cursor = on_local_cursor,
       .auth_unsupported = on_auth_unsupported,
       .server_cut_text = on_server_cut_text,
@@ -1456,7 +1524,8 @@
                               GVNC_ENCODING_HEXTILE,
                               GVNC_ENCODING_RRE,
                               GVNC_ENCODING_COPY_RECT,
-                               GVNC_ENCODING_RAW };
+                               GVNC_ENCODING_RAW,
+                               GVNC_ENCODING_CURSOR_POS };
       int32_t *encodingsp;
       int n_encodings;
       int ret;
@@ -2063,6 +2132,7 @@
       priv->grab_pointer = FALSE;
       priv->grab_keyboard = FALSE;
       priv->local_pointer = FALSE;
+       priv->ptr_image = NULL;

 #if WITH_GTKGLEXT
       if (gtk_gl_init_check(NULL, NULL)) {

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Gtk-vnc-devel mailing list
Gtk-vnc-devel lists sourceforge net
https://lists.sourceforge.net/lists/listinfo/gtk-vnc-devel




--
Regards,
+ ---------------------------------------------------------------------------------+
Jorge Pereira, From: Olinda/Pe/Brazil
Home: http://www.jorgepereira.com.br/
E-mail: jpereiran gmail com, jorge jorgepereira com br
Mobile: +55 (81) 8833-2484
My Public Key: http://www.jorgepereira.com.br/public.pgp
+ ---------------------------------------------------------------------------------+
"Se você ama alguma coisa, liberte-a;
Se ela não voltar a ti, cace-a e mate-a."
+----------------------------------------------------------------------------------+

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]