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]