diff options
Diffstat (limited to 'vnc.c')
-rw-r--r-- | vnc.c | 123 |
1 files changed, 78 insertions, 45 deletions
@@ -27,12 +27,14 @@ static int debug_libvnc; struct vnc_window { /* vnc connection */ + char display[128]; rfbClient *client; GIOChannel *ch; guint id; /* gtk */ GtkWidget *win; GtkWidget *draw; + GtkWidget *line, *kbd, *res; GdkCursor *on,*off; int filter_installed; int input_grabbed; @@ -45,6 +47,7 @@ struct vnc_window { /* config */ int standalone; int showpointer; + int uskbd; int debug; }; @@ -110,24 +113,35 @@ 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_title(struct vnc_window *vnc) +static void vnc_window_texts(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); + char textline[256]; + + if (vnc->client->desktopName && strlen(vnc->client->desktopName)) + gtk_window_set_title(GTK_WINDOW(vnc->win), vnc->client->desktopName); + else + gtk_window_set_title(GTK_WINDOW(vnc->win), "untitled vnc session"); + + if (vnc->input_grabbed) { + gtk_label_set_text(GTK_LABEL(vnc->line), + "Press Ctrl-Alt to release input grab."); + } else { + snprintf(textline, sizeof(textline), "connected to %s", + vnc->display); + gtk_label_set_text(GTK_LABEL(vnc->line), textline); + } + + snprintf(textline, sizeof(textline), "%dx%d", + vnc->client->width, vnc->client->height); + gtk_label_set_text(GTK_LABEL(vnc->res), textline); + gtk_label_set_text(GTK_LABEL(vnc->kbd), vnc->uskbd ? "kbd: us" : "kbd: local"); } static void vnc_window_conf(struct vnc_window *vnc) { if (!vnc->draw) return; - vnc_window_title(vnc); + vnc_window_texts(vnc); gtk_widget_set_size_request(vnc->draw, vnc->client->width, vnc->client->height); if (vnc->draw->window) { if (!vnc->showpointer) @@ -173,7 +187,7 @@ static void grab_input(struct vnc_window *vnc, guint32 time) FALSE, time); vnc->input_grabbed = 1; - vnc_window_title(vnc); + vnc_window_texts(vnc); } static void ungrab_input(struct vnc_window *vnc, guint32 time) @@ -183,7 +197,7 @@ static void ungrab_input(struct vnc_window *vnc, guint32 time) gdk_pointer_ungrab(time); gdk_keyboard_ungrab(time); vnc->input_grabbed = 0; - vnc_window_title(vnc); + vnc_window_texts(vnc); } /* ------------------------------------------------------------------ */ @@ -431,33 +445,21 @@ static gboolean motion_cb(GtkWidget *widget, GdkEventMotion *event, return TRUE; } -static gboolean key_cb_local(GtkWidget *widget, GdkEventKey *event, - gpointer data) +static void key_local(struct vnc_window *vnc, 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); keydown = (8 == event->type); SendKeyEvent(vnc->client, event->keyval, keydown ? TRUE : FALSE); - return TRUE; } -static gboolean key_cb_uskbd(GtkWidget *widget, GdkEventKey *event, - gpointer data) +static void key_uskbd(struct vnc_window *vnc, 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) { @@ -481,6 +483,21 @@ static gboolean key_cb_uskbd(GtkWidget *widget, GdkEventKey *event, event->type, event->hardware_keycode, keysym); if (keysym) SendKeyEvent(vnc->client, keysym, keydown ? TRUE : FALSE); +} + +static gboolean key_cb(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + struct vnc_window *vnc = data; + int mask = GDK_CONTROL_MASK | GDK_MOD1_MASK; + + if (mask == (event->state & mask)) + ungrab_input(vnc, event->time); + + if (vnc->uskbd) + key_uskbd(vnc, event); + else + key_local(vnc, event); return TRUE; } @@ -494,6 +511,8 @@ static GdkFilterReturn event_filter(GdkXEvent *gdkxevent, GdkEvent *gtkevent, switch (xevent->type) { case KeymapNotify: + if (!vnc->uskbd) + return GDK_FILTER_REMOVE; for (by = 0; by < 32; by++) { if (vnc->keydown[by] == xevent->xkeymap.key_vector[by]) continue; @@ -525,8 +544,8 @@ static GdkFilterReturn event_filter(GdkXEvent *gdkxevent, GdkEvent *gtkevent, GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, int debug_level) { - char display[128]; - char *argv[] = { "vnc-client", display, NULL }; + GtkWidget *vbox, *hbox; + char *argv[] = { "vnc-client", NULL, NULL }; int argc = sizeof(argv)/sizeof(argv[0]) -1; struct vnc_window *vnc; int rc; @@ -537,6 +556,7 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, memset(vnc,0,sizeof(*vnc)); vnc->standalone = (flags & VNC_FLAG_STANDALONE); vnc->showpointer = (flags & VNC_FLAG_SHOW_MOUSE); + vnc->uskbd = (flags & VNC_FLAG_US_KBD); vnc->debug = debug_level; debug_libvnc = debug_level; @@ -547,8 +567,10 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, goto err; /* rfb client */ - snprintf(display, sizeof(display), "%s:%d", hostname, tcpport - 5900); - fprintf(stderr, "%s: connecting to %s\n", __FUNCTION__, display); + snprintf(vnc->display, sizeof(vnc->display), + "%s:%d", hostname, tcpport - 5900); + argv[1] = vnc->display; + fprintf(stderr, "%s: connecting to %s\n", __FUNCTION__, vnc->display); if (8 == x11_red_bits) vnc->client = rfbGetClient(8,3,4); else @@ -579,7 +601,6 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, /* gtk drawing area */ vnc->draw = gtk_drawing_area_new(); - gtk_container_add(GTK_CONTAINER(vnc->win), vnc->draw); GTK_WIDGET_SET_FLAGS(vnc->draw, GTK_CAN_FOCUS); gtk_widget_add_events(vnc->draw, GDK_BUTTON_PRESS_MASK | @@ -598,19 +619,31 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, G_CALLBACK(button_cb), vnc); g_signal_connect(G_OBJECT(vnc->draw), "motion-notify-event", G_CALLBACK(motion_cb), vnc); - 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", - G_CALLBACK(key_cb_uskbd), vnc); - gdk_window_add_filter(NULL, event_filter, vnc); - vnc->filter_installed = 1; - } else { - g_signal_connect(G_OBJECT(vnc->draw), "key-press-event", - G_CALLBACK(key_cb_local), vnc); - g_signal_connect(G_OBJECT(vnc->draw), "key-release-event", - G_CALLBACK(key_cb_local), vnc); - } + g_signal_connect(G_OBJECT(vnc->draw), "key-press-event", + G_CALLBACK(key_cb), vnc); + g_signal_connect(G_OBJECT(vnc->draw), "key-release-event", + G_CALLBACK(key_cb), vnc); + gdk_window_add_filter(NULL, event_filter, vnc); + vnc->filter_installed = 1; + + /* labels for the status line */ + vnc->line = gtk_label_new("status line"); + vnc->kbd = gtk_label_new("keyboard mode"); + vnc->res = gtk_label_new("vnc screen resolution"); + gtk_misc_set_alignment(GTK_MISC(vnc->line), 0, 0.5); + gtk_misc_set_padding(GTK_MISC(vnc->line), 3, 3); + gtk_misc_set_padding(GTK_MISC(vnc->kbd), 3, 3); + gtk_misc_set_padding(GTK_MISC(vnc->res), 3, 3); + + /* packing */ + vbox = gtk_vbox_new(FALSE, 0); + hbox = gtk_hbox_new(FALSE, 1); + gtk_container_add(GTK_CONTAINER(vnc->win), vbox); + gtk_box_pack_start(GTK_BOX(vbox), vnc->draw, TRUE, TRUE, 0); + gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), vnc->line, TRUE, TRUE, 0); + gtk_box_pack_end(GTK_BOX(hbox), vnc->kbd, FALSE, TRUE, 0); + gtk_box_pack_end(GTK_BOX(hbox), vnc->res, FALSE, TRUE, 0); /* show window */ gtk_widget_show_all(vnc->win); |