]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkwin.c
Avoid freeing the backend in notify_remote_exit(), since that's
[PuTTY.git] / unix / gtkwin.c
index 2972dba11a5fba3145cb3fd712f638445ff58198..6510e267ba8e2fe7f47f5f2f72962d8e2bf1e7ae 100644 (file)
@@ -75,6 +75,7 @@ struct gui_data {
     int mouseptr_visible;
     int busy_status;
     guint term_paste_idle_id;
+    guint term_exit_idle_id;
     int alt_keycode;
     int alt_digits;
     char wintitle[sizeof(((Config *)0)->wintitle)];
@@ -134,7 +135,7 @@ FontSpec platform_default_fontspec(const char *name)
 {
     FontSpec ret;
     if (!strcmp(name, "Font"))
-       strcpy(ret.name, "fixed");
+       strcpy(ret.name, "server:fixed");
     else
        *ret.name = '\0';
     return ret;
@@ -1087,45 +1088,46 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
     return TRUE;
 }
 
-gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
+gboolean button_internal(struct gui_data *inst, guint32 timestamp,
+                        GdkEventType type, guint ebutton, guint state,
+                        gdouble ex, gdouble ey)
 {
-    struct gui_data *inst = (struct gui_data *)data;
     int shift, ctrl, alt, x, y, button, act;
 
     /* Remember the timestamp. */
-    inst->input_event_time = event->time;
+    inst->input_event_time = timestamp;
 
     show_mouseptr(inst, 1);
 
-    if (event->button == 4 && event->type == GDK_BUTTON_PRESS) {
+    if (ebutton == 4 && type == GDK_BUTTON_PRESS) {
        term_scroll(inst->term, 0, -5);
        return TRUE;
     }
-    if (event->button == 5 && event->type == GDK_BUTTON_PRESS) {
+    if (ebutton == 5 && type == GDK_BUTTON_PRESS) {
        term_scroll(inst->term, 0, +5);
        return TRUE;
     }
 
-    shift = event->state & GDK_SHIFT_MASK;
-    ctrl = event->state & GDK_CONTROL_MASK;
-    alt = event->state & GDK_MOD1_MASK;
+    shift = state & GDK_SHIFT_MASK;
+    ctrl = state & GDK_CONTROL_MASK;
+    alt = state & GDK_MOD1_MASK;
 
-    if (event->button == 3 && ctrl) {
+    if (ebutton == 3 && ctrl) {
        gtk_menu_popup(GTK_MENU(inst->menu), NULL, NULL, NULL, NULL,
-                      event->button, event->time);
+                      ebutton, timestamp);
        return TRUE;
     }
 
-    if (event->button == 1)
+    if (ebutton == 1)
        button = MBT_LEFT;
-    else if (event->button == 2)
+    else if (ebutton == 2)
        button = MBT_MIDDLE;
-    else if (event->button == 3)
+    else if (ebutton == 3)
        button = MBT_RIGHT;
     else
        return FALSE;                  /* don't even know what button! */
 
-    switch (event->type) {
+    switch (type) {
       case GDK_BUTTON_PRESS: act = MA_CLICK; break;
       case GDK_BUTTON_RELEASE: act = MA_RELEASE; break;
       case GDK_2BUTTON_PRESS: act = MA_2CLK; break;
@@ -1137,8 +1139,8 @@ gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
        act != MA_CLICK && act != MA_RELEASE)
        return TRUE;                   /* we ignore these in raw mouse mode */
 
-    x = (event->x - inst->cfg.window_border) / inst->font_width;
-    y = (event->y - inst->cfg.window_border) / inst->font_height;
+    x = (ex - inst->cfg.window_border) / inst->font_width;
+    y = (ey - inst->cfg.window_border) / inst->font_height;
 
     term_mouse(inst->term, button, translate_button(button), act,
               x, y, shift, ctrl, alt);
@@ -1146,6 +1148,36 @@ gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
     return TRUE;
 }
 
+gboolean button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+    struct gui_data *inst = (struct gui_data *)data;
+    return button_internal(inst, event->time, event->type, event->button,
+                          event->state, event->x, event->y);
+}
+
+#if GTK_CHECK_VERSION(2,0,0)
+/*
+ * In GTK 2, mouse wheel events have become a new type of event.
+ * This handler translates them back into button-4 and button-5
+ * presses so that I don't have to change my old code too much :-)
+ */
+gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
+{
+    struct gui_data *inst = (struct gui_data *)data;
+    guint button;
+
+    if (event->direction == GDK_SCROLL_UP)
+       button = 4;
+    else if (event->direction == GDK_SCROLL_DOWN)
+       button = 5;
+    else
+       return FALSE;
+
+    return button_internal(inst, event->time, GDK_BUTTON_PRESS,
+                          button, event->state, event->x, event->y);
+}
+#endif
+
 gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
 {
     struct gui_data *inst = (struct gui_data *)data;
@@ -1189,9 +1221,9 @@ void frontend_keypress(void *handle)
        exit(0);
 }
 
-void notify_remote_exit(void *frontend)
+static gint idle_exit_func(gpointer data)
 {
-    struct gui_data *inst = (struct gui_data *)frontend;
+    struct gui_data *inst = (struct gui_data *)data;
     int exitcode;
 
     if (!inst->exited &&
@@ -1213,6 +1245,16 @@ void notify_remote_exit(void *frontend)
        }
        gtk_widget_show(inst->restartitem);
     }
+
+    gtk_idle_remove(inst->term_exit_idle_id);
+    return TRUE;
+}
+
+void notify_remote_exit(void *frontend)
+{
+    struct gui_data *inst = (struct gui_data *)frontend;
+
+    inst->term_exit_idle_id = gtk_idle_add(idle_exit_func, inst);
 }
 
 static gint timer_trigger(gpointer data)
@@ -1350,12 +1392,28 @@ void request_resize(void *frontend, int w, int h)
      */
 #if GTK_CHECK_VERSION(2,0,0)
     gtk_widget_set_size_request(inst->area, area_x, area_y);
-    _gtk_container_dequeue_resize_handler(GTK_CONTAINER(inst->window));
     gtk_window_resize(GTK_WINDOW(inst->window),
                      area_x + offset_x, area_y + offset_y);
 #else
     gtk_widget_set_usize(inst->area, area_x, area_y);
     gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), area_x, area_y);
+    /*
+     * I can no longer remember what this call to
+     * gtk_container_dequeue_resize_handler is for. It was
+     * introduced in r3092 with no comment, and the commit log
+     * message was uninformative. I'm _guessing_ its purpose is to
+     * prevent gratuitous resize processing on the window given
+     * that we're about to resize it anyway, but I have no idea
+     * why that's so incredibly vital.
+     * 
+     * I've tried removing the call, and nothing seems to go
+     * wrong. I've backtracked to r3092 and tried removing the
+     * call there, and still nothing goes wrong. So I'm going to
+     * adopt the working hypothesis that it's superfluous; I won't
+     * actually remove it from the GTK 1.2 code, but I won't
+     * attempt to replicate its functionality in the GTK 2 code
+     * above.
+     */
     gtk_container_dequeue_resize_handler(GTK_CONTAINER(inst->window));
     gdk_window_resize(inst->window->window,
                      area_x + offset_x, area_y + offset_y);
@@ -1455,7 +1513,7 @@ void palette_reset(void *frontend)
     /* Since Default Background may have changed, ensure that space
      * between text area and window border is refreshed. */
     set_window_background(inst);
-    if (inst->area) {
+    if (inst->area && inst->area->window) {
        draw_backing_rect(inst);
        gtk_widget_queue_draw(inst->area);
     }
@@ -2026,7 +2084,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
            unifont_draw_text(inst->pixmap, gc, inst->fonts[fontid],
                              x*inst->font_width+inst->cfg.window_border,
                              y*inst->font_height+inst->cfg.window_border+inst->fonts[0]->ascent,
-                             gcs, mblen, widefactor > 1, bold);
+                             gcs, mblen, widefactor > 1, bold, inst->font_width);
        }
 
        sfree(gcs);
@@ -2618,7 +2676,8 @@ void setup_fonts_ucs(struct gui_data *inst)
     if (inst->fonts[3])
         unifont_destroy(inst->fonts[3]);
 
-    inst->fonts[0] = unifont_create(inst->cfg.font.name, FALSE, FALSE,
+    inst->fonts[0] = unifont_create(inst->area, inst->cfg.font.name,
+                                   FALSE, FALSE,
                                    inst->cfg.shadowboldoffset,
                                    inst->cfg.shadowbold);
     if (!inst->fonts[0]) {
@@ -2630,7 +2689,8 @@ void setup_fonts_ucs(struct gui_data *inst)
     if (inst->cfg.shadowbold || !inst->cfg.boldfont.name[0]) {
        inst->fonts[1] = NULL;
     } else {
-       inst->fonts[1] = unifont_create(inst->cfg.boldfont.name, FALSE, TRUE,
+       inst->fonts[1] = unifont_create(inst->area, inst->cfg.boldfont.name,
+                                       FALSE, TRUE,
                                        inst->cfg.shadowboldoffset,
                                        inst->cfg.shadowbold);
        if (!inst->fonts[1]) {
@@ -2641,7 +2701,8 @@ void setup_fonts_ucs(struct gui_data *inst)
     }
 
     if (inst->cfg.widefont.name[0]) {
-       inst->fonts[2] = unifont_create(inst->cfg.widefont.name, TRUE, FALSE,
+       inst->fonts[2] = unifont_create(inst->area, inst->cfg.widefont.name,
+                                       TRUE, FALSE,
                                        inst->cfg.shadowboldoffset,
                                        inst->cfg.shadowbold);
        if (!inst->fonts[2]) {
@@ -2656,7 +2717,8 @@ void setup_fonts_ucs(struct gui_data *inst)
     if (inst->cfg.shadowbold || !inst->cfg.wideboldfont.name[0]) {
        inst->fonts[3] = NULL;
     } else {
-       inst->fonts[3] = unifont_create(inst->cfg.wideboldfont.name, TRUE,
+       inst->fonts[3] = unifont_create(inst->area,
+                                       inst->cfg.wideboldfont.name, TRUE,
                                        TRUE, inst->cfg.shadowboldoffset,
                                        inst->cfg.shadowbold);
        if (!inst->fonts[3]) {
@@ -3320,6 +3382,8 @@ int pt_main(int argc, char **argv)
     if (!utf8_string_atom)
         utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE);
 
+    inst->area = gtk_drawing_area_new();
+
     setup_fonts_ucs(inst);
     init_cutbuffers();
 
@@ -3333,7 +3397,6 @@ int pt_main(int argc, char **argv)
     inst->width = inst->cfg.width;
     inst->height = inst->cfg.height;
 
-    inst->area = gtk_drawing_area_new();
     gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area),
                          inst->font_width * inst->cfg.width + 2*inst->cfg.window_border,
                          inst->font_height * inst->cfg.height + 2*inst->cfg.window_border);
@@ -3392,6 +3455,10 @@ int pt_main(int argc, char **argv)
                       GTK_SIGNAL_FUNC(button_event), inst);
     gtk_signal_connect(GTK_OBJECT(inst->area), "button_release_event",
                       GTK_SIGNAL_FUNC(button_event), inst);
+#if GTK_CHECK_VERSION(2,0,0)
+    gtk_signal_connect(GTK_OBJECT(inst->area), "scroll_event",
+                      GTK_SIGNAL_FUNC(scroll_event), inst);
+#endif
     gtk_signal_connect(GTK_OBJECT(inst->area), "motion_notify_event",
                       GTK_SIGNAL_FUNC(motion_event), inst);
     gtk_signal_connect(GTK_OBJECT(inst->area), "selection_received",