X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/1a6759413e00cb564ea19ed8aaa0369b9f51e991..0ac15bdc20b75615898a22c61a6aacbdf929ce56:/unix/pterm.c diff --git a/unix/pterm.c b/unix/pterm.c index f7dbcbd9..1e80df45 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -472,6 +474,12 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data) output[1] = cfg.bksp_is_delete ? '\x7F' : '\x08'; end = 2; } + /* For Shift Backspace, do opposite of what is configured. */ + if (event->keyval == GDK_BackSpace && + (event->state & GDK_SHIFT_MASK)) { + output[1] = cfg.bksp_is_delete ? '\x08' : '\x7F'; + end = 2; + } /* Shift-Tab is ESC [ Z */ if (event->keyval == GDK_ISO_Left_Tab || @@ -1236,13 +1244,12 @@ void free_ctx(Context ctx) void do_text_internal(Context ctx, int x, int y, char *text, int len, unsigned long attr, int lattr) { - int nfg, nbg, t; + int nfg, nbg, t, fontid, shadow; GdkGC *gc = (GdkGC *)ctx; /* * NYI: * - Unicode, code pages, and ATTR_WIDE for CJK support. - * - shadow bolding */ nfg = 2 * ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT); @@ -1261,6 +1268,14 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len, nbg = NCOLOURS-1; } + fontid = shadow = 0; + if ((attr & ATTR_BOLD) && !cfg.bold_colour) { + if (inst->fonts[1]) + fontid = 1; + else + shadow = 1; + } + if (lattr != LATTR_NORM) { x *= 2; if (x >= cols) @@ -1276,11 +1291,25 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len, len*inst->font_width, inst->font_height); gdk_gc_set_foreground(gc, &inst->cols[nfg]); - gdk_draw_text(inst->pixmap, inst->fonts[0], gc, + gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc, x*inst->font_width+cfg.window_border, y*inst->font_height+cfg.window_border+inst->fonts[0]->ascent, text, len); + /* + * X fonts seem to be pretty consistent about leaving the + * _left_ pixel of the cell blank rather than the right. Hence + * I'm going to hard-code shadow bolding as displaying one + * pixel to the left rather than try to work out whether it + * should be left or right. + */ + if (shadow) { + gdk_draw_text(inst->pixmap, inst->fonts[fontid], gc, + x*inst->font_width+cfg.window_border - 1, + y*inst->font_height+cfg.window_border+inst->fonts[0]->ascent, + text, len); + } + if (attr & ATTR_UNDER) { int uheight = inst->fonts[0]->ascent + 1; if (uheight >= inst->font_height) @@ -1554,26 +1583,101 @@ char *get_x_display(void) return gdk_get_display(); } -int main(int argc, char **argv) +char *app_name = "pterm"; + +int do_cmdline(int argc, char **argv, int do_everything) { - extern int pty_master_fd; /* declared in pty.c */ - extern char **pty_argv; /* declared in pty.c */ int err = 0; + extern char **pty_argv; /* declared in pty.c */ - gtk_init(&argc, &argv); + /* + * Macros to make argument handling easier. + */ +#define EXPECTS_ARG do { \ + if (--argc <= 0) { \ + err = 1; \ + fprintf(stderr, "pterm: %s expects an argument\n", p); \ + } else \ + val = *++argv; \ +} while (0) +#define SECOND_PASS_ONLY do { \ + if (!do_everything) continue; \ +} while (0) - do_defaults(NULL, &cfg); + /* + * TODO: + * + * finish -geometry + */ + char *val; while (--argc > 0) { char *p = *++argv; - if (!strcmp(p, "-fn")) { - if (--argc > 0) { - strncpy(cfg.font, *++argv, sizeof(cfg.font)); - cfg.font[sizeof(cfg.font)-1] = '\0'; - } else - err = 1, fprintf(stderr, "pterm: -fn expects an argument\n"); - } - if (!strcmp(p, "-e")) { + if (!strcmp(p, "-fn") || !strcmp(p, "-font")) { + EXPECTS_ARG; + SECOND_PASS_ONLY; + strncpy(cfg.font, val, sizeof(cfg.font)); + cfg.font[sizeof(cfg.font)-1] = '\0'; + + } else if (!strcmp(p, "-fb")) { + EXPECTS_ARG; + SECOND_PASS_ONLY; + strncpy(cfg.boldfont, val, sizeof(cfg.boldfont)); + cfg.boldfont[sizeof(cfg.boldfont)-1] = '\0'; + + } else if (!strcmp(p, "-geometry")) { + int flags, x, y, w, h; + EXPECTS_ARG; + SECOND_PASS_ONLY; + + flags = XParseGeometry(val, &x, &y, &w, &h); + if (flags & WidthValue) + cfg.width = w; + if (flags & HeightValue) + cfg.height = h; + + /* + * Apparently setting the initial window position is + * difficult in GTK 1.2. Not entirely sure why this + * should be. 2.0 has gtk_window_parse_geometry(), + * which would help... For the moment, though, I can't + * be bothered with this. + */ + + } else if (!strcmp(p, "-sl")) { + EXPECTS_ARG; + SECOND_PASS_ONLY; + cfg.savelines = atoi(val); + + } else if (!strcmp(p, "-fg") || !strcmp(p, "-bg") || + !strcmp(p, "-bfg") || !strcmp(p, "-bbg") || + !strcmp(p, "-cfg") || !strcmp(p, "-cbg")) { + GdkColor col; + + EXPECTS_ARG; + SECOND_PASS_ONLY; + if (!gdk_color_parse(val, &col)) { + err = 1; + fprintf(stderr, "pterm: unable to parse colour \"%s\"\n", val); + } else { + int index; + index = (!strcmp(p, "-fg") ? 0 : + !strcmp(p, "-bg") ? 2 : + !strcmp(p, "-bfg") ? 1 : + !strcmp(p, "-bbg") ? 3 : + !strcmp(p, "-cfg") ? 4 : + !strcmp(p, "-cbg") ? 5 : -1); + assert(index != -1); + cfg.colours[index][0] = col.red / 256; + cfg.colours[index][1] = col.green / 256; + cfg.colours[index][2] = col.blue / 256; + } + + } else if (!strcmp(p, "-e")) { + /* This option swallows all further arguments. */ + if (!do_everything) + break; + if (--argc > 0) { int i; pty_argv = smalloc((argc+1) * sizeof(char *)); @@ -1584,45 +1688,92 @@ int main(int argc, char **argv) break; /* finished command-line processing */ } else err = 1, fprintf(stderr, "pterm: -e expects an argument\n"); - } - if (!strcmp(p, "-T")) { - if (--argc > 0) { - strncpy(cfg.wintitle, *++argv, sizeof(cfg.wintitle)); - cfg.wintitle[sizeof(cfg.wintitle)-1] = '\0'; - } else - err = 1, fprintf(stderr, "pterm: -T expects an argument\n"); - } - if (!strcmp(p, "-log")) { - if (--argc > 0) { - strncpy(cfg.logfilename, *++argv, sizeof(cfg.logfilename)); - cfg.logfilename[sizeof(cfg.logfilename)-1] = '\0'; - cfg.logtype = LGTYP_DEBUG; - } else - err = 1, fprintf(stderr, "pterm: -log expects an argument\n"); - } - if (!strcmp(p, "-hide")) { - cfg.hide_mouseptr = 1; - } - if (!strcmp(p, "-ut-")) { + + } else if (!strcmp(p, "-T")) { + EXPECTS_ARG; + SECOND_PASS_ONLY; + strncpy(cfg.wintitle, val, sizeof(cfg.wintitle)); + cfg.wintitle[sizeof(cfg.wintitle)-1] = '\0'; + + } else if (!strcmp(p, "-log")) { + EXPECTS_ARG; + SECOND_PASS_ONLY; + strncpy(cfg.logfilename, val, sizeof(cfg.logfilename)); + cfg.logfilename[sizeof(cfg.logfilename)-1] = '\0'; + cfg.logtype = LGTYP_DEBUG; + + } else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) { + SECOND_PASS_ONLY; cfg.stamp_utmp = 0; - } - if (!strcmp(p, "-ls-")) { + + } else if (!strcmp(p, "-ut")) { + SECOND_PASS_ONLY; + cfg.stamp_utmp = 0; + + } else if (!strcmp(p, "-ls-") || !strcmp(p, "+ls")) { + SECOND_PASS_ONLY; cfg.login_shell = 0; - } - if (!strcmp(p, "-nethack")) { + + } else if (!strcmp(p, "-ls")) { + SECOND_PASS_ONLY; + cfg.login_shell = 1; + + } else if (!strcmp(p, "-nethack")) { + SECOND_PASS_ONLY; cfg.nethack_keypad = 1; - } - if (!strcmp(p, "-sb-")) { + + } else if (!strcmp(p, "-sb-") || !strcmp(p, "+sb")) { + SECOND_PASS_ONLY; + cfg.scrollbar = 0; + + } else if (!strcmp(p, "-sb")) { + SECOND_PASS_ONLY; cfg.scrollbar = 0; + + } else if (!strcmp(p, "-name")) { + EXPECTS_ARG; + app_name = val; + + } else if (!strcmp(p, "-xrm")) { + EXPECTS_ARG; + provide_xrm_string(val); + } } + return err; +} + +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 */ + + pty_pre_init(); + + gtk_init(&argc, &argv); + + if (do_cmdline(argc, argv, 0)) /* pre-defaults pass to get -class */ + exit(1); + do_defaults(NULL, &cfg); + if (do_cmdline(argc, argv, 1)) /* post-defaults, do everything */ + exit(1); + inst->fonts[0] = gdk_font_load(cfg.font); if (!inst->fonts[0]) { fprintf(stderr, "pterm: unable to load font \"%s\"\n", cfg.font); exit(1); } - inst->fonts[1] = NULL; /* FIXME: what about bold font? */ + if (cfg.boldfont[0]) { + inst->fonts[1] = gdk_font_load(cfg.boldfont); + if (!inst->fonts[1]) { + fprintf(stderr, "pterm: unable to load bold font \"%s\"\n", + cfg.boldfont); + exit(1); + } + } else + inst->fonts[1] = NULL; + inst->font_width = gdk_char_width(inst->fonts[0], ' '); inst->font_height = inst->fonts[0]->ascent + inst->fonts[0]->descent;