]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkwin.c
Giant const-correctness patch of doom!
[PuTTY.git] / unix / gtkwin.c
index 59a5c383a8f8c4d0f272cfd0d2b4694b02cf95a1..e8345881cd803d391da8aa1ccf6fdca7433bd99f 100644 (file)
@@ -94,6 +94,7 @@ struct gui_data {
     int mouseptr_visible;
     int busy_status;
     guint toplevel_callback_idle_id;
+    int idle_fn_scheduled, quit_fn_scheduled;
     int alt_keycode;
     int alt_digits;
     char *wintitle;
@@ -132,7 +133,7 @@ struct draw_ctx {
 
 static int send_raw_mouse;
 
-static char *app_name = "pterm";
+static const char *app_name = "pterm";
 
 static void start_backend(struct gui_data *inst);
 static void exit_callback(void *vinst);
@@ -142,7 +143,7 @@ char *x_get_default(const char *key)
     return XGetDefault(GDK_DISPLAY(), app_name, key);
 }
 
-void connection_fatal(void *frontend, char *p, ...)
+void connection_fatal(void *frontend, const char *p, ...)
 {
     struct gui_data *inst = (struct gui_data *)frontend;
 
@@ -193,7 +194,7 @@ int platform_default_i(const char *name, int def)
 }
 
 /* Dummy routine, only required in plink. */
-void ldisc_update(void *frontend, int echo, int edit)
+void frontend_echoedit_update(void *frontend, int echo, int edit)
 {
 }
 
@@ -220,7 +221,7 @@ int from_backend_eof(void *frontend)
     return TRUE;   /* do respond to incoming EOF with outgoing */
 }
 
-int get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
+int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen)
 {
     struct gui_data *inst = (struct gui_data *)p->frontend;
     int ret;
@@ -884,7 +885,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
         * NetHack keypad mode.
         */
        if (nethack_mode) {
-           char *keys = NULL;
+           const char *keys = NULL;
            switch (event->keyval) {
              case GDK_KP_1: case GDK_KP_End: keys = "bB\002"; break;
              case GDK_KP_2: case GDK_KP_Down: keys = "jJ\012"; break;
@@ -1233,26 +1234,32 @@ gboolean button_internal(struct gui_data *inst, guint32 timestamp,
                         GdkEventType type, guint ebutton, guint state,
                         gdouble ex, gdouble ey)
 {
-    int shift, ctrl, alt, x, y, button, act;
+    int shift, ctrl, alt, x, y, button, act, raw_mouse_mode;
 
     /* Remember the timestamp. */
     inst->input_event_time = timestamp;
 
     show_mouseptr(inst, 1);
 
-    if (ebutton == 4 && type == GDK_BUTTON_PRESS) {
-       term_scroll(inst->term, 0, -5);
-       return TRUE;
-    }
-    if (ebutton == 5 && type == GDK_BUTTON_PRESS) {
-       term_scroll(inst->term, 0, +5);
-       return TRUE;
-    }
-
     shift = state & GDK_SHIFT_MASK;
     ctrl = state & GDK_CONTROL_MASK;
     alt = state & GDK_MOD1_MASK;
 
+    raw_mouse_mode =
+        send_raw_mouse && !(shift && conf_get_int(inst->conf,
+                                                  CONF_mouse_override));
+
+    if (!raw_mouse_mode) {
+        if (ebutton == 4 && type == GDK_BUTTON_PRESS) {
+            term_scroll(inst->term, 0, -5);
+            return TRUE;
+        }
+        if (ebutton == 5 && type == GDK_BUTTON_PRESS) {
+            term_scroll(inst->term, 0, +5);
+            return TRUE;
+        }
+    }
+
     if (ebutton == 3 && ctrl) {
        gtk_menu_popup(GTK_MENU(inst->menu), NULL, NULL, NULL, NULL,
                       ebutton, timestamp);
@@ -1265,6 +1272,10 @@ gboolean button_internal(struct gui_data *inst, guint32 timestamp,
        button = MBT_MIDDLE;
     else if (ebutton == 3)
        button = MBT_RIGHT;
+    else if (ebutton == 4)
+       button = MBT_WHEEL_UP;
+    else if (ebutton == 5)
+       button = MBT_WHEEL_DOWN;
     else
        return FALSE;                  /* don't even know what button! */
 
@@ -1276,9 +1287,7 @@ gboolean button_internal(struct gui_data *inst, guint32 timestamp,
       default: return FALSE;          /* don't know this event type */
     }
 
-    if (send_raw_mouse && !(shift && conf_get_int(inst->conf,
-                                                 CONF_mouse_override)) &&
-       act != MA_CLICK && act != MA_RELEASE)
+    if (raw_mouse_mode && act != MA_CLICK && act != MA_RELEASE)
        return TRUE;                   /* we ignore these in raw mouse mode */
 
     x = (ex - inst->window_border) / inst->font_width;
@@ -1395,23 +1404,70 @@ void notify_remote_exit(void *frontend)
     queue_toplevel_callback(exit_callback, inst);
 }
 
+static void notify_toplevel_callback(void *frontend);
+
+static gint quit_toplevel_callback_func(gpointer data)
+{
+    struct gui_data *inst = (struct gui_data *)data;
+
+    notify_toplevel_callback(inst);
+
+    inst->quit_fn_scheduled = FALSE;
+
+    return 0;
+}
+
 static gint idle_toplevel_callback_func(gpointer data)
 {
     struct gui_data *inst = (struct gui_data *)data;
 
-    run_toplevel_callbacks();
+    if (gtk_main_level() > 1) {
+        /*
+         * We don't run the callbacks if we're in the middle of a
+         * subsidiary gtk_main. Instead, ask for a callback when we
+         * get back out of the subsidiary main loop (if we haven't
+         * already arranged one), so we can reschedule ourself then.
+         */
+        if (!inst->quit_fn_scheduled) {
+            gtk_quit_add(2, quit_toplevel_callback_func, inst);
+            inst->quit_fn_scheduled = TRUE;
+        }
+        /*
+         * And unschedule this idle function, since we've now done
+         * everything we can until the innermost gtk_main has quit and
+         * can reschedule us with a chance of actually taking action.
+         */
+        if (inst->idle_fn_scheduled) { /* double-check, just in case */
+            gtk_idle_remove(inst->toplevel_callback_idle_id);
+            inst->idle_fn_scheduled = FALSE;
+        }
+    } else {
+        run_toplevel_callbacks();
+    }
 
-    gtk_idle_remove(inst->toplevel_callback_idle_id);
+    /*
+     * If we've emptied our toplevel callback queue, unschedule
+     * ourself. Otherwise, leave ourselves pending so we'll be called
+     * again to deal with more callbacks after another round of the
+     * event loop.
+     */
+    if (!toplevel_callback_pending() && inst->idle_fn_scheduled) {
+        gtk_idle_remove(inst->toplevel_callback_idle_id);
+        inst->idle_fn_scheduled = FALSE;
+    }
 
     return TRUE;
 }
 
-void notify_toplevel_callback(void *frontend)
+static void notify_toplevel_callback(void *frontend)
 {
     struct gui_data *inst = (struct gui_data *)frontend;
 
-    inst->toplevel_callback_idle_id =
-        gtk_idle_add(idle_toplevel_callback_func, inst);
+    if (!inst->idle_fn_scheduled) {
+        inst->toplevel_callback_idle_id =
+            gtk_idle_add(idle_toplevel_callback_func, inst);
+        inst->idle_fn_scheduled = TRUE;
+    }
 }
 
 static gint timer_trigger(gpointer data)
@@ -1420,7 +1476,21 @@ static gint timer_trigger(gpointer data)
     unsigned long next, then;
     long ticks;
 
-    if (run_timers(now, &next)) {
+    /*
+     * Destroy the timer we got here on.
+     */
+    if (timer_id) {
+       gtk_timeout_remove(timer_id);
+        timer_id = 0;
+    }
+
+    /*
+     * run_timers() may cause a call to timer_change_notify, in which
+     * case a new timer will already have been set up and left in
+     * timer_id. If it hasn't, and run_timers reports that some timing
+     * still needs to be done, we do it ourselves.
+     */
+    if (run_timers(now, &next) && !timer_id) {
        then = now;
        now = GETTICKCOUNT();
        if (now - then > next - then)
@@ -1432,8 +1502,9 @@ static gint timer_trigger(gpointer data)
     }
 
     /*
-     * Never let a timer resume. If we need another one, we've
-     * asked for it explicitly above.
+     * Returning FALSE means 'don't call this timer again', which
+     * _should_ be redundant given that we removed it above, but just
+     * in case, return FALSE anyway.
      */
     return FALSE;
 }
@@ -2532,7 +2603,7 @@ GdkCursor *make_mouse_ptr(struct gui_data *inst, int cursor_val)
     return ret;
 }
 
-void modalfatalbox(char *p, ...)
+void modalfatalbox(const char *p, ...)
 {
     va_list ap;
     fprintf(stderr, "FATAL ERROR: ");
@@ -2543,7 +2614,7 @@ void modalfatalbox(char *p, ...)
     exit(1);
 }
 
-void cmdline_error(char *p, ...)
+void cmdline_error(const char *p, ...)
 {
     va_list ap;
     fprintf(stderr, "%s: ", appname);
@@ -2624,7 +2695,7 @@ int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch,
 #define SECOND_PASS_ONLY { if (!do_everything) continue; }
 
     while (--argc > 0) {
-       char *p = *++argv;
+       const char *p = *++argv;
         int ret;
 
        /*
@@ -2879,7 +2950,7 @@ char *setup_fonts_ucs(struct gui_data *inst)
             for (i = 0; i < 2; i++)
                 if (fonts[i])
                     unifont_destroy(fonts[i]);
-            return dupprintf("%s: unable to load wide font \"%s\"", fs->name);
+            return dupprintf("unable to load wide font \"%s\"", fs->name);
        }
     } else {
        fonts[2] = NULL;
@@ -2895,8 +2966,7 @@ char *setup_fonts_ucs(struct gui_data *inst)
             for (i = 0; i < 3; i++)
                 if (fonts[i])
                     unifont_destroy(fonts[i]);
-           return dupprintf("%s: unable to load wide bold font \"%s\"",
-                             fs->name);
+           return dupprintf("unable to load wide bold font \"%s\"", fs->name);
        }
     }
 
@@ -2950,7 +3020,7 @@ void reset_terminal_menuitem(GtkMenuItem *item, gpointer data)
     struct gui_data *inst = (struct gui_data *)data;
     term_pwron(inst->term, TRUE);
     if (inst->ldisc)
-       ldisc_send(inst->ldisc, NULL, 0, 0);
+       ldisc_echoedit_update(inst->ldisc);
 }
 
 void copy_all_menuitem(GtkMenuItem *item, gpointer data)
@@ -3018,7 +3088,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
          */
         if (inst->ldisc) {
             ldisc_configure(inst->ldisc, inst->conf);
-           ldisc_send(inst->ldisc, NULL, 0, 0);
+            ldisc_echoedit_update(inst->ldisc);
         }
         /* Pass new config data to the terminal */
         term_reconfig(inst->term, inst->conf);
@@ -3583,6 +3653,8 @@ int pt_main(int argc, char **argv)
     inst->busy_status = BUSY_NOT;
     inst->conf = conf_new();
     inst->wintitle = inst->icontitle = NULL;
+    inst->quit_fn_scheduled = FALSE;
+    inst->idle_fn_scheduled = FALSE;
 
     /* defer any child exit handling until we're ready to deal with
      * it */
@@ -3852,7 +3924,7 @@ int pt_main(int argc, char **argv)
 
     start_backend(inst);
 
-    ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
+    ldisc_echoedit_update(inst->ldisc);     /* cause ldisc to notice changes */
 
     /* now we're reday to deal with the child exit handler being
      * called */