Reorganise setup_fonts_ucs so that in case of error it does nothing
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 13 Jan 2013 21:59:10 +0000 (21:59 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 13 Jan 2013 21:59:10 +0000 (21:59 +0000)
and returns its error message as a string, instead of actually
printing it on standard error and exiting. Now we can preserve the
previous error behaviour when we get a nonexistent font name at
startup time, but no longer rudely terminate in mid-session if the
user configures a bogus font name in Change Settings.

git-svn-id: svn://svn.tartarus.org/sgt/putty@9745 cda61777-01e9-0310-a592-d414129be87e

unix/gtkdlg.c
unix/gtkwin.c
unix/unix.h

index eb93d33..50aa4fa 100644 (file)
@@ -3262,7 +3262,7 @@ int messagebox(GtkWidget *parentwin, char *title, char *msg, int minwid, ...)
     return dp.retval;
 }
 
-static int string_width(char *text)
+int string_width(char *text)
 {
     GtkWidget *label = gtk_label_new(text);
     GtkRequisition req;
index bd69fb6..da40e54 100644 (file)
@@ -31,6 +31,8 @@
 
 #define PUTTY_DO_GLOBALS              /* actually _define_ globals */
 
+#define MAY_REFER_TO_GTK_IN_HEADERS
+
 #include "putty.h"
 #include "terminal.h"
 #include "gtkfont.h"
@@ -2861,69 +2863,74 @@ void frontend_net_error_pending(void)
     }
 }
 
-void setup_fonts_ucs(struct gui_data *inst)
+char *setup_fonts_ucs(struct gui_data *inst)
 {
     int shadowbold = conf_get_int(inst->conf, CONF_shadowbold);
     int shadowboldoffset = conf_get_int(inst->conf, CONF_shadowboldoffset);
     FontSpec *fs;
-
-    if (inst->fonts[0])
-        unifont_destroy(inst->fonts[0]);
-    if (inst->fonts[1])
-        unifont_destroy(inst->fonts[1]);
-    if (inst->fonts[2])
-        unifont_destroy(inst->fonts[2]);
-    if (inst->fonts[3])
-        unifont_destroy(inst->fonts[3]);
+    unifont *fonts[4];
+    int i;
 
     fs = conf_get_fontspec(inst->conf, CONF_font);
-    inst->fonts[0] = multifont_create(inst->area, fs->name, FALSE, FALSE,
-                                      shadowboldoffset, shadowbold);
-    if (!inst->fonts[0]) {
-       fprintf(stderr, "%s: unable to load font \"%s\"\n", appname,
-               fs->name);
-       exit(1);
+    fonts[0] = multifont_create(inst->area, fs->name, FALSE, FALSE,
+                                shadowboldoffset, shadowbold);
+    if (!fonts[0]) {
+        return dupprintf("unable to load font \"%s\"", fs->name);
     }
 
     fs = conf_get_fontspec(inst->conf, CONF_boldfont);
     if (shadowbold || !fs->name[0]) {
-       inst->fonts[1] = NULL;
+       fonts[1] = NULL;
     } else {
-       inst->fonts[1] = multifont_create(inst->area, fs->name, FALSE, TRUE,
-                                          shadowboldoffset, shadowbold);
-       if (!inst->fonts[1]) {
-           fprintf(stderr, "%s: unable to load bold font \"%s\"\n", appname,
-                   fs->name);
-           exit(1);
+       fonts[1] = multifont_create(inst->area, fs->name, FALSE, TRUE,
+                                    shadowboldoffset, shadowbold);
+       if (!fonts[1]) {
+            if (fonts[0])
+                unifont_destroy(fonts[0]);
+           return dupprintf("unable to load bold font \"%s\"", fs->name);
        }
     }
 
     fs = conf_get_fontspec(inst->conf, CONF_widefont);
     if (fs->name[0]) {
-       inst->fonts[2] = multifont_create(inst->area, fs->name, TRUE, FALSE,
-                                          shadowboldoffset, shadowbold);
-       if (!inst->fonts[2]) {
-           fprintf(stderr, "%s: unable to load wide font \"%s\"\n", appname,
-                   fs->name);
-           exit(1);
+       fonts[2] = multifont_create(inst->area, fs->name, TRUE, FALSE,
+                                    shadowboldoffset, shadowbold);
+       if (!fonts[2]) {
+            for (i = 0; i < 2; i++)
+                if (fonts[i])
+                    unifont_destroy(fonts[i]);
+            return dupprintf("%s: unable to load wide font \"%s\"", fs->name);
        }
     } else {
-       inst->fonts[2] = NULL;
+       fonts[2] = NULL;
     }
 
     fs = conf_get_fontspec(inst->conf, CONF_wideboldfont);
     if (shadowbold || !fs->name[0]) {
-       inst->fonts[3] = NULL;
+       fonts[3] = NULL;
     } else {
-       inst->fonts[3] = multifont_create(inst->area, fs->name, TRUE, TRUE,
-                                          shadowboldoffset, shadowbold);
-       if (!inst->fonts[3]) {
-           fprintf(stderr, "%s: unable to load wide bold font \"%s\"\n", appname,
-                   fs->name);
-           exit(1);
+       fonts[3] = multifont_create(inst->area, fs->name, TRUE, TRUE,
+                                    shadowboldoffset, shadowbold);
+       if (!fonts[3]) {
+            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);
        }
     }
 
+    /*
+     * Now we've got past all the possible error conditions, we can
+     * actually update our state.
+     */
+
+    for (i = 0; i < 4; i++) {
+        if (inst->fonts[i])
+            unifont_destroy(inst->fonts[i]);
+        inst->fonts[i] = fonts[i];
+    }
+
     inst->font_width = inst->fonts[0]->width;
     inst->font_height = inst->fonts[0]->height;
 
@@ -2932,6 +2939,8 @@ void setup_fonts_ucs(struct gui_data *inst)
                                    conf_get_int(inst->conf, CONF_utf8_override),
                                    inst->fonts[0]->public_charset,
                                    conf_get_int(inst->conf, CONF_vtmode));
+
+    return NULL;
 }
 
 void set_geom_hints(struct gui_data *inst)
@@ -3097,6 +3106,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
          * Redo the whole tangled fonts and Unicode mess if
          * necessary.
          */
+        need_size = FALSE;
         if (strcmp(conf_get_fontspec(oldconf, CONF_font)->name,
                   conf_get_fontspec(newconf, CONF_font)->name) ||
            strcmp(conf_get_fontspec(oldconf, CONF_boldfont)->name,
@@ -3115,10 +3125,20 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
            conf_get_int(newconf, CONF_shadowbold) ||
            conf_get_int(oldconf, CONF_shadowboldoffset) !=
            conf_get_int(newconf, CONF_shadowboldoffset)) {
-            setup_fonts_ucs(inst);
-            need_size = 1;
-        } else
-            need_size = 0;
+            char *errmsg = setup_fonts_ucs(inst);
+            if (errmsg) {
+                char *msgboxtext =
+                    dupprintf("Could not change fonts in terminal window: %s\n",
+                              errmsg);
+                messagebox(inst->window, "Font setup error", msgboxtext,
+                           string_width("Could not change fonts in terminal window:"),
+                           "OK", 'o', +1, 1,
+                           NULL);
+                sfree(errmsg);
+            } else {
+                need_size = TRUE;
+            }
+        }
 
         /*
          * Resize the window.
@@ -3631,7 +3651,13 @@ int pt_main(int argc, char **argv)
     inst->imc = gtk_im_multicontext_new();
 #endif
 
-    setup_fonts_ucs(inst);
+    {
+        char *errmsg = setup_fonts_ucs(inst);
+        if (errmsg) {
+            fprintf(stderr, "%s: %s\n", appname, errmsg);
+            exit(1);
+        }
+    }
     init_cutbuffers();
 
     inst->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
index feef0fb..91d0642 100644 (file)
@@ -93,6 +93,10 @@ void *eventlogstuff_new(void);
 void showeventlog(void *estuff, void *parentwin);
 void logevent_dlg(void *estuff, const char *string);
 int reallyclose(void *frontend);
+#ifdef MAY_REFER_TO_GTK_IN_HEADERS
+int messagebox(GtkWidget *parentwin, char *title, char *msg, int minwid, ...);
+int string_width(char *text);
+#endif
 
 /* Things pterm.c needs from {ptermm,uxputty}.c */
 char *make_default_wintitle(char *hostname);