aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-11-10 16:14:34 +0000
committerkraxel <kraxel>2006-11-10 16:14:34 +0000
commit627b78ed80f300d887d792d716f8769afc723213 (patch)
treeef6a50e2b67e75191cc42c71bbda605e12d85049
parent85d2f0b6b27d11038695bf083c382869b0ca19f9 (diff)
downloadxenwatch-627b78ed80f300d887d792d716f8769afc723213.tar.gz
input grabbing
-rw-r--r--vnc.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/vnc.c b/vnc.c
index 09972ef..2dee570 100644
--- a/vnc.c
+++ b/vnc.c
@@ -35,6 +35,7 @@ struct vnc_window {
GtkWidget *draw;
GdkCursor *on,*off;
int filter_installed;
+ int input_grabbed;
/* x11 */
XImage *ximage;
void *shm;
@@ -109,15 +110,24 @@ static void vnc_blit(struct vnc_window *vnc, char *reason,
XPUTIMAGE(vnc->dpy, win, vnc->gc, vnc->ximage, x,y, x,y, w,h);
}
-static void vnc_window_conf(struct vnc_window *vnc)
+static void vnc_window_title(struct vnc_window *vnc)
{
+ static const char *grabtext
+ = " [input grab active, press Ctrl-Alt to release]";
char title[256];
+ snprintf(title, sizeof(title), "VNC: %s (%dx%d)%s",
+ vnc->client->desktopName,
+ vnc->client->width, vnc->client->height,
+ vnc->input_grabbed ? grabtext : "");
+ gtk_window_set_title(GTK_WINDOW(vnc->win), title);
+}
+
+static void vnc_window_conf(struct vnc_window *vnc)
+{
if (!vnc->draw)
return;
- snprintf(title, sizeof(title), "VNC: %s (%dx%d)", vnc->client->desktopName,
- vnc->client->width, vnc->client->height);
- gtk_window_set_title(GTK_WINDOW(vnc->win), title);
+ vnc_window_title(vnc);
gtk_widget_set_size_request(vnc->draw, vnc->client->width, vnc->client->height);
if (vnc->draw->window) {
if (!vnc->showpointer)
@@ -147,6 +157,35 @@ static void vnc_release(struct vnc_window *vnc)
free(vnc);
}
+static void grab_input(struct vnc_window *vnc, guint32 time)
+{
+ if (vnc->input_grabbed)
+ return;
+ gdk_pointer_grab(vnc->draw->window,
+ FALSE,
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ vnc->draw->window,
+ NULL,
+ time);
+ gdk_keyboard_grab(vnc->draw->window,
+ FALSE,
+ time);
+ vnc->input_grabbed = 1;
+ vnc_window_title(vnc);
+}
+
+static void ungrab_input(struct vnc_window *vnc, guint32 time)
+{
+ if (!vnc->input_grabbed)
+ return;
+ gdk_pointer_ungrab(time);
+ gdk_keyboard_ungrab(time);
+ vnc->input_grabbed = 0;
+ vnc_window_title(vnc);
+}
+
/* ------------------------------------------------------------------ */
/* libvncclient callbacks */
@@ -372,6 +411,7 @@ static gboolean button_cb(GtkWidget *widget, GdkEventButton *event,
switch (event->type) {
case GDK_BUTTON_PRESS:
send_mouse(vnc, event->x, event->y, event->state, event->button, 0);
+ grab_input(vnc, event->time);
break;
case GDK_BUTTON_RELEASE:
send_mouse(vnc, event->x, event->y, event->state, 0, event->button);
@@ -396,7 +436,10 @@ static gboolean key_cb_local(GtkWidget *widget, GdkEventKey *event,
{
struct vnc_window *vnc = data;
int keydown;
+ int mask = GDK_CONTROL_MASK | GDK_MOD1_MASK;
+ if (mask == (event->state & mask))
+ ungrab_input(vnc, event->time);
if (vnc->debug)
fprintf(stderr,"%s[%d]: called: keysym %d\n", __FUNCTION__,
event->type, event->keyval);
@@ -411,6 +454,10 @@ static gboolean key_cb_uskbd(GtkWidget *widget, GdkEventKey *event,
struct vnc_window *vnc = data;
rfbKeySym keysym = 0;
int shift,keydown;
+ int mask = GDK_CONTROL_MASK | GDK_MOD1_MASK;
+
+ if (mask == (event->state & mask))
+ ungrab_input(vnc, event->time);
keydown = (8 == event->type);
if (event->hardware_keycode < 256) {