]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkask.c
Compile fix for GTK 3.18: avoid gtk_adjustment_changed().
[PuTTY.git] / unix / gtkask.c
index 1d6e8768e391b485a58357cd5fc076a8cd3b0938..e5439bbb172c8b5e743f9f78218e8c5a0f44ecb3 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "gtkfont.h"
 #include "gtkcompat.h"
+#include "gtkmisc.h"
 
 #include "misc.h"
 
@@ -42,6 +43,9 @@ struct askpass_ctx {
 #endif
     char *passphrase;
     int passlen, passsize;
+#if GTK_CHECK_VERSION(3,0,0)
+    GdkDevice *keyboard;               /* for gdk_device_grab */
+#endif
 };
 
 static void visually_acknowledge_keypress(struct askpass_ctx *ctx)
@@ -185,6 +189,14 @@ static void askpass_redraw_gdk(GdkWindow *win, struct drawing_area_ctx *ctx)
 }
 #endif
 
+#if GTK_CHECK_VERSION(3,0,0)
+static gint draw_area(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+    struct drawing_area_ctx *ctx = (struct drawing_area_ctx *)data;
+    askpass_redraw_cairo(cr, ctx);
+    return TRUE;
+}
+#else
 static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
                         gpointer data)
 {
@@ -200,11 +212,49 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
 
     return TRUE;
 }
+#endif
 
 static int try_grab_keyboard(struct askpass_ctx *ctx)
 {
-    int ret = gdk_keyboard_grab(gtk_widget_get_window(ctx->dialog),
-                                FALSE, GDK_CURRENT_TIME);
+    int ret;
+
+#if GTK_CHECK_VERSION(3,0,0)
+    /*
+     * Grabbing the keyboard is quite complicated in GTK 3.
+     */
+    GdkDeviceManager *dm;
+    GdkDevice *pointer, *keyboard;
+
+    dm = gdk_display_get_device_manager
+        (gtk_widget_get_display(ctx->dialog));
+    if (!dm)
+        return FALSE;
+
+    pointer = gdk_device_manager_get_client_pointer(dm);
+    if (!pointer)
+        return FALSE;
+    keyboard = gdk_device_get_associated_device(pointer);
+    if (!keyboard)
+        return FALSE;
+    if (gdk_device_get_source(keyboard) != GDK_SOURCE_KEYBOARD)
+        return FALSE;
+
+    ctx->keyboard = keyboard;
+    ret = gdk_device_grab(ctx->keyboard,
+                          gtk_widget_get_window(ctx->dialog),
+                          GDK_OWNERSHIP_NONE,
+                          TRUE,
+                          GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
+                          NULL,
+                          GDK_CURRENT_TIME);
+#else
+    /*
+     * It's much simpler in GTK 1 and 2!
+     */
+    ret = gdk_keyboard_grab(gtk_widget_get_window(ctx->dialog),
+                            FALSE, GDK_CURRENT_TIME);
+#endif
+
     return ret == GDK_GRAB_SUCCESS;
 }
 
@@ -240,6 +290,7 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
                                      const char *prompt_text)
 {
     int i;
+    GtkBox *action_area;
 
     ctx->passlen = 0;
     ctx->passsize = 2048;
@@ -248,13 +299,18 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
     /*
      * Create widgets.
      */
-    ctx->dialog = gtk_dialog_new();
+    ctx->dialog = our_dialog_new();
     gtk_window_set_title(GTK_WINDOW(ctx->dialog), window_title);
+    gtk_window_set_position(GTK_WINDOW(ctx->dialog), GTK_WIN_POS_CENTER);
     ctx->promptlabel = gtk_label_new(prompt_text);
+    align_label_left(GTK_LABEL(ctx->promptlabel));
+    gtk_widget_show(ctx->promptlabel);
     gtk_label_set_line_wrap(GTK_LABEL(ctx->promptlabel), TRUE);
-    gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area
-                                    (GTK_DIALOG(ctx->dialog))),
-                      ctx->promptlabel);
+#if GTK_CHECK_VERSION(3,0,0)
+    gtk_label_set_width_chars(GTK_LABEL(ctx->promptlabel), 48);
+#endif
+    our_dialog_add_to_content_area(GTK_WINDOW(ctx->dialog),
+                                   ctx->promptlabel, TRUE, TRUE, 0);
 #if GTK_CHECK_VERSION(2,0,0)
     ctx->imc = gtk_im_multicontext_new();
 #endif
@@ -270,6 +326,9 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
             return "unable to allocate colours";
     }
 #endif
+
+    action_area = our_dialog_make_action_hbox(GTK_WINDOW(ctx->dialog));
+
     for (i = 0; i < N_DRAWING_AREAS; i++) {
         ctx->drawingareas[i].area = gtk_drawing_area_new();
 #ifndef DRAW_DEFAULT_CAIRO
@@ -281,17 +340,23 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
          * context-sensitive way, like measuring the size of some
          * piece of template text. */
         gtk_widget_set_size_request(ctx->drawingareas[i].area, 32, 32);
-        gtk_container_add(GTK_CONTAINER(gtk_dialog_get_action_area
-                                        (GTK_DIALOG(ctx->dialog))),
-                          ctx->drawingareas[i].area);
+        gtk_box_pack_end(action_area, ctx->drawingareas[i].area,
+                         TRUE, TRUE, 5);
         g_signal_connect(G_OBJECT(ctx->drawingareas[i].area),
                          "configure_event",
                          G_CALLBACK(configure_area),
                          &ctx->drawingareas[i]);
+#if GTK_CHECK_VERSION(3,0,0)
+        g_signal_connect(G_OBJECT(ctx->drawingareas[i].area),
+                         "draw",
+                         G_CALLBACK(draw_area),
+                         &ctx->drawingareas[i]);
+#else
         g_signal_connect(G_OBJECT(ctx->drawingareas[i].area),
                          "expose_event",
                          G_CALLBACK(expose_area),
                          &ctx->drawingareas[i]);
+#endif
         gtk_widget_show(ctx->drawingareas[i].area);
     }
     ctx->active_area = rand() % N_DRAWING_AREAS;
@@ -324,7 +389,7 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
 
     /*
      * And now that we've got the keyboard grab, connect up our
-     * keyboard handlers, and display the prompt.
+     * keyboard handlers.
      */
 #if GTK_CHECK_VERSION(2,0,0)
     g_signal_connect(G_OBJECT(ctx->imc), "commit",
@@ -338,14 +403,17 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx,
     gtk_im_context_set_client_window(ctx->imc,
                                      gtk_widget_get_window(ctx->dialog));
 #endif
-    gtk_widget_show(ctx->promptlabel);
 
     return NULL;
 }
 
 static void gtk_askpass_cleanup(struct askpass_ctx *ctx)
 {
+#if GTK_CHECK_VERSION(3,0,0)
+    gdk_device_ungrab(ctx->keyboard, GDK_CURRENT_TIME);
+#else
     gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+#endif
     gtk_grab_remove(ctx->promptlabel);
 
     if (ctx->passphrase) {
@@ -431,7 +499,7 @@ int main(int argc, char **argv)
         ret = dupprintf("usage: %s <prompt text>", argv[0]);
     } else {
         srand(time(NULL));
-        ret = gtk_askpass_main(argv[1], &success);
+        ret = gtk_askpass_main(NULL, "Enter passphrase", argv[1], &success);
     }
 
     if (!success) {