diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2009-04-04 15:10:46 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2009-04-04 15:10:46 +0000 |
commit | 3f1e1ec27086e513778a2fc86e249a11ab92fe41 (patch) | |
tree | 75e82b3c8cc0a7321b566c0f831566abb383dae2 /app/xterm/button.c | |
parent | 142e50ea1b148e92d0c6d2b57c5895e7d6b7065a (diff) |
Update to xterm 243. tested by naddy@.
Patch #243 - 2009/3/28
* revert change to default for allowTcapOps (request by Bram Moolenaar).
* reallocate result returned by xtermEnvLocale() to avoid reference to
freed memory after handling menuLocale resource.
* fix an old (X11R5) bug in tek4014 for switching fontsizes.
* add resource defaultString to make configurable the use of "#" when
pastes of UTF-8 text fail due to limitations in the current locale settings.
* make the set of selection target Atom's configurable by two new
resources eightBitSelectTypes and utf8SelectTypes, e.g., to use the TEXT
Atom in preference to UTF8_STRING (discussion with Stanislav Sedov
regarding koi8rxterm and the FreeBSD port).
* modify handling of TARGETS Atom by making it return exactly the set of
targets as those which xterm is currently providing.
* set MANPAGER and PAGER explicitly to /bin/cat in minstall.sh to work
around /etc/man.conf's with those variables already set (report by
Mar'yasin Semion).
* improve error-checking of tcap-query parser.
* add check for keyboard tcap), which ensures that terminal descriptions
containing the same string for shifted/unshifted keys will be seen by
tcap-query as only the unshifted key. (This would only happen with an
incorrect terminal description).
* fix conversion for input event-state to modifier-parameter which made
tcap-query feature not work with tcapFunctionKeys (keyboard type tcap).
* add "DEF_ALLOW_XXX" definitions to main.h to allow overriding the
default compiled-in values for "allowxxx" resources.
* remove check on bell-percentage added in patch #242, which disallowed
zero/negative values (Redhat Bugzilla #487829).
Diffstat (limited to 'app/xterm/button.c')
-rw-r--r-- | app/xterm/button.c | 336 |
1 files changed, 254 insertions, 82 deletions
diff --git a/app/xterm/button.c b/app/xterm/button.c index 70e8ffc1a..86e739227 100644 --- a/app/xterm/button.c +++ b/app/xterm/button.c @@ -1,4 +1,4 @@ -/* $XTermId: button.c,v 1.306 2009/02/13 21:09:08 tom Exp $ */ +/* $XTermId: button.c,v 1.320 2009/03/27 00:00:56 tom Exp $ */ /* * Copyright 1999-2008,2009 by Thomas E. Dickey @@ -1076,12 +1076,12 @@ DECtoASCII(unsigned ch) */ #if OPT_WIDE_CHARS static Char * -UTF8toLatin1(Char * s, unsigned len, unsigned long *result) +UTF8toLatin1(TScreen * screen, Char * s, unsigned len, unsigned long *result) { static Char *buffer; static Cardinal used; - Char *q; + Char *p, *q; if (len > used) { used = 1 + (2 * len); @@ -1094,9 +1094,11 @@ UTF8toLatin1(Char * s, unsigned len, unsigned long *result) q = buffer; fakePtyData(&data, s, s + len); while (decodeUtf8(&data)) { + Bool fails = False; + Bool extra = False; IChar value = skipPtyData(&data); if (value == UCS_REPL) { - *q++ = '#'; + fails = True; } else if (value < 256) { *q++ = CharOf(value); } else { @@ -1105,13 +1107,33 @@ UTF8toLatin1(Char * s, unsigned len, unsigned long *result) *q++ = (Char) DECtoASCII(eqv); } else { eqv = AsciiEquivs(value); - if (eqv == value) - eqv = '#'; - *q++ = (Char) eqv; + if (eqv == value) { + fails = True; + } else { + *q++ = (Char) eqv; + } if (isWide((wchar_t) value)) - *q++ = ' '; + extra = True; + } + } + + /* + * If we're not able to plug in a single-byte result, insert the + * defaultString (which normally is a single "#", but could be + * whatever the user wants). + */ + if (fails) { + for (p = (Char *) screen->default_string; *p != '\0'; ++p) { + len = (unsigned) (3 + q - buffer); + if (len >= used) { + used = 1 + (2 * len); + allocXtermChars(&buffer, used); + } + *q++ = *p; } } + if (extra) + *q++ = ' '; } *q = 0; *result = (unsigned long) (q - buffer); @@ -1122,64 +1144,208 @@ UTF8toLatin1(Char * s, unsigned len, unsigned long *result) } #endif /* OPT_WIDE_CHARS */ -static Atom * -_SelectionTargets(Widget w) +static char * +parseItem(char *value, char *nextc) { - static Atom *eightBitSelectionTargets = NULL; - TScreen *screen; - int n; + char *nextp = value; + while (*nextp != '\0' && *nextp != ',') { + *nextp = x_toupper(*nextp); + ++nextp; + } + *nextc = *nextp; + *nextp = '\0'; + x_strtrim(value); + + return nextp; +} + +/* + * All of the wanted strings are unique in the first character, so we can + * use simple abbreviations. + */ +static Bool +sameItem(const char *actual, const char *wanted) +{ + Bool result = False; + size_t have = strlen(actual); + size_t need = strlen(wanted); + + if (have != 0 && have <= need) { + if (!strncmp(actual, wanted, have)) { + TRACE(("...matched \"%s\"\n", wanted)); + result = True; + } + } + + return result; +} +/* + * Handle the eightBitSelectTypes or utf8SelectTypes resource values. + */ +static Bool +overrideTargets(Widget w, String value, Atom ** resultp) +{ + Bool override = False; XtermWidget xw; - if ((xw = getXtermWidget(w)) == 0) - return NULL; + if ((xw = getXtermWidget(w)) != 0) { + TScreen *screen = TScreenOf(xw); - screen = TScreenOf(xw); + if (value != 0 && *value != '\0') { + String copied = x_strdup(value); + if (copied != 0) { + Atom *result = 0; + Cardinal count = 1; + int n; + + TRACE(("decoding SelectTypes \"%s\"\n", value)); + for (n = 0; copied[n] != '\0'; ++n) { + if (copied[n] == ',') + ++count; + } + result = (Atom *) XtMalloc(((2 * count) + 1) * sizeof(Atom)); + if (result == NULL) { + TRACE(("Couldn't allocate selection types\n")); + } else { + char nextc = '?'; + char *listp = copied; + count = 0; + do { + char *nextp = parseItem(listp, &nextc); + size_t len = strlen(listp); + + if (len == 0) { + ; + } +#if OPT_WIDE_CHARS + else if (sameItem(listp, "UTF8")) { + result[count++] = XA_UTF8_STRING(XtDisplay(w)); + } +#endif + else if (sameItem(listp, "I18N")) { + if (screen->i18nSelections) { + result[count++] = XA_TEXT(XtDisplay(w)); + result[count++] = XA_COMPOUND_TEXT(XtDisplay(w)); + } + } else if (sameItem(listp, "TEXT")) { + result[count++] = XA_TEXT(XtDisplay(w)); + } else if (sameItem(listp, "COMPOUND_TEXT")) { + result[count++] = XA_COMPOUND_TEXT(XtDisplay(w)); + } else if (sameItem(listp, "STRING")) { + result[count++] = XA_STRING; + } + *nextp++ = nextc; + listp = nextp; + } while (nextc != '\0'); + if (count) { + result[count] = None; + override = True; + *resultp = result; + } else { + XtFree((char *) result); + } + } + } else { + TRACE(("Couldn't allocate copy of selection types\n")); + } + } + } + return override; +} #if OPT_WIDE_CHARS - if (screen->wide_chars) { - static Atom *utf8SelectionTargets = NULL; +static Atom * +allocUtf8Targets(Widget w, TScreen * screen) +{ + Atom **resultp = &(screen->selection_targets_utf8); - if (utf8SelectionTargets == NULL) { - utf8SelectionTargets = (Atom *) XtMalloc(5 * sizeof(Atom)); - if (utf8SelectionTargets == NULL) { - TRACE(("Couldn't allocate utf8SelectionTargets\n")); - return NULL; - } - n = 0; - utf8SelectionTargets[n++] = XA_UTF8_STRING(XtDisplay(w)); + if (*resultp == 0) { + Atom *result; + + if (!overrideTargets(w, screen->utf8_select_types, &result)) { + result = (Atom *) XtMalloc(5 * sizeof(Atom)); + if (result == NULL) { + TRACE(("Couldn't allocate utf-8 selection targets\n")); + } else { + int n = 0; + + result[n++] = XA_UTF8_STRING(XtDisplay(w)); #ifdef X_HAVE_UTF8_STRING - if (screen->i18nSelections) { - utf8SelectionTargets[n++] = XA_TEXT(XtDisplay(w)); - utf8SelectionTargets[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); - } + if (screen->i18nSelections) { + result[n++] = XA_TEXT(XtDisplay(w)); + result[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); + } #endif - utf8SelectionTargets[n++] = XA_STRING; - utf8SelectionTargets[n] = None; + result[n++] = XA_STRING; + result[n] = None; + } } - return utf8SelectionTargets; + + *resultp = result; } + + return *resultp; +} #endif - /* not screen->wide_chars */ - if (eightBitSelectionTargets == NULL) { - eightBitSelectionTargets = (Atom *) XtMalloc(5 * sizeof(Atom)); - if (eightBitSelectionTargets == NULL) { - TRACE(("Couldn't allocate eightBitSelectionTargets\n")); - return NULL; - } - n = 0; +static Atom * +alloc8bitTargets(Widget w, TScreen * screen) +{ + Atom **resultp = &(screen->selection_targets_8bit); + + if (*resultp == 0) { + Atom *result = 0; + + if (!overrideTargets(w, screen->eightbit_select_types, &result)) { + result = (Atom *) XtMalloc(5 * sizeof(Atom)); + if (result == NULL) { + TRACE(("Couldn't allocate 8bit selection targets\n")); + } else { + int n = 0; + #ifdef X_HAVE_UTF8_STRING - eightBitSelectionTargets[n++] = XA_UTF8_STRING(XtDisplay(w)); + result[n++] = XA_UTF8_STRING(XtDisplay(w)); +#endif + if (screen->i18nSelections) { + result[n++] = XA_TEXT(XtDisplay(w)); + result[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); + } + result[n++] = XA_STRING; + result[n] = None; + } + } + + *resultp = result; + } + + return *resultp; +} + +static Atom * +_SelectionTargets(Widget w) +{ + Atom *result; + TScreen *screen; + XtermWidget xw; + + if ((xw = getXtermWidget(w)) == 0) { + result = NULL; + } else { + screen = TScreenOf(xw); + +#if OPT_WIDE_CHARS + if (screen->wide_chars) { + result = allocUtf8Targets(w, screen); + } else #endif - if (screen->i18nSelections) { - eightBitSelectionTargets[n++] = XA_TEXT(XtDisplay(w)); - eightBitSelectionTargets[n++] = XA_COMPOUND_TEXT(XtDisplay(w)); + { + /* not screen->wide_chars */ + result = alloc8bitTargets(w, screen); } - eightBitSelectionTargets[n++] = XA_STRING; - eightBitSelectionTargets[n] = None; } - return eightBitSelectionTargets; + + return result; } #define isSELECT(value) (!strcmp(value, "SELECT")) @@ -1321,14 +1487,16 @@ xtermGetSelection(Widget w, if ((xw = getXtermWidget(w)) == 0) return; - TRACE(("xtermGetSelection\n")); + TRACE(("xtermGetSelection num_params %d\n", num_params)); params = MapSelections(xw, params, num_params); XmuInternStrings(XtDisplay(w), params, (Cardinal) 1, &selection); cutbuffer = CutBuffer(selection); - TRACE(("Cutbuffer: %d, target: %lu\n", cutbuffer, - targets ? (unsigned long) targets[0] : 0)); + TRACE(("Cutbuffer: %d, target: %s\n", cutbuffer, + (targets + ? visibleSelectionTarget(XtDisplay(w), targets[0]) + : "None"))); if (cutbuffer >= 0) { int inbytes; @@ -1618,6 +1786,11 @@ SelectionReceived(Widget w, text_prop.format = *format; text_prop.nitems = *length; + TRACE(("SelectionReceived %s format %d, nitems %ld\n", + visibleSelectionTarget(dpy, text_prop.encoding), + text_prop.format, + text_prop.nitems)); + #if OPT_WIDE_CHARS if (screen->wide_chars) { if (*type == XA_UTF8_STRING(dpy) || @@ -1664,7 +1837,7 @@ SelectionReceived(Widget w, for (i = 0; i < text_list_count; ++i) { data = (Char *) text_list[i]; size = strlen(text_list[i]) + 1; - data = UTF8toLatin1(data, size, &size); + data = UTF8toLatin1(screen, data, size, &size); new_size += size + 1; } new_text_list = @@ -1673,7 +1846,7 @@ SelectionReceived(Widget w, for (i = 0; i < text_list_count; ++i) { data = (Char *) text_list[i]; size = strlen(text_list[i]) + 1; - data = UTF8toLatin1(data, size, &size); + data = UTF8toLatin1(screen, data, size, &size); memcpy(tmp, data, size + 1); new_text_list[i] = tmp; tmp += size + 1; @@ -1737,6 +1910,8 @@ SelectionReceived(Widget w, fail: if (client_data != 0) { struct _SelectionList *list = (struct _SelectionList *) client_data; + + TRACE(("SelectionReceived ->xtermGetSelection\n")); xtermGetSelection(w, list->time, list->params, list->count, list->targets); XtFree((char *) client_data); @@ -3012,15 +3187,14 @@ SaltTextAway(XtermWidget xw, TScreen *screen = TScreenOf(xw); int i, j = 0; int eol; + int tmp; Char *line; Char *lp; CELL first = *cellc; CELL last = *cell; if (isSameRow(&first, &last) && first.col > last.col) { - int tmp = first.col; - first.col = last.col; - last.col = tmp; + EXCHANGE(first.col, last.col, tmp); } --last.col; @@ -3259,6 +3433,9 @@ ConvertSelection(Widget w, if (screen->selection_data == NULL) return False; /* can this happen? */ + TRACE(("ConvertSelection %s\n", + visibleSelectionTarget(dpy, *target))); + if (*target == XA_TARGETS(dpy)) { Atom *allocP; Atom *targetP; @@ -3266,10 +3443,12 @@ ConvertSelection(Widget w, XPointer std_return = 0; unsigned long std_length; - TRACE(("ConvertSelection XA_TARGETS(dpy)\n")); if (XmuConvertStandardSelection(w, screen->selection_time, selection, target, type, &std_return, &std_length, format)) { + Atom *my_targets = _SelectionTargets(w); + + TRACE(("XmuConvertStandardSelection - success\n")); std_targets = (Atom *) (std_return); *length = std_length + 6; @@ -3278,18 +3457,9 @@ ConvertSelection(Widget w, *value = (XtPointer) targetP; - *targetP++ = XA_STRING; - *targetP++ = XA_TEXT(dpy); -#ifdef X_HAVE_UTF8_STRING - *targetP++ = XA_COMPOUND_TEXT(dpy); - *targetP++ = XA_UTF8_STRING(dpy); -#else - *targetP = XA_COMPOUND_TEXT(dpy); - if_OPT_WIDE_CHARS(screen, { - *targetP = XA_UTF8_STRING(dpy); - }); - targetP++; -#endif + while (*my_targets != None) { + *targetP++ = *my_targets++; + } *targetP++ = XA_LENGTH(dpy); *targetP++ = XA_LIST_LENGTH(dpy); @@ -3300,37 +3470,39 @@ ConvertSelection(Widget w, *type = XA_ATOM; *format = 32; result = True; + } else { + TRACE(("XmuConvertStandardSelection - failed\n")); } } #if OPT_WIDE_CHARS else if (screen->wide_chars && *target == XA_STRING) { - TRACE(("ConvertSelection XA_STRING - wide\n")); result = _ConvertSelectionHelper(w, type, value, length, format, Xutf8TextListToTextProperty, XStringStyle); + TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_UTF8_STRING(dpy)) { - TRACE(("ConvertSelection XA_UTF8_STRING(dpy) - wide\n")); result = _ConvertSelectionHelper(w, type, value, length, format, Xutf8TextListToTextProperty, XUTF8StringStyle); + TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_TEXT(dpy)) { - TRACE(("ConvertSelection XA_TEXT(dpy) - wide\n")); result = _ConvertSelectionHelper(w, type, value, length, format, Xutf8TextListToTextProperty, XStdICCTextStyle); + TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } else if (screen->wide_chars && *target == XA_COMPOUND_TEXT(dpy)) { - TRACE(("ConvertSelection XA_COMPOUND_TEXT(dpy) - wide\n")); result = _ConvertSelectionHelper(w, type, value, length, format, Xutf8TextListToTextProperty, XCompoundTextStyle); + TRACE(("...Xutf8TextListToTextProperty:%d\n", result)); } #endif @@ -3341,56 +3513,56 @@ ConvertSelection(Widget w, properly internationalised, and dump raw eight-bit data with no conversion into the selection. Yes, this breaks the ICCCM in non-Latin-1 locales. */ - TRACE(("ConvertSelection XA_STRING\n")); *type = XA_STRING; *value = (XtPointer) screen->selection_data; *length = screen->selection_length; *format = 8; result = True; + TRACE(("...raw 8-bit data:%d\n", result)); } else if (*target == XA_TEXT(dpy)) { /* not wide_chars */ - TRACE(("ConvertSelection XA_TEXT(dpy)\n")); result = _ConvertSelectionHelper(w, type, value, length, format, XmbTextListToTextProperty, XStdICCTextStyle); + TRACE(("...XmbTextListToTextProperty(StdICC):%d\n", result)); } else if (*target == XA_COMPOUND_TEXT(dpy)) { /* not wide_chars */ - TRACE(("ConvertSelection XA_COMPOUND_TEXT(dpy)\n")); result = _ConvertSelectionHelper(w, type, value, length, format, XmbTextListToTextProperty, XCompoundTextStyle); + TRACE(("...XmbTextListToTextProperty(Compound):%d\n", result)); } #ifdef X_HAVE_UTF8_STRING else if (*target == XA_UTF8_STRING(dpy)) { /* not wide_chars */ - TRACE(("ConvertSelection XA_UTF8_STRING(dpy)\n")); result = _ConvertSelectionHelper(w, type, value, length, format, XmbTextListToTextProperty, XUTF8StringStyle); + TRACE(("...XmbTextListToTextProperty(UTF8):%d\n", result)); } #endif else if (*target == XA_LIST_LENGTH(dpy)) { - TRACE(("ConvertSelection XA_LIST_LENGTH(dpy)\n")); result = SaveConvertedLength(value, 1); *type = XA_INTEGER; *length = 1; *format = 32; + TRACE(("...list of values:%d\n", result)); } else if (*target == XA_LENGTH(dpy)) { - TRACE(("ConvertSelection XA_LENGTH(dpy)\n")); /* This value is wrong if we have UTF-8 text */ result = SaveConvertedLength(value, screen->selection_length); *type = XA_INTEGER; *length = 1; *format = 32; + TRACE(("...list of values:%d\n", result)); } else if (XmuConvertStandardSelection(w, screen->selection_time, selection, target, type, (XPointer *) value, length, format)) { - TRACE(("ConvertSelection XmuConvertStandardSelection\n")); result = True; + TRACE(("...XmuConvertStandardSelection:%d\n", result)); } /* else */ @@ -3458,7 +3630,7 @@ _OwnSelection(XtermWidget xw, if (screen->selection_length == 0) return; - TRACE(("_OwnSelection\n")); + TRACE(("_OwnSelection count %d\n", count)); selections = MapSelections(xw, selections, count); if (count > screen->sel_atoms_size) { @@ -3486,7 +3658,7 @@ _OwnSelection(XtermWidget xw, unsigned long length = screen->selection_length; Char *data = screen->selection_data; if_OPT_WIDE_CHARS((screen), { - data = UTF8toLatin1(data, length, &length); + data = UTF8toLatin1(screen, data, length, &length); }); TRACE(("XStoreBuffer(%d)\n", cutbuffer)); XStoreBuffer(XtDisplay((Widget) xw), |