OS X Leopard, it turns out, has a new and exciting strategy for
[sgt/putty] / unix / gtkwin.c
index cd8c715..d31037b 100644 (file)
@@ -155,6 +155,8 @@ Filename platform_default_filename(const char *name)
 
 char *platform_default_s(const char *name)
 {
+    if (!strcmp(name, "SerialLine"))
+       return dupstr("/dev/ttyS0");
     return NULL;
 }
 
@@ -661,13 +663,12 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
            end = 2;
        }
 
-       /* Control-Break is the same as Control-C */
+       /* Control-Break sends a Break special to the backend */
        if (event->keyval == GDK_Break &&
            (event->state & GDK_CONTROL_MASK)) {
-           output[1] = '\003';
-           use_ucsoutput = FALSE;
-           end = 2;
-           special = TRUE;
+           if (inst->back)
+               inst->back->special(inst->backhandle, TS_BRK);
+           return TRUE;
        }
 
        /* We handle Return ourselves, because it needs to be flagged as
@@ -722,6 +723,13 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
            end = 1 + sprintf(output+1, "\033[Z");
            use_ucsoutput = FALSE;
        }
+       /* And normal Tab is Tab, if the keymap hasn't already told us.
+        * (Curiously, at least one version of the MacOS 10.5 X server
+        * doesn't translate Tab for us. */
+       if (event->keyval == GDK_Tab && end <= 1) {
+           output[1] = '\t';
+           end = 2;
+       }
 
        /*
         * NetHack keypad mode.
@@ -1203,6 +1211,7 @@ void notify_remote_exit(void *frontend)
            inst->back->free(inst->backhandle);
            inst->backhandle = NULL;
            inst->back = NULL;
+            term_provide_resize_fn(inst->term, NULL, NULL);
            update_specials_menu(inst);
        }
        gtk_widget_show(inst->restartitem);
@@ -1432,7 +1441,7 @@ void palette_reset(void *frontend)
            int r = i / 36, g = (i / 6) % 6, b = i % 6;
            inst->cols[i+16].red = r ? r * 0x2828 + 0x3737 : 0;
            inst->cols[i+16].green = g ? g * 0x2828 + 0x3737 : 0;
-           inst->cols[i+16].blue = b ? b + 0x2828 + 0x3737 : 0;
+           inst->cols[i+16].blue = b ? b * 0x2828 + 0x3737 : 0;
        } else {
            int shade = i - 216;
            shade = shade * 0x0a0a + 0x0808;
@@ -1464,22 +1473,23 @@ void palette_reset(void *frontend)
  */
 void init_cutbuffers()
 {
+    unsigned char empty[] = "";
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER0, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER0, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER1, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER1, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER2, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER2, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER3, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER3, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER4, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER4, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER5, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER5, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER6, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER6, XA_STRING, 8, PropModeAppend, empty, 0);
     XChangeProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
-                   XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, "", 0);
+                   XA_CUT_BUFFER7, XA_STRING, 8, PropModeAppend, empty, 0);
 }
 
 /* Store the data in a cut-buffer. */
@@ -1599,15 +1609,16 @@ void selection_get(GtkWidget *widget, GtkSelectionData *seldata,
     struct gui_data *inst = (struct gui_data *)data;
     if (seldata->target == utf8_string_atom)
        gtk_selection_data_set(seldata, seldata->target, 8,
-                              inst->pasteout_data_utf8,
+                              (unsigned char *)inst->pasteout_data_utf8,
                               inst->pasteout_data_utf8_len);
     else if (seldata->target == compound_text_atom)
        gtk_selection_data_set(seldata, seldata->target, 8,
-                              inst->pasteout_data_ctext,
+                              (unsigned char *)inst->pasteout_data_ctext,
                               inst->pasteout_data_ctext_len);
     else
        gtk_selection_data_set(seldata, seldata->target, 8,
-                              inst->pasteout_data, inst->pasteout_data_len);
+                              (unsigned char *)inst->pasteout_data,
+                              inst->pasteout_data_len);
 }
 
 gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata,
@@ -1863,7 +1874,7 @@ void sys_cursor(void *frontend, int x, int y)
  */
 void do_beep(void *frontend, int mode)
 {
-    if (mode != BELL_VISUAL)
+    if (mode == BELL_DEFAULT)
        gdk_beep();
 }
 
@@ -1996,12 +2007,18 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
            wcs[i] = text[i];
        }
 
+       if (inst->fonts[fontid] == NULL && (fontid & 2)) {
+           /*
+            * We've been given ATTR_WIDE, but have no wide font.
+            * Fall back to the non-wide font.
+            */
+           fontid &= ~2;
+       }
+
        if (inst->fonts[fontid] == NULL) {
            /*
-            * The font for this contingency does not exist.
-            * Typically this means we've been given ATTR_WIDE
-            * character and have no wide font. So we display
-            * nothing at all; such is life.
+            * The font for this contingency does not exist. So we
+            * display nothing at all; such is life.
             */
        } else if (inst->fontinfo[fontid].is_wide) {
            /*
@@ -2398,7 +2415,7 @@ static void help(FILE *fp) {
     }
 }
 
-int do_cmdline(int argc, char **argv, int do_everything,
+int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch,
                struct gui_data *inst, Config *cfg)
 {
     int err = 0;
@@ -2480,15 +2497,16 @@ int do_cmdline(int argc, char **argv, int do_everything,
            cfg->line_codepage[sizeof(cfg->line_codepage)-1] = '\0';
 
        } else if (!strcmp(p, "-geometry")) {
-           int flags, x, y, w, h;
+           int flags, x, y;
+           unsigned int w, h;
            EXPECTS_ARG;
            SECOND_PASS_ONLY;
 
            flags = XParseGeometry(val, &x, &y, &w, &h);
            if (flags & WidthValue)
-               cfg->width = w;
+               cfg->width = (int)w;
            if (flags & HeightValue)
-               cfg->height = h;
+               cfg->height = (int)h;
 
             if (flags & (XValue | YValue)) {
                 inst->xpos = x;
@@ -2603,7 +2621,8 @@ int do_cmdline(int argc, char **argv, int do_everything,
             exit(1);
 
        } else if(p[0] != '-' && (!do_everything ||
-                                  process_nonoption_arg(p, cfg))) {
+                                  process_nonoption_arg(p, cfg,
+                                                       allow_launch))) {
             /* do nothing */
 
        } else {
@@ -3290,6 +3309,36 @@ static void update_savedsess_menu(GtkMenuItem *menuitem, gpointer data)
     get_sesslist(&sesslist, FALSE); /* free up */
 }
 
+void set_window_icon(GtkWidget *window, const char *const *const *icon,
+                    int n_icon)
+{
+    GdkPixmap *iconpm;
+    GdkBitmap *iconmask;
+#if GTK_CHECK_VERSION(2,0,0)
+    GList *iconlist;
+    int n;
+#endif
+
+    if (!n_icon)
+       return;
+
+    gtk_widget_realize(window);
+    iconpm = gdk_pixmap_create_from_xpm_d(window->window, &iconmask,
+                                         NULL, (gchar **)icon[0]);
+    gdk_window_set_icon(window->window, NULL, iconpm, iconmask);
+
+#if GTK_CHECK_VERSION(2,0,0)
+    iconlist = NULL;
+    for (n = 0; n < n_icon; n++) {
+       iconlist =
+           g_list_append(iconlist,
+                         gdk_pixbuf_new_from_xpm_data((const gchar **)
+                                                      icon[n]));
+    }
+    gdk_window_set_icon_list(window->window, iconlist);
+#endif
+}
+
 void update_specials_menu(void *frontend)
 {
     struct gui_data *inst = (struct gui_data *)frontend;
@@ -3386,6 +3435,8 @@ static void start_backend(struct gui_data *inst)
        set_icon(inst, title);
        sfree(title);
     }
+    sfree(realhost);
+
     inst->back->provide_logctx(inst->backhandle, inst->logctx);
 
     term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
@@ -3434,15 +3485,23 @@ int pt_main(int argc, char **argv)
        /* Splatter this argument so it doesn't clutter a ps listing */
        memset(argv[1], 0, strlen(argv[1]));
     } else {
-       if (do_cmdline(argc, argv, 0, inst, &inst->cfg))
+       /* By default, we bring up the config dialog, rather than launching
+        * a session. This gets set to TRUE if something happens to change
+        * that (e.g., a hostname is specified on the command-line). */
+       int allow_launch = FALSE;
+       if (do_cmdline(argc, argv, 0, &allow_launch, inst, &inst->cfg))
            exit(1);                   /* pre-defaults pass to get -class */
        do_defaults(NULL, &inst->cfg);
-       if (do_cmdline(argc, argv, 1, inst, &inst->cfg))
+       if (do_cmdline(argc, argv, 1, &allow_launch, inst, &inst->cfg))
            exit(1);                   /* post-defaults, do everything */
 
        cmdline_run_saved(&inst->cfg);
 
-       if (!*inst->cfg.host && !cfgbox(&inst->cfg))
+       if (loaded_session)
+           allow_launch = TRUE;
+
+       if ((!allow_launch || !cfg_launchable(&inst->cfg)) &&
+           !cfgbox(&inst->cfg))
            exit(0);                   /* config box hit Cancel */
     }
 
@@ -3539,6 +3598,12 @@ int pt_main(int argc, char **argv)
                          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                          GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK);
 
+    {
+       extern const char *const *const main_icon[];
+       extern const int n_main_icon;
+       set_window_icon(inst->window, main_icon, n_main_icon);
+    }
+
     gtk_widget_show(inst->window);
 
     set_window_background(inst);