aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-10-30 15:50:24 +0000
committerkraxel <kraxel>2006-10-30 15:50:24 +0000
commitb0b7aac6a182502230ecadf0e37f24b220c3b450 (patch)
treeabaef77f9a1b210cc84c050233667102167ebe67
parent16928d0f1b55cd0adb39450f1fbd122e6aac3f5e (diff)
downloadxenwatch-b0b7aac6a182502230ecadf0e37f24b220c3b450.tar.gz
misc vnc fixes
-rw-r--r--vnc-client.c17
-rw-r--r--vnc.c108
-rw-r--r--vnc.h8
-rw-r--r--xd_view.c5
4 files changed, 118 insertions, 20 deletions
diff --git a/vnc-client.c b/vnc-client.c
index da2ca20..479428c 100644
--- a/vnc-client.c
+++ b/vnc-client.c
@@ -23,8 +23,9 @@ static void usage(FILE *fp)
"usage: vnc-client [options] hostname displayno\n"
"options:\n"
" -h Print this text.\n"
- " -u Send us kbd layout keysyms.\n"
" -d Enable debug output.\n"
+ " -u Send us kbd layout keysyms.\n"
+ " -p Show mouse pointer.\n"
"\n"
"-- \n"
"(c) 2006 Gerd Hoffmann <kraxel@suse.de>\n");
@@ -33,20 +34,23 @@ static void usage(FILE *fp)
int
main(int argc, char *argv[])
{
+ unsigned long vnc_flags = VNC_FLAG_STANDALONE;
int debug = 0;
- int uskbd = 0;
int c;
gtk_init(&argc, &argv);
for (;;) {
- if (-1 == (c = getopt(argc, argv, "hdu")))
+ if (-1 == (c = getopt(argc, argv, "hdup")))
break;
switch (c) {
case 'd':
- debug = 1;
+ debug++;
break;
case 'u':
- uskbd = 1;
+ vnc_flags |= VNC_FLAG_US_KBD;
+ break;
+ case 'p':
+ vnc_flags |= VNC_FLAG_SHOW_MOUSE;
break;
case 'h':
usage(stdout);
@@ -62,8 +66,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (NULL == vnc_open(argv[optind], atoi(argv[optind+1]),
- 1 /* standalone */, uskbd, debug))
+ if (NULL == vnc_open(argv[optind], atoi(argv[optind+1]), vnc_flags, debug))
exit(1);
gtk_main();
diff --git a/vnc.c b/vnc.c
index 5afdcfc..0d488f0 100644
--- a/vnc.c
+++ b/vnc.c
@@ -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:
diff --git a/vnc.h b/vnc.h
index 55cd9ef..ce2a673 100644
--- a/vnc.h
+++ b/vnc.h
@@ -1,2 +1,6 @@
-GtkWidget *vnc_open(char *hostname, int displayno,
- int standalone, int uskbd, int debug);
+#define VNC_FLAG_STANDALONE (1 << 1)
+#define VNC_FLAG_US_KBD (1 << 2)
+#define VNC_FLAG_SHOW_MOUSE (1 << 3)
+
+GtkWidget *vnc_open(char *hostname, int displayno, unsigned long flags,
+ int debug_level);
diff --git a/xd_view.c b/xd_view.c
index 129fef8..f89b0b4 100644
--- a/xd_view.c
+++ b/xd_view.c
@@ -136,10 +136,7 @@ static void open_vnc(gint id, char *hostname, gint displayno)
{
#ifdef HAVE_VNCCLIENT
if (1) {
- vnc_open(hostname, displayno,
- 0, /* standalone */
- 1, /* uskbd */
- 0); /* debug */
+ vnc_open(hostname, displayno, VNC_FLAG_US_KBD, 0);
return;
}
#endif