diff options
Diffstat (limited to 'app/xterm/misc.c')
-rw-r--r-- | app/xterm/misc.c | 1076 |
1 files changed, 739 insertions, 337 deletions
diff --git a/app/xterm/misc.c b/app/xterm/misc.c index d378f9026..20a66e424 100644 --- a/app/xterm/misc.c +++ b/app/xterm/misc.c @@ -1,8 +1,8 @@ -/* $XTermId: misc.c,v 1.428 2009/10/12 00:44:44 tom Exp $ */ +/* $XTermId: misc.c,v 1.482 2010/01/21 09:34:58 tom Exp $ */ /* * - * Copyright 1999-2008,2009 by Thomas E. Dickey + * Copyright 1999-2009,2010 by Thomas E. Dickey * * All Rights Reserved * @@ -225,13 +225,11 @@ DoSpecialEnterNotify(XtermWidget xw, XEnterWindowEvent * ev) TScreen *screen = TScreenOf(xw); TRACE(("DoSpecialEnterNotify(%d)\n", screen->select)); -#ifdef ACTIVEWINDOWINPUTONLY - if (ev->window == XtWindow(XtParent(CURRENT_EMU()))) -#endif - if (((ev->detail) != NotifyInferior) && - ev->focus && - !(screen->select & FOCUS)) - selectwindow(screen, INWINDOW); + TRACE_FOCUS(xw, ev); + if (((ev->detail) != NotifyInferior) && + ev->focus && + !(screen->select & FOCUS)) + selectwindow(screen, INWINDOW); } static void @@ -240,13 +238,11 @@ DoSpecialLeaveNotify(XtermWidget xw, XEnterWindowEvent * ev) TScreen *screen = TScreenOf(xw); TRACE(("DoSpecialLeaveNotify(%d)\n", screen->select)); -#ifdef ACTIVEWINDOWINPUTONLY - if (ev->window == XtWindow(XtParent(CURRENT_EMU()))) -#endif - if (((ev->detail) != NotifyInferior) && - ev->focus && - !(screen->select & FOCUS)) - unselectwindow(screen, INWINDOW); + TRACE_FOCUS(xw, ev); + if (((ev->detail) != NotifyInferior) && + ev->focus && + !(screen->select & FOCUS)) + unselectwindow(screen, INWINDOW); } #ifndef XUrgencyHint @@ -517,10 +513,7 @@ HandleKeyPressed(Widget w GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { TRACE(("Handle insert-seven-bit for %p\n", (void *) w)); -#ifdef ACTIVEWINDOWINPUTONLY - if (w == CURRENT_EMU()) -#endif - Input(term, &event->xkey, False); + Input(term, &event->xkey, False); } /* ARGSUSED */ @@ -531,10 +524,7 @@ HandleEightBitKeyPressed(Widget w GCC_UNUSED, Cardinal *nparams GCC_UNUSED) { TRACE(("Handle insert-eight-bit for %p\n", (void *) w)); -#ifdef ACTIVEWINDOWINPUTONLY - if (w == CURRENT_EMU()) -#endif - Input(term, &event->xkey, True); + Input(term, &event->xkey, True); } /* ARGSUSED */ @@ -544,10 +534,6 @@ HandleStringEvent(Widget w GCC_UNUSED, String * params, Cardinal *nparams) { -#ifdef ACTIVEWINDOWINPUTONLY - if (w != CURRENT_EMU()) - return; -#endif if (*nparams != 1) return; @@ -555,10 +541,11 @@ HandleStringEvent(Widget w GCC_UNUSED, if ((*params)[0] == '0' && (*params)[1] == 'x' && (*params)[2] != '\0') { const char *abcdef = "ABCDEF"; const char *xxxxxx; - Char c, *p; + Char c; + UString p; unsigned value = 0; - for (p = (Char *) (*params + 2); (c = CharOf(x_toupper(*p))) != + for (p = (UString) (*params + 2); (c = CharOf(x_toupper(*p))) != '\0'; p++) { value *= 16; if (c >= '0' && c <= '9') @@ -592,7 +579,7 @@ HandleSpawnTerminal(Widget w GCC_UNUSED, String * params, Cardinal *nparams) { - TScreen *screen = &term->screen; + TScreen *screen = TScreenOf(term); char *child_cwd = NULL; char *child_exe; pid_t pid; @@ -712,6 +699,7 @@ HandleEnterWindow(Widget w GCC_UNUSED, { /* NOP since we handled it above */ TRACE(("HandleEnterWindow ignored\n")); + TRACE_FOCUS(w, event); } /*ARGSUSED*/ @@ -723,6 +711,7 @@ HandleLeaveWindow(Widget w GCC_UNUSED, { /* NOP since we handled it above */ TRACE(("HandleLeaveWindow ignored\n")); + TRACE_FOCUS(w, event); } /*ARGSUSED*/ @@ -740,6 +729,7 @@ HandleFocusChange(Widget w GCC_UNUSED, visibleEventType(event->type), event->mode, event->detail)); + TRACE_FOCUS(xw, event); if (screen->quiet_grab && (event->mode == NotifyGrab || event->mode == NotifyUngrab)) { @@ -824,6 +814,41 @@ xtermBell(XtermWidget xw, int which, int percent) TScreen *screen = TScreenOf(xw); #if defined(HAVE_XKB_BELL_EXT) Atom tony = AtomBell(xw, which); +#endif + + switch (which) { + case XkbBI_Info: + case XkbBI_MinorError: + case XkbBI_MajorError: + case XkbBI_TerminalBell: + switch (screen->warningVolume) { + case bvOff: + percent = -100; + break; + case bvLow: + break; + case bvHigh: + percent = 100; + break; + } + break; + case XkbBI_MarginBell: + switch (screen->marginVolume) { + case bvOff: + percent = -100; + break; + case bvLow: + break; + case bvHigh: + percent = 100; + break; + } + break; + default: + break; + } + +#if defined(HAVE_XKB_BELL_EXT) if (tony != None) { XkbBell(screen->display, VShellWindow, percent, tony); } else @@ -832,7 +857,7 @@ xtermBell(XtermWidget xw, int which, int percent) } void -Bell(int which GCC_UNUSED, int percent) +Bell(int which, int percent) { XtermWidget xw = term; TScreen *screen = TScreenOf(xw); @@ -912,7 +937,7 @@ VisualBell(void) visualGC = XtGetGC((Widget) term, GCFunction + GCForeground, &gcval); #if OPT_TEK4014 if (TEK4014_ACTIVE(term)) { - TekScreen *tekscr = &(tekWidget->screen); + TekScreen *tekscr = TekScreenOf(tekWidget); flashWindow(screen, TWindow(tekscr), visualGC, TFullWidth(tekscr), TFullHeight(tekscr)); @@ -954,7 +979,7 @@ WMFrameWindow(XtermWidget termw) do { if (win_parent) win_current = win_parent; - XQueryTree((&termw->screen)->display, + XQueryTree(TScreenOf(termw)->display, win_current, &win_root, &win_parent, @@ -1141,7 +1166,7 @@ HandleDabbrevExpand(Widget w, TRACE(("Handle dabbrev-expand for %p\n", (void *) w)); if ((xw = getXtermWidget(w)) != 0) { - TScreen *screen = &xw->screen; + TScreen *screen = TScreenOf(xw); if (!dabbrev_expand(screen)) Bell(XkbBI_TerminalBell, 0); } @@ -1184,7 +1209,7 @@ HandleIconify(Widget w, int QueryMaximize(XtermWidget termw, unsigned *width, unsigned *height) { - TScreen *screen = &termw->screen; + TScreen *screen = TScreenOf(termw); XSizeHints hints; long supp = 0; Window root_win; @@ -1236,10 +1261,12 @@ QueryMaximize(XtermWidget termw, unsigned *width, unsigned *height) void RequestMaximize(XtermWidget termw, int maximize) { - TScreen *screen = &termw->screen; + TScreen *screen = TScreenOf(termw); XWindowAttributes wm_attrs, vshell_attrs; unsigned root_width, root_height; + TRACE(("RequestMaximize %s\n", maximize ? "maximize" : "restore")); + if (maximize) { if (QueryMaximize(termw, &root_width, &root_height)) { @@ -1359,7 +1386,7 @@ Redraw(void) } #if OPT_TEK4014 if (TEK4014_SHOWN(term)) { - TekScreen *tekscr = &(tekWidget->screen); + TekScreen *tekscr = TekScreenOf(tekWidget); event.window = TWindow(tekscr); event.width = tekWidget->core.width; event.height = tekWidget->core.height; @@ -1528,7 +1555,7 @@ creat_as(uid_t uid, gid_t gid, Bool append, char *pathname, int mode) If we can check for this possibility without hanging, do so. */ do - if (waited == term->screen.pid) + if (waited == TScreenOf(term)->pid) Cleanup(0); while ((waited = nonblocking_wait()) > 0) ; #endif /* HAVE_WAITPID */ @@ -1748,22 +1775,24 @@ FlushLog(TScreen * screen) static void ReportAnsiColorRequest(XtermWidget xw, int colornum, int final) { - XColor color; - Colormap cmap = xw->core.colormap; - char buffer[80]; - - TRACE(("ReportAnsiColorRequest %d\n", colornum)); - color.pixel = GET_COLOR_RES(xw->screen.Acolors[colornum]); - XQueryColor(xw->screen.display, cmap, &color); - sprintf(buffer, "4;%d;rgb:%04x/%04x/%04x", - colornum, - color.red, - color.green, - color.blue); - unparseputc1(xw, ANSI_OSC); - unparseputs(xw, buffer); - unparseputc1(xw, final); - unparse_end(xw); + if (AllowColorOps(xw, ecGetAnsiColor)) { + XColor color; + Colormap cmap = xw->core.colormap; + char buffer[80]; + + TRACE(("ReportAnsiColorRequest %d\n", colornum)); + color.pixel = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[colornum]); + XQueryColor(TScreenOf(xw)->display, cmap, &color); + sprintf(buffer, "4;%d;rgb:%04x/%04x/%04x", + colornum, + color.red, + color.green, + color.blue); + unparseputc1(xw, ANSI_OSC); + unparseputs(xw, buffer); + unparseputc1(xw, final); + unparse_end(xw); + } } static unsigned @@ -1896,7 +1925,7 @@ AllocateAnsiColor(XtermWidget xw, { int result; XColor def; - TScreen *screen = &xw->screen; + TScreen *screen = TScreenOf(xw); Colormap cmap = xw->core.colormap; if (XParseColor(screen->display, cmap, spec, &def) @@ -1928,7 +1957,7 @@ AllocateAnsiColor(XtermWidget xw, #if OPT_COLOR_RES Pixel -xtermGetColorRes(ColorRes * res) +xtermGetColorRes(XtermWidget xw, ColorRes * res) { Pixel result = 0; @@ -1936,13 +1965,13 @@ xtermGetColorRes(ColorRes * res) result = res->value; } else { TRACE(("xtermGetColorRes for Acolors[%d]\n", - res - term->screen.Acolors)); + res - TScreenOf(xw)->Acolors)); - if (res >= term->screen.Acolors) { - assert(res - term->screen.Acolors < MAXCOLORS); + if (res >= TScreenOf(xw)->Acolors) { + assert(res - TScreenOf(xw)->Acolors < MAXCOLORS); - if (AllocateAnsiColor(term, res, res->resource) < 0) { - res->value = term->screen.Tcolors[TEXT_FG].value; + if (AllocateAnsiColor(xw, res, res->resource) < 0) { + res->value = TScreenOf(xw)->Tcolors[TEXT_FG].value; res->mode = -True; fprintf(stderr, "%s: Cannot allocate color %s\n", @@ -1958,15 +1987,45 @@ xtermGetColorRes(ColorRes * res) } #endif +static int +ChangeOneAnsiColor(XtermWidget xw, int color, char *name) +{ + int code; + + if (color < 0 || color >= MAXCOLORS) { + code = -1; + } else { + ColorRes *res = &(TScreenOf(xw)->Acolors[color]); + + TRACE(("ChangeAnsiColor for Acolors[%d]\n", color)); + code = AllocateAnsiColor(xw, res, name); + } + return code; +} + +/* + * Set or query entries in the Acolors[] array by parsing pairs of color/name + * values from the given buffer. + * + * The color can be any legal index into Acolors[], which consists of the + * 16/88/256 "ANSI" colors, followed by special color values for the various + * colorXX resources. The indices for the special color values are not + * simple to work with, so an alternative is to use the calls which pass in + * 'first' set to the beginning of those indices. + * + * If the name is "?", report to the host the current value for the color. + */ static Bool ChangeAnsiColorRequest(XtermWidget xw, char *buf, + int first, int final) { char *name; int color; int repaint = False; int code; + int last = (MAXCOLORS - first); TRACE(("ChangeAnsiColorRequest string='%s'\n", buf)); @@ -1977,18 +2036,17 @@ ChangeAnsiColorRequest(XtermWidget xw, *name = '\0'; name++; color = atoi(buf); - if (color < 0 || color >= NUM_ANSI_COLORS) - break; + if (color < 0 || color >= last) + break; /* quit on any error */ buf = strchr(name, ';'); if (buf) { *buf = '\0'; buf++; } - if (!strcmp(name, "?")) - ReportAnsiColorRequest(xw, color, final); - else { - TRACE(("ChangeAnsiColor for Acolors[%d]\n", color)); - code = AllocateAnsiColor(xw, &(xw->screen.Acolors[color]), name); + if (!strcmp(name, "?")) { + ReportAnsiColorRequest(xw, color + first, final); + } else { + code = ChangeOneAnsiColor(xw, color + first, name); if (code < 0) { /* stop on any error */ break; @@ -2000,11 +2058,66 @@ ChangeAnsiColorRequest(XtermWidget xw, */ } } - if (repaint) - xtermRepaint(xw); return (repaint); } + +static Bool +ResetOneAnsiColor(XtermWidget xw, int color, int start) +{ + Bool repaint = False; + int last = MAXCOLORS - start; + + if (color >= 0 && color < last) { + ColorRes *res = &(TScreenOf(xw)->Acolors[color + start]); + + if (res->mode) { + /* a color has been allocated for this slot - test further... */ + if (ChangeOneAnsiColor(xw, color + start, res->resource) > 0) { + repaint = True; + } + } + } + return repaint; +} + +int +ResetAnsiColorRequest(XtermWidget xw, char *buf, int start) +{ + int repaint = 0; + int color; + + TRACE(("ResetAnsiColorRequest(%s)\n", buf)); + if (*buf != '\0') { + /* reset specific colors */ + while (!IsEmpty(buf)) { + char *next; + + color = strtol(buf, &next, 10); + if (next == buf) + break; /* no number at all */ + if (next != 0) { + if (strchr(";", *next) == 0) + break; /* unexpected delimiter */ + ++next; + } + + if (ResetOneAnsiColor(xw, color, start)) { + ++repaint; + } + buf = next; + } + } else { + TRACE(("...resetting all %d colors\n", MAXCOLORS)); + for (color = 0; color < MAXCOLORS; ++color) { + if (ResetOneAnsiColor(xw, color, start)) { + ++repaint; + } + } + } + TRACE(("...ResetAnsiColorRequest ->%d\n", repaint)); + return repaint; +} #else #define find_closest_color(display, cmap, def) 0 #endif /* OPT_ISO_COLORS */ @@ -2016,7 +2129,7 @@ ManipulateSelectionData(XtermWidget xw, TScreen * screen, char *buf, int final) #define PDATA(a,b) { a, #b } static struct { char given; - char *result; + String result; } table[] = { PDATA('s', SELECT), PDATA('p', PRIMARY), @@ -2034,7 +2147,7 @@ ManipulateSelectionData(XtermWidget xw, TScreen * screen, char *buf, int final) const char *base = buf; char *used = x_strdup(base); Cardinal j, n = 0; - char **select_args = 0; + String *select_args = 0; TRACE(("Manipulate selection data\n")); @@ -2063,26 +2176,30 @@ ManipulateSelectionData(XtermWidget xw, TScreen * screen, char *buf, int final) used[n] = 0; if (!strcmp(buf, "?")) { - TRACE(("Getting selection\n")); - unparseputc1(xw, ANSI_OSC); - unparseputs(xw, "52"); - unparseputc(xw, ';'); + if (AllowWindowOps(xw, ewGetSelection)) { + TRACE(("Getting selection\n")); + unparseputc1(xw, ANSI_OSC); + unparseputs(xw, "52"); + unparseputc(xw, ';'); - unparseputs(xw, used); - unparseputc(xw, ';'); + unparseputs(xw, used); + unparseputc(xw, ';'); - /* Tell xtermGetSelection data is base64 encoded */ - screen->base64_paste = n; - screen->base64_final = final; + /* Tell xtermGetSelection data is base64 encoded */ + screen->base64_paste = n; + screen->base64_final = final; - /* terminator will be written in this call */ - xtermGetSelection((Widget) xw, 0, select_args, n, NULL); + /* terminator will be written in this call */ + xtermGetSelection((Widget) xw, 0, select_args, n, NULL); + } } else { - TRACE(("Setting selection with %s\n", buf)); - ClearSelectionBuffer(screen); - while (*buf != '\0') - AppendToSelectionBuffer(screen, CharOf(*buf++)); - CompleteSelection(xw, select_args, n); + if (AllowWindowOps(xw, ewSetSelection)) { + TRACE(("Setting selection with %s\n", buf)); + ClearSelectionBuffer(screen); + while (*buf != '\0') + AppendToSelectionBuffer(screen, CharOf(*buf++)); + CompleteSelection(xw, select_args, n); + } } } } @@ -2090,9 +2207,12 @@ ManipulateSelectionData(XtermWidget xw, TScreen * screen, char *buf, int final) /***====================================================================***/ +#define IsSetUtf8Title(xw) (IsTitleMode(xw, tmSetUtf8) || (xw->screen.utf8_title)) + static Bool -xtermIsPrintable(TScreen * screen, Char ** bufp, Char * last) +xtermIsPrintable(XtermWidget xw, Char ** bufp, Char * last) { + TScreen *screen = TScreenOf(xw); Bool result = False; Char *cp = *bufp; Char *next = cp; @@ -2101,7 +2221,7 @@ xtermIsPrintable(TScreen * screen, Char ** bufp, Char * last) (void) last; #if OPT_WIDE_CHARS - if (xtermEnvUTF8() && screen->utf8_title) { + if (xtermEnvUTF8() && IsSetUtf8Title(xw)) { PtyData data; if (decodeUtf8(fakePtyData(&data, cp, last))) { @@ -2135,7 +2255,7 @@ xtermIsPrintable(TScreen * screen, Char ** bufp, Char * last) /* * Enum corresponding to the actual OSC codes rather than the internal - * array indices. + * array indices. Compare with TermColors. */ typedef enum { OSC_TEXT_FG = 10 @@ -2159,6 +2279,12 @@ typedef enum { ,OSC_NCOLORS } OscTextColors; +/* + * Map codes to OSC controls that can reset colors. + */ +#define OSC_RESET 100 +#define OSC_Reset(code) (code) + OSC_RESET + static ScrnColors *pOldColors = NULL; static Bool @@ -2222,29 +2348,32 @@ oppositeColor(int n) static void ReportColorRequest(XtermWidget xw, int ndx, int final) { - XColor color; - Colormap cmap = xw->core.colormap; - char buffer[80]; + if (AllowColorOps(xw, ecGetColor)) { + XColor color; + Colormap cmap = xw->core.colormap; + char buffer[80]; - /* - * ChangeColorsRequest() has "always" chosen the opposite color when - * reverse-video is set. Report this as the original color index, but - * reporting the opposite color which would be used. - */ - int i = (xw->misc.re_verse) ? oppositeColor(ndx) : ndx; - - GetOldColors(xw); - color.pixel = pOldColors->colors[ndx]; - XQueryColor(xw->screen.display, cmap, &color); - sprintf(buffer, "%d;rgb:%04x/%04x/%04x", i + 10, - color.red, - color.green, - color.blue); - TRACE(("ReportColors %d: %#lx as %s\n", ndx, pOldColors->colors[ndx], buffer)); - unparseputc1(xw, ANSI_OSC); - unparseputs(xw, buffer); - unparseputc1(xw, final); - unparse_end(xw); + /* + * ChangeColorsRequest() has "always" chosen the opposite color when + * reverse-video is set. Report this as the original color index, but + * reporting the opposite color which would be used. + */ + int i = (xw->misc.re_verse) ? oppositeColor(ndx) : ndx; + + GetOldColors(xw); + color.pixel = pOldColors->colors[ndx]; + XQueryColor(TScreenOf(xw)->display, cmap, &color); + sprintf(buffer, "%d;rgb:%04x/%04x/%04x", i + 10, + color.red, + color.green, + color.blue); + TRACE(("ReportColors %d: %#lx as %s\n", + ndx, pOldColors->colors[ndx], buffer)); + unparseputc1(xw, ANSI_OSC); + unparseputs(xw, buffer); + unparseputc1(xw, final); + unparse_end(xw); + } } static Bool @@ -2330,7 +2459,7 @@ ChangeColorsRequest(XtermWidget xw, if (xw->misc.re_verse) ndx = oppositeColor(ndx); - if ((names == NULL) || (names[0] == '\0')) { + if (IsEmpty(names)) { newColors.names[ndx] = NULL; } else { if (names[0] == ';') @@ -2360,16 +2489,227 @@ ChangeColorsRequest(XtermWidget xw, return result; } +static Bool +ResetColorsRequest(XtermWidget xw, + int code) +{ + Bool result = False; + char *thisName; + ScrnColors newColors; + int ndx; + + TRACE(("ResetColorsRequest code=%d\n", code)); + +#if OPT_COLOR_RES + if (GetOldColors(xw)) { + ndx = OscToColorIndex((OscTextColors) (code - OSC_RESET)); + if (xw->misc.re_verse) + ndx = oppositeColor(ndx); + + thisName = xw->screen.Tcolors[ndx].resource; + + newColors.which = 0; + newColors.names[ndx] = NULL; + + if (thisName != 0 + && pOldColors->names[ndx] != 0 + && strcmp(thisName, pOldColors->names[ndx])) { + AllocateTermColor(xw, &newColors, ndx, thisName); + + if (newColors.which != 0) { + ChangeColors(xw, &newColors); + UpdateOldColors(xw, &newColors); + } + } + result = True; + } +#endif + return result; +} + +#if OPT_SHIFT_FONTS +/* + * Initially, 'source' points to '#' or '?'. + * + * Look for an optional sign and optional number. If those are found, lookup + * the corresponding menu font entry. + */ +static int +ParseShiftedFont(XtermWidget xw, char *source, char **target) +{ + TScreen *screen = TScreenOf(xw); + int num = screen->menu_font_number; + int rel = 0; + + if (*++source == '+') { + rel = 1; + source++; + } else if (*source == '-') { + rel = -1; + source++; + } + + if (isdigit(CharOf(*source))) { + int val = atoi(source); + if (rel > 0) + rel = val; + else if (rel < 0) + rel = -val; + else + num = val; + } + + if (rel != 0) { + num = lookupRelativeFontSize(xw, + screen->menu_font_number, rel); + + } + TRACE(("ParseShiftedFont(%s) ->%d (%s)\n", *target, num, source)); + *target = source; + return num; +} + +static void +QueryFontRequest(XtermWidget xw, char *buf, int final) +{ + if (AllowFontOps(xw, efGetFont)) { + TScreen *screen = TScreenOf(xw); + Bool success = True; + int num; + char *base = buf + 1; + char *name = 0; + char temp[10]; + + num = ParseShiftedFont(xw, buf, &buf); + if (num < 0 + || num > fontMenu_lastBuiltin) { + Bell(XkbBI_MinorError, 0); + success = False; + } else { +#if OPT_RENDERFONT + if (UsingRenderFont(xw)) { + name = getFaceName(xw, False); + } else +#endif + if ((name = screen->MenuFontName(num)) == 0) { + success = False; + } + } + + unparseputc1(xw, ANSI_OSC); + unparseputs(xw, "50"); + + if (success) { + unparseputc(xw, ';'); + if (buf >= base) { + /* identify the font-entry, unless it is the current one */ + if (*buf != '\0') { + unparseputc(xw, '#'); + sprintf(temp, "%d", num); + unparseputs(xw, temp); + if (*name != '\0') + unparseputc(xw, ' '); + } + } + unparseputs(xw, name); + } + + unparseputc1(xw, final); + unparse_end(xw); + } +} + +static void +ChangeFontRequest(XtermWidget xw, char *buf) +{ + if (AllowFontOps(xw, efSetFont)) { + TScreen *screen = TScreenOf(xw); + Bool success = True; + int num; + VTFontNames fonts; + char *name; + + /* + * If the font specification is a "#", followed by an optional sign and + * optional number, lookup the corresponding menu font entry. + * + * Further, if the "#", etc., is followed by a font name, use that + * to load the font entry. + */ + if (*buf == '#') { + num = ParseShiftedFont(xw, buf, &buf); + + if (num < 0 + || num > fontMenu_lastBuiltin) { + Bell(XkbBI_MinorError, 0); + success = False; + } else { + /* + * Skip past the optional number, and any whitespace to look + * for a font specification within the control. + */ + while (isdigit(CharOf(*buf))) { + ++buf; + } + while (isspace(CharOf(*buf))) { + ++buf; + } +#if OPT_RENDERFONT + if (UsingRenderFont(xw)) { + ; /* there is only one font entry to load */ + } else +#endif + { + /* + * Normally there is no font specified in the control. + * But if there is, simply overwrite the font entry. + */ + if (*buf == '\0') { + if ((buf = screen->MenuFontName(num)) == 0) { + success = False; + } + } + } + } + } else { + num = screen->menu_font_number; + } + name = x_strtrim(buf); + if (success && !IsEmpty(name)) { +#if OPT_RENDERFONT + if (UsingRenderFont(xw)) { + setFaceName(xw, name); + xtermUpdateFontInfo(xw, True); + } else +#endif + { + memset(&fonts, 0, sizeof(fonts)); + fonts.f_n = name; + SetVTFont(xw, num, True, &fonts); + } + } else { + Bell(XkbBI_MinorError, 0); + } + free(name); + } +} +#endif /* OPT_SHIFT_FONTS */ + /***====================================================================***/ void do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) { - TScreen *screen = &(xw->screen); + TScreen *screen = TScreenOf(xw); int mode; Char *cp; int state = 0; char *buf = 0; + char temp[2]; +#if OPT_ISO_COLORS + int ansi_colors = 0; +#endif + Bool need_data = True; TRACE(("do_osc %s\n", oscbuf)); @@ -2405,7 +2745,7 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) state = 3; /* FALLTHRU */ default: - if (!xtermIsPrintable(screen, &cp, oscbuf + len)) { + if (!xtermIsPrintable(xw, &cp, oscbuf + len)) { switch (mode) { case 0: case 1: @@ -2420,8 +2760,49 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) } } } - if (buf == 0) { - TRACE(("do_osc found no data\n")); + + /* + * Most OSC controls other than resets require data. Handle the others as + * a special case. + */ + switch (mode) { +#if OPT_ISO_COLORS + case OSC_Reset(4): + case OSC_Reset(5): + case OSC_Reset(OSC_TEXT_FG): + case OSC_Reset(OSC_TEXT_BG): + case OSC_Reset(OSC_TEXT_CURSOR): + case OSC_Reset(OSC_MOUSE_FG): + case OSC_Reset(OSC_MOUSE_BG): +#if OPT_HIGHLIGHT_COLOR + case OSC_Reset(OSC_HIGHLIGHT_BG): + case OSC_Reset(OSC_HIGHLIGHT_FG): +#endif +#if OPT_TEK4014 + case OSC_Reset(OSC_TEK_FG): + case OSC_Reset(OSC_TEK_BG): + case OSC_Reset(OSC_TEK_CURSOR): +#endif + need_data = False; + break; +#endif + default: + break; + } + + /* + * Check if we have data when we want, and not when we do not want it. + * Either way, that is a malformed control sequence, and will be ignored. + */ + if (IsEmpty(buf)) { + if (need_data) { + TRACE(("do_osc found no data\n")); + return; + } + temp[0] = '\0'; + buf = temp; + } else if (!need_data) { + TRACE(("do_osc found found unwanted data\n")); return; } @@ -2440,12 +2821,23 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) break; case 3: /* change X property */ - if (AllowWindowOps(xw)) + if (AllowWindowOps(xw, ewSetXprop)) ChangeXprop(buf); break; #if OPT_ISO_COLORS + case 5: + ansi_colors = NUM_ANSI_COLORS; + /* FALLTHRU */ case 4: - ChangeAnsiColorRequest(xw, buf, final); + if (ChangeAnsiColorRequest(xw, buf, ansi_colors, final)) + xtermRepaint(xw); + break; + case OSC_Reset(5): + ansi_colors = NUM_ANSI_COLORS; + /* FALLTHRU */ + case OSC_Reset(4): + if (ResetAnsiColorRequest(xw, buf, ansi_colors)) + xtermRepaint(xw); break; #endif case OSC_TEXT_FG: @@ -2455,14 +2847,34 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) case OSC_MOUSE_BG: #if OPT_HIGHLIGHT_COLOR case OSC_HIGHLIGHT_BG: + case OSC_HIGHLIGHT_FG: #endif #if OPT_TEK4014 case OSC_TEK_FG: case OSC_TEK_BG: case OSC_TEK_CURSOR: #endif - if (xw->misc.dynamicColors) + if (xw->misc.dynamicColors) { ChangeColorsRequest(xw, mode, buf, final); + } + break; + case OSC_Reset(OSC_TEXT_FG): + case OSC_Reset(OSC_TEXT_BG): + case OSC_Reset(OSC_TEXT_CURSOR): + case OSC_Reset(OSC_MOUSE_FG): + case OSC_Reset(OSC_MOUSE_BG): +#if OPT_HIGHLIGHT_COLOR + case OSC_Reset(OSC_HIGHLIGHT_BG): + case OSC_Reset(OSC_HIGHLIGHT_FG): +#endif +#if OPT_TEK4014 + case OSC_Reset(OSC_TEK_FG): + case OSC_Reset(OSC_TEK_BG): + case OSC_Reset(OSC_TEK_CURSOR): +#endif + if (xw->misc.dynamicColors) { + ResetColorsRequest(xw, mode); + } break; case 30: @@ -2477,8 +2889,7 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) * Warning, enabling this feature allows people to overwrite * arbitrary files accessible to the person running xterm. */ - if (buf != 0 - && strcmp(buf, "?") + if (strcmp(buf, "?") && (cp = CastMallocN(char, strlen(buf)) != NULL)) { strcpy(cp, buf); if (screen->logfile) @@ -2494,70 +2905,10 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) case 50: #if OPT_SHIFT_FONTS - if (!AllowFontOps(xw) && xw->misc.shift_fonts) { - ; /* disabled via resource or control-sequence */ - } else if (buf != 0 && !strcmp(buf, "?")) { - int num = screen->menu_font_number; - - unparseputc1(xw, ANSI_OSC); - unparseputs(xw, "50"); - - if ((buf = screen->MenuFontName(num)) != 0) { - unparseputc(xw, ';'); - unparseputs(xw, buf); - } - unparseputc1(xw, final); - unparse_end(xw); - } else if (buf != 0) { - int num = screen->menu_font_number; - VTFontNames fonts; - - memset(&fonts, 0, sizeof(fonts)); - - /* - * If the font specification is a "#", followed by an - * optional sign and optional number, lookup the - * corresponding menu font entry. - */ - if (*buf == '#') { - int rel = 0; - - if (*++buf == '+') { - rel = 1; - buf++; - } else if (*buf == '-') { - rel = -1; - buf++; - } - - if (isdigit(CharOf(*buf))) { - int val = atoi(buf); - if (rel > 0) - rel = val; - else if (rel < 0) - rel = -val; - else - num = val; - } else if (rel == 0) { - num = 0; - } - - if (rel != 0) { - num = lookupRelativeFontSize(xw, - screen->menu_font_number, rel); - - } - if (num < 0 - || num > fontMenu_lastBuiltin - || (buf = screen->MenuFontName(num)) == 0) { - Bell(XkbBI_MinorError, 0); - break; - } - } else { - num = fontMenu_fontescape; - } - fonts.f_n = buf; - SetVTFont(xw, num, True, &fonts); + if (*buf == '?') { + QueryFontRequest(xw, buf, final); + } else if (xw->misc.shift_fonts) { + ChangeFontRequest(xw, buf); } #endif /* OPT_SHIFT_FONTS */ break; @@ -2567,14 +2918,16 @@ do_osc(XtermWidget xw, Char * oscbuf, unsigned len GCC_UNUSED, int final) #if OPT_PASTE64 case 52: - if (AllowWindowOps(xw)) - ManipulateSelectionData(xw, screen, buf, final); + ManipulateSelectionData(xw, screen, buf, final); break; #endif /* * One could write code to send back the display and host names, * but that could potentially open a fairly nasty security hole. */ + default: + TRACE(("do_osc - unrecognized code\n")); + break; } unparse_end(xw); } @@ -2596,22 +2949,21 @@ static struct { * "real" terminals accept commas in the string definitions). */ static int -udk_value(char **cp) +udk_value(const char **cp) { + int result = -1; int c; for (;;) { if ((c = **cp) != '\0') *cp = *cp + 1; if (c == ';' || c == '\0') - return -1; - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; + break; + if ((result = x_hex2int(c)) >= 0) + break; } + + return result; } void @@ -2631,10 +2983,10 @@ reset_decudk(void) * Parse the data for DECUDK (user-defined keys). */ static void -parse_decudk(char *cp) +parse_decudk(const char *cp) { while (*cp) { - char *base = cp; + const char *base = cp; char *str = CastMallocN(char, strlen(cp) + 1); unsigned key = 0; int lo, hi; @@ -2669,7 +3021,7 @@ parse_decudk(char *cp) #define SOFT_HIGH 20 static void -parse_decdld(ANSI * params, char *string) +parse_decdld(ANSI * params, const char *string) { char DscsName[8]; int len; @@ -2783,9 +3135,9 @@ parse_decdld(ANSI * params, char *string) * interspersing with control characters, but have the string already. */ static void -parse_ansi_params(ANSI * params, char **string) +parse_ansi_params(ANSI * params, const char **string) { - char *cp = *string; + const char *cp = *string; ParmType nparam = 0; memset(params, 0, sizeof(*params)); @@ -2815,9 +3167,9 @@ parse_ansi_params(ANSI * params, char **string) void do_dcs(XtermWidget xw, Char * dcsbuf, size_t dcslen) { - TScreen *screen = &xw->screen; + TScreen *screen = TScreenOf(xw); char reply[BUFSIZ]; - char *cp = (char *) dcsbuf; + const char *cp = (const char *) dcsbuf; Bool okay; ANSI params; @@ -2930,58 +3282,69 @@ do_dcs(XtermWidget xw, Char * dcsbuf, size_t dcslen) #if OPT_TCAP_QUERY case '+': cp++; - if ((*cp == 'q') && AllowTcapOps(xw)) { - Bool fkey; - unsigned state; - int code; - char *tmp; - char *parsed = ++cp; + switch (*cp) { + case 'p': + if (AllowTcapOps(xw, etSetTcap)) { + set_termcap(xw, cp + 1); + } + break; + case 'q': + if (AllowTcapOps(xw, etGetTcap)) { + Bool fkey; + unsigned state; + int code; + const char *tmp; + const char *parsed = ++cp; - code = xtermcapKeycode(xw, &parsed, &state, &fkey); + code = xtermcapKeycode(xw, &parsed, &state, &fkey); - unparseputc1(xw, ANSI_DCS); + unparseputc1(xw, ANSI_DCS); - unparseputc(xw, code >= 0 ? '1' : '0'); + unparseputc(xw, code >= 0 ? '1' : '0'); - unparseputc(xw, '+'); - unparseputc(xw, 'r'); + unparseputc(xw, '+'); + unparseputc(xw, 'r'); - while (*cp != 0 && (code >= -1)) { - if (cp == parsed) - break; /* no data found, error */ + while (*cp != 0 && (code >= -1)) { + if (cp == parsed) + break; /* no data found, error */ - for (tmp = cp; tmp != parsed; ++tmp) - unparseputc(xw, *tmp); + for (tmp = cp; tmp != parsed; ++tmp) + unparseputc(xw, *tmp); - if (code >= 0) { - unparseputc(xw, '='); - screen->tc_query_code = code; - screen->tc_query_fkey = fkey; + if (code >= 0) { + unparseputc(xw, '='); + screen->tc_query_code = code; + screen->tc_query_fkey = fkey; #if OPT_ISO_COLORS - /* XK_COLORS is a fake code for the "Co" entry (maximum - * number of colors) */ - if (code == XK_COLORS) { - unparseputn(xw, NUM_ANSI_COLORS); - } else -#endif - { - XKeyEvent event; - event.state = state; - Input(xw, &event, False); + /* XK_COLORS is a fake code for the "Co" entry (maximum + * number of colors) */ + if (code == XK_COLORS) { + unparseputn(xw, NUM_ANSI_COLORS); + } else +#endif + if (code == XK_TCAPNAME) { + unparseputs(xw, xterm_name); + } else { + XKeyEvent event; + event.state = state; + Input(xw, &event, False); + } + screen->tc_query_code = -1; + } else { + break; /* no match found, error */ } - screen->tc_query_code = -1; - } else { - break; /* no match found, error */ - } - cp = parsed; - if (*parsed == ';') { - unparseputc(xw, *parsed++); cp = parsed; - code = xtermcapKeycode(xw, &parsed, &state, &fkey); + if (*parsed == ';') { + unparseputc(xw, *parsed++); + cp = parsed; + code = xtermcapKeycode(xw, &parsed, &state, &fkey); + } } + unparseputc1(xw, ANSI_ST); } - unparseputc1(xw, ANSI_ST); + break; } break; #endif @@ -3023,107 +3386,141 @@ ChangeGroup(XtermWidget xw, const char *attribute, char *value) static char empty[1]; Arg args[1]; - char *my_attr = x_strdup(attribute); - char *original = (value != 0) ? value : empty; - char *name = original; - TScreen *screen = TScreenOf(xw); + Boolean changed = True; Widget w = CURRENT_EMU(); Widget top = SHELL_OF(w); - unsigned limit = strlen(name); - Char *c1 = (Char *) original; - Char *cp; - TRACE(("ChangeGroup(attribute=%s, value=%s)\n", my_attr, name)); + char *my_attr; + char *name; + unsigned limit; + Char *c1; + Char *cp; if (!AllowTitleOps(xw)) return; + if (value == 0) + value = empty; + if (IsTitleMode(xw, tmSetBase16)) { + const char *temp; + char *test; + + value = x_decode_hex(value, &temp); + if (*temp != '\0') + return; + for (test = value; *test != '\0'; ++test) { + if (CharOf(*test) < 32) { + *test = '\0'; + break; + } + } + } + + c1 = (Char *) value; + name = value; + limit = strlen(name); + my_attr = x_strdup(attribute); + + TRACE(("ChangeGroup(attribute=%s, value=%s)\n", my_attr, name)); + /* * Ignore titles that are too long to be plausible requests. */ - if (limit >= 1024) - return; + if (limit > 0 && limit < 1024) { - for (cp = c1; *cp != 0; ++cp) { - Char *c2 = cp; - if (!xtermIsPrintable(screen, &cp, c1 + limit)) { - memset(c2, '?', (size_t) (cp + 1 - c2)); + /* + * After all decoding, overwrite nonprintable characters with '?'. + */ + for (cp = c1; *cp != 0; ++cp) { + Char *c2 = cp; + if (!xtermIsPrintable(xw, &cp, c1 + limit)) { + memset(c2, '?', (size_t) (cp + 1 - c2)); + } } - } #if OPT_WIDE_CHARS - /* - * Title strings are limited to ISO-8859-1, which is consistent with the - * printable data in sos_table. However, if we're running in UTF-8 mode, - * it is likely that non-ASCII text in the string will be rejected because - * it is not printable in the current locale. So we convert it to UTF-8, - * allowing the X library to convert it back. - */ - if (xtermEnvUTF8() && !screen->utf8_title) { - int n; - - for (n = 0; name[n] != '\0'; ++n) { - if (CharOf(name[n]) > 127) { - if (converted != 0) - free(converted); - if ((converted = TypeMallocN(Char, 1 + (5 * limit))) != 0) { - Char *temp = converted; - while (*name != 0) { - temp = convertToUTF8(temp, CharOf(*name)); - ++name; + /* + * If we're running in UTF-8 mode, and have not been told that the + * title string is in UTF-8, it is likely that non-ASCII text in the + * string will be rejected because it is not printable in the current + * locale. So we convert it to UTF-8, allowing the X library to + * convert it back. + */ + if (xtermEnvUTF8() && !IsSetUtf8Title(xw)) { + int n; + + for (n = 0; name[n] != '\0'; ++n) { + if (CharOf(name[n]) > 127) { + if (converted != 0) + free(converted); + if ((converted = TypeMallocN(Char, 1 + (6 * limit))) != 0) { + Char *temp = converted; + while (*name != 0) { + temp = convertToUTF8(temp, CharOf(*name)); + ++name; + } + *temp = 0; + name = (char *) converted; + TRACE(("...converted{%s}\n", name)); } - *temp = 0; - name = (char *) converted; - TRACE(("...converted{%s}\n", name)); + break; } - break; } } - } #endif #if OPT_SAME_NAME - /* If the attribute isn't going to change, then don't bother... */ - - if (resource.sameName) { - char *buf; - XtSetArg(args[0], my_attr, &buf); - XtGetValues(top, args, 1); - TRACE(("...comparing{%s}\n", buf)); - if (strcmp(name, buf) == 0) - return; - } + /* If the attribute isn't going to change, then don't bother... */ + + if (resource.sameName) { + char *buf; + XtSetArg(args[0], my_attr, &buf); + XtGetValues(top, args, 1); + TRACE(("...comparing{%s}\n", buf)); + if (strcmp(name, buf) == 0) + changed = False; + } #endif /* OPT_SAME_NAME */ - TRACE(("...updating %s\n", my_attr)); - TRACE(("...value is %s\n", name)); - XtSetArg(args[0], my_attr, name); - XtSetValues(top, args, 1); + if (changed) { + TRACE(("...updating %s\n", my_attr)); + TRACE(("...value is %s\n", name)); + XtSetArg(args[0], my_attr, name); + XtSetValues(top, args, 1); #if OPT_WIDE_CHARS - if (xtermEnvUTF8()) { - Display *dpy = XtDisplay(xw); - Atom my_atom; - - const char *propname = (!strcmp(my_attr, XtNtitle) - ? "_NET_WM_NAME" - : "_NET_WM_ICON_NAME"); - if ((my_atom = XInternAtom(dpy, propname, False)) != None) { - if (screen->utf8_title) { /* FIXME - redundant? */ - TRACE(("...updating %s\n", propname)); - TRACE(("...value is %s\n", original)); - XChangeProperty(dpy, VShellWindow, - my_atom, XA_UTF8_STRING(dpy), 8, - PropModeReplace, - (Char *) original, (int) strlen(original)); - } else { - TRACE(("...deleting %s\n", propname)); - XDeleteProperty(dpy, VShellWindow, my_atom); + if (xtermEnvUTF8()) { + Display *dpy = XtDisplay(xw); + Atom my_atom; + + const char *propname = (!strcmp(my_attr, XtNtitle) + ? "_NET_WM_NAME" + : "_NET_WM_ICON_NAME"); + if ((my_atom = XInternAtom(dpy, propname, False)) != None) { + if (IsSetUtf8Title(xw)) { + TRACE(("...updating %s\n", propname)); + TRACE(("...value is %s\n", value)); + XChangeProperty(dpy, VShellWindow, my_atom, + XA_UTF8_STRING(dpy), 8, + PropModeReplace, + (Char *) value, + (int) strlen(value)); + } else { + TRACE(("...deleting %s\n", propname)); + XDeleteProperty(dpy, VShellWindow, my_atom); + } + } } +#endif } + + free(my_attr); + + if (IsTitleMode(xw, tmSetBase16)) + free(value); + } -#endif - free(my_attr); + return; } void @@ -3134,7 +3531,7 @@ ChangeIconName(XtermWidget xw, char *name) name = dummy; } #if OPT_ZICONBEEP /* If warning should be given then give it */ - if (resource.zIconBeep && xw->screen.zIconBeep_flagged) { + if (resource.zIconBeep && TScreenOf(xw)->zIconBeep_flagged) { char *newname = CastMallocN(char, strlen(name) + 4); if (!newname) { fprintf(stderr, "malloc failed in ChangeIconName\n"); @@ -3229,24 +3626,29 @@ AllocateTermColor(XtermWidget xw, int ndx, const char *name) { - XColor def; - TScreen *screen = &xw->screen; - Colormap cmap = xw->core.colormap; - char *newName; + Bool result = False; - if (XParseColor(screen->display, cmap, name, &def) - && (XAllocColor(screen->display, cmap, &def) - || find_closest_color(screen->display, cmap, &def)) - && (newName = x_strdup(name)) != 0) { - if (COLOR_DEFINED(pNew, ndx)) - free(pNew->names[ndx]); - SET_COLOR_VALUE(pNew, ndx, def.pixel); - SET_COLOR_NAME(pNew, ndx, newName); - TRACE(("AllocateTermColor #%d: %s (pixel %#lx)\n", ndx, newName, def.pixel)); - return (True); - } - TRACE(("AllocateTermColor #%d: %s (failed)\n", ndx, name)); - return (False); + if (AllowColorOps(xw, ecSetColor)) { + XColor def; + TScreen *screen = TScreenOf(xw); + Colormap cmap = xw->core.colormap; + char *newName; + + if (XParseColor(screen->display, cmap, name, &def) + && (XAllocColor(screen->display, cmap, &def) + || find_closest_color(screen->display, cmap, &def)) + && (newName = x_strdup(name)) != 0) { + if (COLOR_DEFINED(pNew, ndx)) + free(pNew->names[ndx]); + SET_COLOR_VALUE(pNew, ndx, def.pixel); + SET_COLOR_NAME(pNew, ndx, newName); + TRACE(("AllocateTermColor #%d: %s (pixel %#lx)\n", ndx, newName, def.pixel)); + result = True; + } else { + TRACE(("AllocateTermColor #%d: %s (failed)\n", ndx, name)); + } + } + return result; } /***====================================================================***/ @@ -3665,7 +4067,7 @@ void end_tek_mode(void) { if (TEK4014_ACTIVE(term)) { - FlushLog(&(term->screen)); + FlushLog(TScreenOf(term)); longjmp(Tekend, 1); } return; @@ -3675,7 +4077,7 @@ void end_vt_mode(void) { if (!TEK4014_ACTIVE(term)) { - FlushLog(&(term->screen)); + FlushLog(TScreenOf(term)); TEK4014_ACTIVE(term) = True; longjmp(VTend, 1); } |