diff options
Diffstat (limited to 'vnc.c')
-rw-r--r-- | vnc.c | 55 |
1 files changed, 51 insertions, 4 deletions
@@ -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) { |