Add a "Config *" argument to term_init(), and use that instead of the global
[u/mdw/putty] / unix / pterm.c
index e53499d..8b28a23 100644 (file)
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
 
 #define PUTTY_DO_GLOBALS              /* actually _define_ globals */
 #include "putty.h"
@@ -68,6 +69,13 @@ struct draw_ctx {
 
 static int send_raw_mouse;
 
+static char *app_name = "pterm";
+
+char *x_get_default(char *key)
+{
+    return XGetDefault(GDK_DISPLAY(), app_name, key);
+}
+
 void ldisc_update(void *frontend, int echo, int edit)
 {
     /*
@@ -1344,7 +1352,7 @@ void beep(void *frontend, int mode)
        gdk_beep();
 }
 
-int CharWidth(Context ctx, int uc)
+int char_width(Context ctx, int uc)
 {
     /*
      * Under X, any fixed-width font really _is_ fixed-width.
@@ -1390,7 +1398,7 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
     struct gui_data *inst = dctx->inst;
     GdkGC *gc = dctx->gc;
 
-    int nfg, nbg, t, fontid, shadow;
+    int nfg, nbg, t, fontid, shadow, rlen;
 
     /*
      * NYI:
@@ -1427,13 +1435,25 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
            return;
        if (x + len*2 > inst->term->cols)
            len = (inst->term->cols-x)/2;    /* trim to LH half */
+       rlen = len * 2;
+    } else
+       rlen = len;
+
+    {
+       GdkRectangle r;
+
+       r.x = x*inst->font_width+cfg.window_border;
+       r.y = y*inst->font_height+cfg.window_border;
+       r.width = rlen*inst->font_width;
+       r.height = inst->font_height;
+       gdk_gc_set_clip_rectangle(gc, &r);
     }
 
     gdk_gc_set_foreground(gc, &inst->cols[nbg]);
     gdk_draw_rectangle(inst->pixmap, gc, 1,
                       x*inst->font_width+cfg.window_border,
                       y*inst->font_height+cfg.window_border,
-                      len*inst->font_width, inst->font_height);
+                      rlen*inst->font_width, inst->font_height);
 
     gdk_gc_set_foreground(gc, &inst->cols[nfg]);
     gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc,
@@ -1726,8 +1746,6 @@ char *get_x_display(void *frontend)
     return gdk_get_display();
 }
 
-char *app_name = "pterm";
-
 static void help(FILE *fp) {
     if(fprintf(fp,
 "pterm option summary:\n"
@@ -1761,18 +1779,22 @@ int do_cmdline(int argc, char **argv, int do_everything)
     extern char **pty_argv;           /* declared in pty.c */
 
     /*
-     * Macros to make argument handling easier.
+     * Macros to make argument handling easier. Note that because
+     * they need to call `continue', they cannot be contained in
+     * the usual do {...} while (0) wrapper to make them
+     * syntactically single statements; hence it is not legal to
+     * use one of these macros as an unbraced statement between
+     * `if' and `else'.
      */
-#define EXPECTS_ARG do { \
+#define EXPECTS_ARG { \
     if (--argc <= 0) { \
        err = 1; \
        fprintf(stderr, "pterm: %s expects an argument\n", p); \
+        continue; \
     } else \
        val = *++argv; \
-} while (0)
-#define SECOND_PASS_ONLY do { \
-    if (!do_everything) continue; \
-} while (0)
+}
+#define SECOND_PASS_ONLY { if (!do_everything) continue; }
 
     /*
      * TODO:
@@ -1921,12 +1943,27 @@ int do_cmdline(int argc, char **argv, int do_everything)
     return err;
 }
 
+static void block_signal(int sig, int block_it) {
+  sigset_t ss;
+
+  sigemptyset(&ss);
+  sigaddset(&ss, sig);
+  if(sigprocmask(block_it ? SIG_BLOCK : SIG_UNBLOCK, &ss, 0) < 0) {
+    perror("sigprocmask");
+    exit(1);
+  }
+}
+
 int main(int argc, char **argv)
 {
     extern int pty_master_fd;         /* declared in pty.c */
     extern void pty_pre_init(void);    /* declared in pty.c */
     struct gui_data *inst;
 
+    /* defer any child exit handling until we're ready to deal with
+     * it */
+    block_signal(SIGCHLD, 1);
+
     pty_pre_init();
 
     gtk_init(&argc, &argv);
@@ -2064,7 +2101,7 @@ int main(int argc, char **argv)
     inst->currcursor = inst->textcursor;
     show_mouseptr(inst, 1);
 
-    inst->term = term_init(inst);
+    inst->term = term_init(&cfg, inst);
     inst->logctx = log_init(inst);
     term_provide_logctx(inst->term, inst->logctx);
 
@@ -2084,6 +2121,10 @@ int main(int argc, char **argv)
     inst->master_func_id = gdk_input_add(pty_master_fd, GDK_INPUT_READ,
                                         pty_input_func, inst);
 
+    /* now we're reday to deal with the child exit handler being
+     * called */
+    block_signal(SIGCHLD, 0);
+    
     gtk_main();
 
     return 0;