Re: [gtk-vnc-devel] Mouse pointer patch, take 2
- From: "Jorge Pereira" <jpereiran gmail com>
- To: "Rob Stoddard" <rstoddard telanetix com>
- Cc: gtk-vnc-devel List <gtk-vnc-devel lists sourceforge net>
- Subject: Re: [gtk-vnc-devel] Mouse pointer patch, take 2
- Date: Thu, 10 Apr 2008 16:16:45 -0300
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]