diff options
author | mitchell <70453897+667e-11@users.noreply.github.com> | 2014-11-23 17:02:12 -0500 |
---|---|---|
committer | mitchell <70453897+667e-11@users.noreply.github.com> | 2014-11-23 17:02:12 -0500 |
commit | 42c7f7c48991f2d4639534274bb250f6c5171ddb (patch) | |
tree | 36f131575620e688251d817b304a4337980802c9 /src/cdk.patch | |
parent | 1e3a6f5ead9e9638a511ca9f8657991053d47407 (diff) |
Patch CDK for basic UTF-8 support.
The find & replace pane and UI dialogs can now handle UTF-8 characters. The
support is functional, but not perfect. Since the patch only targets the widgets
Textadept uses, it cannot be submitted to upstream CDK for inclusion. It's kind
of a hack anyway.
Diffstat (limited to 'src/cdk.patch')
-rw-r--r-- | src/cdk.patch | 424 |
1 files changed, 369 insertions, 55 deletions
diff --git a/src/cdk.patch b/src/cdk.patch index 20ab9227..ba274dfb 100644 --- a/src/cdk.patch +++ b/src/cdk.patch @@ -1,6 +1,6 @@ -diff -r 9d0780ddcbab binding.c ---- a/binding.c 2011-05-16 18:36:08.000000000 -0400 -+++ b/binding.c 2013-12-18 11:51:43.781198100 -0500 +diff -r c40f79827990 binding.c +--- a/binding.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/binding.c Sun Nov 23 16:45:38 2014 -0500 @@ -1,4 +1,6 @@ #include <cdk_int.h> +#include "termkey.h" @@ -8,7 +8,7 @@ diff -r 9d0780ddcbab binding.c /* * $Author: tom $ -@@ -167,7 +169,47 @@ +@@ -167,7 +169,48 @@ { EObjectType cdktype = ObjTypeOf (obj); CDKOBJS *test = bindableObject (&cdktype, obj); @@ -39,6 +39,7 @@ diff -r 9d0780ddcbab binding.c + case TERMKEY_TYPE_KEYSYM: + result = keysyms[key.code.sym]; + break; ++ case TERMKEY_TYPE_UNKNOWN_CSI: + case TERMKEY_TYPE_MOUSE: + goto retry; + default: @@ -57,19 +58,61 @@ diff -r 9d0780ddcbab binding.c if (result >= 0 && test != 0 -diff -r 9d0780ddcbab cdk.c ---- a/cdk.c Mon Sep 02 13:43:26 2013 -0400 -+++ b/cdk.c Mon Sep 02 13:46:55 2013 -0400 -@@ -1262,7 +1262,7 @@ - * less than the provided word. At this point we will set the index - * to the current position. If 'ret' is greater than 0, then the - * current word is alphabetically greater than the given word. We -- * should return with index, which might contain the last best match. -+ * should return with index, which might contain the last best match. - * If they are equal, then we've found it. - */ - if (ret < 0) -@@ -1334,7 +1334,7 @@ +diff -r c40f79827990 cdk.c +--- a/cdk.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/cdk.c Sun Nov 23 16:45:38 2014 -0500 +@@ -453,6 +453,33 @@ + return (from + (unsigned)(result - base)); + } + ++unsigned int utf8charlen(unsigned char ch) ++{ ++ if (ch < 0x80) { ++ return 1; ++ } else if (ch < 0x80 + 0x40 + 0x20) { ++ return 2; ++ } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { ++ return 3; ++ } else { ++ return 4; ++ } ++} ++ ++size_t utf8strlen(const char *s) ++{ ++ size_t i, len = strlen(s), utf8len = 0; ++ for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) utf8len++; ++ return utf8len; ++} ++ ++int utf8charpos(char *s, int pos) ++{ ++ int i, len = (int)strlen(s), utf8len = 0; ++ for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) if (utf8len++ >= pos) break; ++ return i; ++} ++ + /* + * This function takes a character string, full of format markers + * and translates them into a chtype * array. This is better suited +@@ -472,6 +499,7 @@ + int start; + int used; + int x; ++ char *s; + + (*to) = 0; + *align = LEFT; +@@ -763,7 +791,7 @@ + result[0] = attrib; + } + } +- *to = used; ++ for (from = 0; from < used; from+=utf8charlen(CharOf(result[from]))) (*to)++; + } + else + { +@@ -1334,7 +1362,7 @@ for (x = pathLen - 1; x != 0; --x) { /* Find the last '/' in the pathname. */ @@ -78,7 +121,7 @@ diff -r 9d0780ddcbab cdk.c { strcpy (base, pathname + x + 1); break; -@@ -1361,7 +1361,7 @@ +@@ -1361,7 +1389,7 @@ && (pathLen = strlen (pathname)) != 0) { x = pathLen; @@ -87,9 +130,9 @@ diff -r 9d0780ddcbab cdk.c { dir[x--] = '\0'; } -diff -r 9d0780ddcbab cdk.h ---- a/cdk.h Mon Sep 02 13:43:26 2013 -0400 -+++ b/cdk.h Mon Sep 02 13:46:55 2013 -0400 +diff -r c40f79827990 cdk.h +--- a/cdk.h Sun Nov 23 16:42:21 2014 -0500 ++++ b/cdk.h Sun Nov 23 16:45:38 2014 -0500 @@ -226,6 +226,10 @@ */ typedef enum {vEARLY_EXIT, vESCAPE_HIT, vNORMAL, vNEVER_ACTIVATED, vERROR} EExitType; @@ -141,9 +184,9 @@ diff -r 9d0780ddcbab cdk.h /* * Low-level object drawing -diff -r 9d0780ddcbab cdk_config.h +diff -r c40f79827990 cdk_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/cdk_config.h Mon Sep 02 13:46:55 2013 -0400 ++++ b/cdk_config.h Sun Nov 23 16:45:38 2014 -0500 @@ -0,0 +1,67 @@ +/* include/cdk_config.h. Generated automatically by configure. */ +/* @@ -158,7 +201,7 @@ diff -r 9d0780ddcbab cdk_config.h +#define CDK_CONST /*nothing*/ +#define CDK_CSTRING CDK_CONST char * +#define CDK_CSTRING2 CDK_CONST char * CDK_CONST * -+#define CDK_PATCHDATE 20120323 ++#define CDK_PATCHDATE 20140118 +#define CDK_VERSION "5.0" +#define HAVE_DIRENT_H 1 +#define HAVE_GETBEGX 1 @@ -212,9 +255,9 @@ diff -r 9d0780ddcbab cdk_config.h +#endif + +#endif /* CDK_CONFIG_H */ -diff -r 9d0780ddcbab cdk_util.h ---- a/cdk_util.h Mon Sep 02 13:43:26 2013 -0400 -+++ b/cdk_util.h Mon Sep 02 13:46:55 2013 -0400 +diff -r c40f79827990 cdk_util.h +--- a/cdk_util.h Sun Nov 23 16:42:21 2014 -0500 ++++ b/cdk_util.h Sun Nov 23 16:45:38 2014 -0500 @@ -53,6 +53,10 @@ * SUCH DAMAGE. */ @@ -226,9 +269,24 @@ diff -r 9d0780ddcbab cdk_util.h /* * This beeps at the user. The standard curses beep() does not * flush the stream, so it will only beep until a force is made. -diff -r 9d0780ddcbab cdk_version.h +@@ -280,6 +284,14 @@ + int /* length */, + chtype /* character */); + ++#define HAVE_CDKUTF8 1 ++/* This takes the first byte of a UTF-8 character and returns the length of that character. */ ++unsigned int utf8charlen(unsigned char /* char */); ++/* This returns the length of the UTF-8 string. */ ++size_t utf8strlen(const char * /* string */); ++/** This returns the absolute position in a UTF-8 string of a character position. */ ++int utf8charpos(char * /* string */, int /* pos */); ++ + /* + * This takes a chtype pointer and returns a char pointer. + */ +diff -r c40f79827990 cdk_version.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/cdk_version.h Mon Sep 02 13:46:55 2013 -0400 ++++ b/cdk_version.h Sun Nov 23 16:45:38 2014 -0500 @@ -0,0 +1,56 @@ +/* + * $Id: cdk_version.hin,v 1.2 2012/03/20 22:10:36 tom Exp $ @@ -274,7 +332,7 @@ diff -r 9d0780ddcbab cdk_version.h + */ +#define CDK_VERSION_MAJOR "5" +#define CDK_VERSION_MINOR "0" -+#define CDK_VERSION_PATCH "20120323" ++#define CDK_VERSION_PATCH "20140118" + +/* + * Runtime to return the same version information. @@ -286,9 +344,9 @@ diff -r 9d0780ddcbab cdk_version.h +#endif + +#endif /* CDK_VERSION_H */ -diff -r ea979bb3ae11 cdkscreen.c ---- a/cdkscreen.c Wed Aug 13 13:55:58 2014 -0400 -+++ b/cdkscreen.c Wed Aug 13 16:14:54 2014 -0400 +diff -r c40f79827990 cdkscreen.c +--- a/cdkscreen.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/cdkscreen.c Sun Nov 23 16:45:38 2014 -0500 @@ -180,17 +180,6 @@ ALL_SCREENS *item; CDKSCREEN *screen = 0; @@ -307,10 +365,86 @@ diff -r ea979bb3ae11 cdkscreen.c if ((item = typeMalloc (ALL_SCREENS)) != 0) { if ((screen = typeCalloc (CDKSCREEN)) != 0) -diff -r 9d0780ddcbab entry.c ---- a/entry.c 2013-06-16 09:12:32.000000000 -0400 -+++ b/entry.c 2013-12-17 16:52:52.969973100 -0500 -@@ -332,6 +332,7 @@ +diff -r c40f79827990 draw.c +--- a/draw.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/draw.c Sun Nov 23 16:45:38 2014 -0500 +@@ -338,23 +338,34 @@ + int diff = end - start; + int display = 0; + int x = 0; ++ char *s, *p; ++ attr_t current_attr; ++ short pair; ++ int charlen; + ++ s = chtype2Char (string), p = s + start; ++ wattr_get (window, ¤t_attr, &pair, NULL); // save original attrs ++ wattr_set (window, (string[x] & ~A_CHARTEXT) | attr, pair, NULL); // set new attrs + if (align == HORIZONTAL) + { + /* Draw the message on a horizontal axis. */ + display = MINIMUM (diff, getmaxx (window) - xpos); +- for (x = 0; x < display; x++) ++ for (x = 0; x < display; x++, p+=charlen) + { +- (void)mvwaddch (window, ypos, xpos + x, string[x + start] | attr); ++ charlen = utf8charlen(*p); ++ (void)mvwaddnstr (window, ypos, xpos + x, (const char *)p, charlen); + } + } + else + { + /* Draw the message on a vertical axis. */ + display = MINIMUM (diff, getmaxy (window) - ypos); +- for (x = 0; x < display; x++) ++ for (x = 0; x < display; x++, p+=charlen) + { +- (void)mvwaddch (window, ypos + x, xpos, string[x + start] | attr); ++ charlen = utf8charlen(p); ++ (void)mvwaddnstr (window, ypos + x, xpos, (const char *)p, charlen); + } + } ++ wattr_set (window, current_attr, pair, NULL); // restore original attrs ++ freeChar (s); + } +diff -r c40f79827990 entry.c +--- a/entry.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/entry.c Sun Nov 23 16:45:38 2014 -0500 +@@ -223,13 +223,13 @@ + int stringLen; + int charCount; + +- stringLen = (int)strlen (entry->info); ++ stringLen = (int)utf8strlen (entry->info); + if (stringLen >= entry->fieldWidth) + { + if (stringLen < entry->max) + { + charCount = entry->fieldWidth - 1; +- entry->leftChar = stringLen - charCount; ++ entry->leftChar = stringLen - charCount; // horizontal scrolling with UTF8 does not work + entry->screenCol = charCount; + } + else +@@ -245,6 +245,8 @@ + } + } + ++inline int isUtf8CharPart(unsigned int ch) { return (ch >= 0x80) && (ch < 0xc0); } ++ + /* + * This injects a single character into the widget. + */ +@@ -284,7 +286,7 @@ + else + { + int infoLength = (int)strlen (widget->info); +- int currPos = widget->screenCol + widget->leftChar; ++ int currPos = utf8charpos (widget->info, widget->screenCol) + widget->leftChar; + + switch (input) + { +@@ -332,6 +334,7 @@ else { wmove (widget->fieldWin, 0, --widget->screenCol); @@ -318,7 +452,7 @@ diff -r 9d0780ddcbab entry.c } break; -@@ -350,6 +351,7 @@ +@@ -350,6 +353,7 @@ { /* Move right. */ wmove (widget->fieldWin, 0, ++widget->screenCol); @@ -326,9 +460,146 @@ diff -r 9d0780ddcbab entry.c } break; -diff -r 9d0780ddcbab fselect.c ---- a/fselect.c Mon Sep 02 13:43:26 2013 -0400 -+++ b/fselect.c Mon Sep 02 13:46:55 2013 -0400 +@@ -364,20 +368,25 @@ + bool success = FALSE; + + if (input == KEY_BACKSPACE) ++ { ++ while (currPos >= 1 && isUtf8CharPart(CharOf(widget->info[currPos - 1]))) currPos--; + --currPos; ++ } + + if (currPos >= 0 && infoLength > 0) + { + if (currPos < infoLength) + { ++ int len = utf8charlen(widget->info[currPos]); + for (x = currPos; x < infoLength; x++) + { +- widget->info[x] = widget->info[x + 1]; ++ widget->info[x] = widget->info[x + len]; + } + success = TRUE; + } + else if (input == KEY_BACKSPACE) + { ++ while (infoLength >= 1 && isUtf8CharPart(CharOf(widget->info[infoLength - 1]))) infoLength--; + widget->info[infoLength - 1] = '\0'; + success = TRUE; + } +@@ -551,6 +560,23 @@ + } + } + ++static void toutf8(int code, char *s, int *len) { ++ int b; ++ if (code < 0x80) *len = 1; ++ else if (code < 0x800) *len = 2; ++ else if (code < 0x10000) *len = 3; ++ else if (code < 0x200000) *len = 4; ++ else if (code < 0x4000000) *len = 5; ++ else *len = 6; ++ for (b = *len - 1; b > 0; b--) s[b] = 0x80 | (code & 0x3F), code >>= 6; ++ if (*len == 1) s[0] = code & 0x7F; ++ else if (*len == 2) s[0] = 0xC0 | (code & 0x1F); ++ else if (*len == 3) s[0] = 0xE0 | (code & 0x0F); ++ else if (*len == 4) s[0] = 0xF0 | (code & 0x07); ++ else if (*len == 5) s[0] = 0xF8 | (code & 0x03); ++ else if (*len == 6) s[0] = 0xFC | (code & 0x01); ++} ++ + /* + * This is a generic character parser for the entry field. It is used as a + * callback function, so any personal modifications can be made by creating +@@ -558,38 +584,42 @@ + */ + static void CDKEntryCallBack (CDKENTRY *entry, chtype character) + { +- int plainchar = filterByDisplayType (entry->dispType, character); ++ int plainchar = character; + size_t temp; ++ char utf8[6]; ++ int len; + + if (plainchar == ERR || +- ((int)strlen (entry->info) >= entry->max)) ++ ((int)utf8strlen (entry->info) >= entry->max)) + { + Beep (); + } + else + { ++ toutf8(plainchar, utf8, &len); + /* Update the screen and pointer. */ + if (entry->screenCol != entry->fieldWidth - 1) + { + int x; ++ int pos = utf8charpos (entry->info, entry->screenCol) + entry->leftChar; + +- for (x = (int)strlen (entry->info); +- x > (entry->screenCol + entry->leftChar); ++ for (x = (int)strlen (entry->info) + len - 1; ++ x > pos + len - 1; + x--) + { +- entry->info[x] = entry->info[x - 1]; ++ entry->info[x] = entry->info[x - len]; + } +- entry->info[entry->screenCol + entry->leftChar] = (char)plainchar; ++ strncpy(entry->info + pos, utf8, len); + entry->screenCol++; + } + else + { + /* Update the character pointer. */ + temp = strlen (entry->info); +- entry->info[temp] = (char)plainchar; +- entry->info[temp + 1] = '\0'; ++ strncpy(entry->info + temp, utf8, len); ++ entry->info[temp + len] = '\0'; + /* Do not update the pointer if it's the last character */ +- if ((int)(temp + 1) < entry->max) ++ if ((int)(temp + len + 1) < entry->max) + entry->leftChar++; + } + +@@ -660,6 +690,8 @@ + { + int infoLength = 0; + int x = 0; ++ char *p; ++ int charlen; + + /* Draw in the filler characters. */ + (void)mvwhline (entry->fieldWin, 0, x, entry->filler, entry->fieldWidth); +@@ -667,7 +699,7 @@ + /* If there is information in the field. Then draw it in. */ + if (entry->info != 0) + { +- infoLength = (int)strlen (entry->info); ++ infoLength = (int)utf8strlen (entry->info); + + /* Redraw the field. */ + if (isHiddenDisplayType (entry->dispType)) +@@ -679,10 +711,12 @@ + } + else + { +- for (x = entry->leftChar; x < infoLength; x++) ++ p = entry->info + entry->leftChar; ++ for (x = entry->leftChar; x < infoLength; x++, p+=charlen) + { +- (void)mvwaddch (entry->fieldWin, 0, x - entry->leftChar, +- CharOf (entry->info[x]) | entry->fieldAttr); ++ charlen = utf8charlen(CharOf (*p)); ++ (void)mvwaddnstr (entry->fieldWin, 0, x - entry->leftChar, ++ (const char *)p, charlen); + } + } + wmove (entry->fieldWin, 0, entry->screenCol); +diff -r c40f79827990 fselect.c +--- a/fselect.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/fselect.c Sun Nov 23 16:45:38 2014 -0500 @@ -1104,7 +1104,7 @@ static char *make_pathname (const char *directory, const char *filename) @@ -354,8 +625,8 @@ diff -r 9d0780ddcbab fselect.c } /* -diff -r 9d0780ddcbab gen-scale.c ---- a/gen-scale.c Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 gen-scale.c +--- a/gen-scale.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,816 +0,0 @@ -#include <cdk_int.h> @@ -1174,8 +1445,8 @@ diff -r 9d0780ddcbab gen-scale.c -dummyRefreshData (<MIXED>) - -dummySaveData (<MIXED>) -diff -r 9d0780ddcbab gen-scale.h ---- a/gen-scale.h Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 gen-scale.h +--- a/gen-scale.h Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/* @@ -1411,8 +1682,8 @@ diff -r 9d0780ddcbab gen-scale.h - -#endif /* CDK<UPPER>_H */ -#endif /* CDKINCLUDES */ -diff -r 9d0780ddcbab gen-slider.c ---- a/gen-slider.c Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 gen-slider.c +--- a/gen-slider.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,871 +0,0 @@ -#include <cdk_int.h> @@ -2286,8 +2557,8 @@ diff -r 9d0780ddcbab gen-slider.c -dummyRefreshData (<MIXED>) - -dummySaveData (<MIXED>) -diff -r 9d0780ddcbab gen-slider.h ---- a/gen-slider.h Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 gen-slider.h +--- a/gen-slider.h Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/* @@ -2523,8 +2794,51 @@ diff -r 9d0780ddcbab gen-slider.h - -#endif /* CDK<UPPER>_H */ -#endif /* CDKINCLUDES */ -diff -r 9d0780ddcbab matrix.c ---- a/matrix.c Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 itemlist.c +--- a/itemlist.c Sun Nov 23 16:42:21 2014 -0500 ++++ b/itemlist.c Sun Nov 23 16:45:38 2014 -0500 +@@ -449,6 +449,8 @@ + int currentItem = itemlist->currentItem; + int len; + int x; ++ char *s, *p; ++ int charlen; + + /* Determine how much we have to draw. */ + len = MINIMUM (itemlist->itemLen[currentItem], itemlist->fieldWidth); +@@ -456,19 +458,25 @@ + /* Erase the field window. */ + werase (itemlist->fieldWin); + ++ s = chtype2Char (itemlist->item[currentItem]), p = s; + /* Draw in the current item in the field. */ +- for (x = 0; x < len; x++) ++ for (x = 0; x < len; x++, p+=charlen) + { +- chtype c = itemlist->item[currentItem][x]; ++ charlen = utf8charlen(*p); + + if (highlight) + { +- c = CharOf (c) | A_REVERSE; ++ wattron(itemlist->fieldWin, A_REVERSE); + } + +- (void)mvwaddch (itemlist->fieldWin, 0, ++ (void)mvwaddnstr (itemlist->fieldWin, 0, + x + itemlist->itemPos[currentItem], +- c); ++ (const char *)p, charlen); ++ ++ if (highlight) ++ { ++ wattroff(itemlist->fieldWin, A_REVERSE); ++ } + } + + /* Redraw the field window. */ +diff -r c40f79827990 matrix.c +--- a/matrix.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1861 +0,0 @@ -#include <cdk_int.h> @@ -4388,8 +4702,8 @@ diff -r 9d0780ddcbab matrix.c -dummyRefreshData (Matrix) - -dummySaveData (Matrix) -diff -r 9d0780ddcbab view_info.c ---- a/view_info.c Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 view_info.c +--- a/view_info.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -#include <cdk_int.h> @@ -4437,8 +4751,8 @@ diff -r 9d0780ddcbab view_info.c - destroyCDKViewer (viewer); - return selected; -} -diff -r 9d0780ddcbab viewer.c ---- a/viewer.c Mon Sep 02 13:43:26 2013 -0400 +diff -r c40f79827990 viewer.c +--- a/viewer.c Sun Nov 23 16:42:21 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1293 +0,0 @@ -#include <cdk_int.h> |