diff options
author | kraxel <kraxel> | 2006-10-30 15:50:24 +0000 |
---|---|---|
committer | kraxel <kraxel> | 2006-10-30 15:50:24 +0000 |
commit | b0b7aac6a182502230ecadf0e37f24b220c3b450 (patch) | |
tree | abaef77f9a1b210cc84c050233667102167ebe67 /vnc.c | |
parent | 16928d0f1b55cd0adb39450f1fbd122e6aac3f5e (diff) | |
download | xenwatch-b0b7aac6a182502230ecadf0e37f24b220c3b450.tar.gz |
misc vnc fixes
Diffstat (limited to 'vnc.c')
-rw-r--r-- | vnc.c | 108 |
1 files changed, 101 insertions, 7 deletions
@@ -7,6 +7,9 @@ #include <locale.h> #include <signal.h> +#include <X11/X.h> +#include <X11/Xlib.h> + #include <gdk/gdk.h> #include <gdk/gdkx.h> #include <gtk/gtk.h> @@ -31,6 +34,7 @@ struct vnc_window { GtkWidget *win; GtkWidget *draw; GdkCursor *on,*off; + int filter_installed; /* x11 */ XImage *ximage; void *shm; @@ -50,6 +54,12 @@ rfbKeySym linux_uskbd[][2] = { static int linux_uskbd_size = sizeof(linux_uskbd)/sizeof(linux_uskbd[0]); /* ------------------------------------------------------------------ */ +/* prototypes */ + +static GdkFilterReturn event_filter(GdkXEvent *gdkxevent, GdkEvent *gtkevent, + gpointer data); + +/* ------------------------------------------------------------------ */ /* helper functions */ static GdkCursor* empty_cursor(void) @@ -111,6 +121,8 @@ static void vnc_release(struct vnc_window *vnc) if (vnc->client) rfbClientCleanup(vnc->client); #endif + if (vnc->filter_installed) + gdk_window_remove_filter(vnc->draw->window, event_filter, vnc); if (vnc->id) g_source_destroy(g_main_context_find_source_by_id (g_main_context_default(), vnc->id)); @@ -133,6 +145,12 @@ static rfbBool vnc_resize(rfbClient* client) __FUNCTION__, client->width, client->height); if (vnc->ximage) { + if (vnc->ximage->width == client->width && + vnc->ximage->height == client->height) { + if (vnc->debug) + fprintf(stderr, "%s: no size change, early exit\n", __FUNCTION__); + return TRUE; + } x11_destroy_ximage(vnc->dpy, vnc->ximage, vnc->shm); vnc->ximage = NULL; } @@ -288,12 +306,20 @@ static gboolean expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer dat if (NULL == vnc->ximage) return FALSE; +#if 0 vnc_blit(vnc, "expose", event->area.x, event->area.y, event->area.width, event->area.height); +#else + SendFramebufferUpdateRequest(vnc->client, + event->area.x, event->area.y, + event->area.width, event->area.height, + FALSE); +#endif return TRUE; } -static void send_mouse(struct vnc_window *vnc, int x, int y, int x11state) +static void send_mouse(struct vnc_window *vnc, int x, int y, + int x11state, int x11press, int x11release) { int rfbstate = 0; @@ -304,12 +330,27 @@ static void send_mouse(struct vnc_window *vnc, int x, int y, int x11state) if (x11state & Button3Mask) rfbstate |= rfbButton3Mask; + if (x11press == Button1) + rfbstate |= rfbButton1Mask; + if (x11press == Button2) + rfbstate |= rfbButton2Mask; + if (x11press == Button3) + rfbstate |= rfbButton3Mask; + + if (x11release == Button1) + rfbstate &= ~rfbButton1Mask; + if (x11release == Button2) + rfbstate &= ~rfbButton2Mask; + if (x11release == Button3) + rfbstate &= ~rfbButton3Mask; + if (vnc->debug) fprintf(stderr,"%s: +%d+%d x11state 0x%x rfbstate 0x%x\n", __FUNCTION__, x, y, x11state, rfbstate); SendPointerEvent(vnc->client, x, y, rfbstate); } +#if 0 static gboolean button_cb(GtkWidget *widget, GdkEventButton *event, gpointer data) { @@ -325,6 +366,7 @@ static gboolean motion_cb(GtkWidget *widget, GdkEventMotion *event, send_mouse(vnc, event->x, event->y, event->state); return TRUE; } +#endif static gboolean key_cb_local(GtkWidget *widget, GdkEventKey *event, gpointer data) @@ -362,11 +404,49 @@ static gboolean key_cb_uskbd(GtkWidget *widget, GdkEventKey *event, return TRUE; } +static GdkFilterReturn event_filter(GdkXEvent *gdkxevent, GdkEvent *gtkevent, + gpointer data) +{ + struct vnc_window *vnc = data; + XEvent *xevent = gdkxevent; + + switch (xevent->type) { + case ButtonPress: + send_mouse(vnc, xevent->xbutton.x, xevent->xbutton.y, + xevent->xbutton.state, xevent->xbutton.button, 0); + return GDK_FILTER_REMOVE; + case ButtonRelease: + send_mouse(vnc, xevent->xbutton.x, xevent->xbutton.y, + xevent->xbutton.state, 0, xevent->xbutton.button); + return GDK_FILTER_REMOVE; + case MotionNotify: + send_mouse(vnc, xevent->xmotion.x, xevent->xmotion.y, + xevent->xmotion.state, 0, 0); + return GDK_FILTER_REMOVE; + + case KeymapNotify: + fprintf(stderr, "%s: KeymapNotify\n", __FUNCTION__); + return GDK_FILTER_REMOVE; + + case Expose: // 12 + case MapNotify: // 19 + case ConfigureNotify: // 22 + case PropertyNotify: // 28 + case ClientMessage: // 33 + case 94: + /* do not log it */ + return GDK_FILTER_CONTINUE; + default: + fprintf(stderr, "%s: unhandled: type %d\n", __FUNCTION__, xevent->type); + return GDK_FILTER_CONTINUE; + } +} + /* ------------------------------------------------------------------ */ /* public API functions */ -GtkWidget *vnc_open(char *hostname, int displayno, - int standalone, int uskbd, int debug) +GtkWidget *vnc_open(char *hostname, int displayno, unsigned long flags, + int debug_level) { char display[128]; char *argv[] = { "vnc-client", display, NULL }; @@ -378,9 +458,9 @@ GtkWidget *vnc_open(char *hostname, int displayno, if (NULL == vnc) goto err; memset(vnc,0,sizeof(*vnc)); - vnc->standalone = standalone; - vnc->debug = debug; - debug_libvnc = debug; + vnc->standalone = (flags & VNC_FLAG_STANDALONE); + vnc->debug = debug_level; + debug_libvnc = debug_level; /* x11 */ vnc->dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); @@ -434,13 +514,15 @@ GtkWidget *vnc_open(char *hostname, int displayno, gtk_widget_set_double_buffered(vnc->draw, FALSE); g_signal_connect(G_OBJECT(vnc->draw), "expose-event", G_CALLBACK(expose_cb), vnc); +#if 0 g_signal_connect(G_OBJECT(vnc->draw), "button-press-event", G_CALLBACK(button_cb), vnc); g_signal_connect(G_OBJECT(vnc->draw), "button-release-event", G_CALLBACK(button_cb), vnc); g_signal_connect(G_OBJECT(vnc->draw), "motion-notify-event", G_CALLBACK(motion_cb), vnc); - if (uskbd) { +#endif + if (flags & VNC_FLAG_US_KBD) { g_signal_connect(G_OBJECT(vnc->draw), "key-press-event", G_CALLBACK(key_cb_uskbd), vnc); g_signal_connect(G_OBJECT(vnc->draw), "key-release-event", @@ -455,6 +537,18 @@ GtkWidget *vnc_open(char *hostname, int displayno, /* show window */ gtk_widget_show_all(vnc->win); vnc_window_conf(vnc); + + /* X11 lowlevel stuff (needs window handle) */ +#if 0 + XSelectInput(vnc->dpy, + gdk_x11_drawable_get_xid(vnc->draw->window), + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + KeymapStateMask); +#endif + gdk_window_add_filter(vnc->draw->window, event_filter, vnc); + vnc->filter_installed = 1; return vnc->win; err: |