Apparantly, I forgot to attach the patch. Hre si the one.
cghan
diff -urdN xforms-1.0-release/Imakefile xforms-1.0-i18n/Imakefile --- xforms-1.0-release/Imakefile Wed Dec 4 02:25:43 2002 +++ xforms-1.0-i18n/Imakefile Tue Feb 25 19:19:40 2003 @@ -100,7 +100,7 @@ image \ $(GL) \ fdesign \ - fd2ps \ + fd2ps \ $(DEMOS) IMAKE_DEFINES = \ diff -urdN xforms-1.0-release/lib/flinternal.h xforms-1.0-i18n/lib/flinternal.h --- xforms-1.0-release/lib/flinternal.h Tue May 21 04:38:39 2002 +++ xforms-1.0-i18n/lib/flinternal.h Tue Feb 25 19:19:40 2003 @@ -226,6 +226,10 @@ extern void fl_dump_state_info(int, const char *); extern void fl_init_stipples(void); +/* XFontSet loading */ + +extern int use_fontset(void); + /* for fdesign */ const char *fl_query_colorname(FL_COLOR); extern long fl_query_namedcolor(const char *s); @@ -411,10 +415,8 @@ int tooltip_time; #ifdef XlibSpecificationRelease XIM xim ; /* input method */ - XIC xic ; /* input context */ #else void *xim; - void *xic; #endif unsigned int navigate_mask; /* input field */ long reserverd[6]; @@ -490,6 +492,7 @@ #define IsEnd(k) (k==XK_End || k==XK_KP_End) #define IsPageDown(k) (k==XK_Next || k==XK_Page_Down || k==XK_KP_Page_Down) #define IsPageUp(k) (k==XK_Prior || k==XK_Page_Up || k==XK_KP_Page_Up) +#define IsReturn(k) (k==XK_Return || k==XK_KP_Enter) #else #define IsHome(k) (k==XK_Home || k== XK_Begin) #define IsLeft(k) (k==XK_Left) @@ -499,6 +502,7 @@ #define IsEnd(k) (k==XK_End) #define IsPageDown(k) (k==XK_Next) #define IsPageUp(k) (k==XK_Prior) +#define IsReturn(k) (k==XK_Return) #endif #define FL_HALFPAGE_UP 0x10000000 @@ -514,6 +518,15 @@ #define Is1LineUp(k) ((k)==FL_1LINE_UP) #define Is1LineDown(k) ((k)==FL_1LINE_DOWN) +#define IsFLCursorKey(k) (IsHome(k) || IsLeft(k) || \ + IsRight(k) || IsUp(k) || \ + IsDown(k) || IsEnd(k) || \ + IsPageDown(k) || IsPageUp(k) || \ + IsReturn(k) || IsHalfPageUp(k) || \ + IsHalfPageDown(k) || IsNLinesUp(k) || \ + IsNLinesDown(k) || Is1LineUp(k) || \ + Is1LineDown(k)) + extern int fl_convert_shortcut(const char *, long *); extern int fl_get_underline_pos(const char *, const char *); diff -urdN xforms-1.0-release/lib/flresource.c xforms-1.0-i18n/lib/flresource.c --- xforms-1.0-release/lib/flresource.c Sun Jun 2 07:09:37 2002 +++ xforms-1.0-i18n/lib/flresource.c Tue Feb 25 19:19:40 2003 @@ -48,7 +48,7 @@ /* used to have other uses, currently does almost nothing */ extern int fl_check_it(const char *); - +extern int use_fontset(void); static XrmDatabase fldatabase; /* final merged database */ static XrmDatabase cmddb; /* command line database */ static char *fl_app_name, *fl_app_class, *fl_ori_app_name; @@ -952,16 +952,9 @@ { XSetLocaleModifiers(""); /* use the same input method throughout xforms */ - fl_context->xim = XOpenIM(fl_display, 0, 0, 0); - /* also use the same input context */ - if (fl_context->xim) - { - int style = XIMPreeditNothing|XIMStatusNothing; - fl_context->xic = XCreateIC(fl_context->xim, - XNInputStyle, style, - 0); - } + fl_context->xim = XOpenIM(fl_display, 0, 0, 0); } + #endif fl_default_xswa(); fl_init_stipples(); @@ -1037,6 +1030,34 @@ return fl_display; } +/* font_loading */ + +extern int +use_fontset() +{ + char * loc = setlocale(LC_ALL, ""); + + if (!strcmp(loc, "ko_KR") || !strcmp(loc, "ko_KR.eucKR") || + !strcmp(loc, "korean") || !strcmp(loc, "korean_euc") || + !strcmp(loc, "ko_KR.euc") || !strcmp(loc, "ko_KR.euckr") || + !strcmp(loc, "ko") || !strcmp(loc, "ko_KR.EUC") || + !strcmp(loc, "ja_JP.eucJP") || !strcmp(loc, "ja_JP") || + !strcmp(loc, "japanese") || !strcmp(loc, "japanese.euc") || + !strcmp(loc, "ja_JP.ujis") || !strcmp(loc, "ja_JP.SJIS") || + !strcmp(loc, "japanese.sjis") || !strcmp(loc, "zh") || + !strcmp(loc, "zh_CN") || !strcmp(loc, "zh_CN.eucCN") || + !strcmp(loc, "zh_CN.euc") || !strcmp(loc, "zh_CN.Big5") || + !strcmp(loc, "zh_CN.EUC") || !strcmp(loc, "zh_CN.big5") || + !strcmp(loc, "zh_CN.gbk") || !strcmp(loc, "zh_TW") || + !strcmp(loc, "zh_TW.big5") || !strcmp(loc, "zh_TW.Big5") || + !strcmp(loc, "zh_HK") || !strcmp(loc, "zh_HK.big5") || + !strcmp(loc, "zh_CN.GB18030") || !strcmp(loc, "zh_CN.gb18030") || + !strcmp(loc, "zh_HK.Big5") || !strcmp(loc, "zh_TW.eucTW") ) + return 1; + + else return 0; +} + /* * Find out about virtual root. Taken from XFaq */ diff -urdN xforms-1.0-release/lib/forms.c xforms-1.0-i18n/lib/forms.c --- xforms-1.0-release/lib/forms.c Wed Nov 20 06:06:43 2002 +++ xforms-1.0-i18n/lib/forms.c Tue Feb 25 19:19:40 2003 @@ -53,6 +53,7 @@ #define SHORT_PAUSE 10 /* check_form wait */ +#define DEFAULT_FONT_NAME "-*-*-medium-r-normal--14-*-*-*-*-*-*-*" void fl_set_no_connection(int yes) @@ -531,6 +532,113 @@ fl_wintitle(form->window, form->label); } +void +fl_create_xic(FL_FORM * form) +{ + char **missing_list; + int missing_count; + char *def_string; + int k, i = 0; + int found = 0; + XRectangle pre_area; + XPoint location; + XVaNestedList status_list; + XVaNestedList preedit_list; + XIMStyle preedit[]={XIMPreeditPosition,XIMPreeditNothing,0}; + XIMStyle status[]={XIMStatusArea,XIMStatusNothing,0}; + XIMStyles *xim_styles = 0; + XIMStyle input_style; + XFontSet fontset; + + if ( XGetIMValues(fl_context->xim, XNQueryInputStyle, &xim_styles, (char *) 0, (char *) 0) || !xim_styles) { + printf("input method doesn't support any style"); + XCloseIM(fl_context->xim); + return; + } + + while ((preedit[i]!=0)&& (found != 1)) + { + int j = 0; + while((status[j]!=0)&& (found != 1)) + { + for (k = 0;k < xim_styles->count_styles;k++) + { + if ((preedit[i] | status[j])==xim_styles->supported_styles[k]) + { + input_style=xim_styles->supported_styles[k]; + found = 1; + break; + } + } + j++; + } + i++; + } + XFree( (char *)xim_styles ); + + + + fontset = XCreateFontSet(fl_display, DEFAULT_FONT_NAME, &missing_list, + &missing_count, &def_string); + + + pre_area.x = 0; + pre_area.y = 0; + pre_area.width = form->w; + pre_area.height = form->h; + + location.x = form->x; + location.y = form->y; + + status_list = XVaCreateNestedList( 0, + XNFontSet, fontset, + 0); + + preedit_list = XVaCreateNestedList( 0, + XNSpotLocation, &location, + XNFontSet, fontset, + XNArea, &pre_area, + 0); + + if(preedit_list){ + form->xic = XCreateIC(fl_context->xim, + XNInputStyle, input_style, + XNClientWindow, form->window, + XNFocusWindow, form->window, + XNPreeditAttributes, preedit_list, + XNStatusAttributes, status_list, + 0); + + XFree(preedit_list); + XFree(status_list); + }else + form->xic = XCreateIC(fl_context->xim, + XNInputStyle, input_style, + XNClientWindow, form->window, + 0); + if(!form->xic){ + M_err("fl_initialize", "Could not create an input context"); + XCloseIM (fl_context->xim); + return; + } + + if(form->focusobj){ + int imx, imy; + fl_get_CJK_offset(form->focusobj, &imx, &imy); + location.x = imx; + location.y = imy; + } + else { + location.x = 0; + location.y = 0; + } + preedit_list = XVaCreateNestedList( 0, + XNSpotLocation, &location, + 0); + XSetICValues(form->xic, XNPreeditAttributes, preedit_list, (char *) 0); + XFree(preedit_list); + } + /* Displays a particular form. Returns window handle. */ static int has_initial; @@ -543,6 +651,7 @@ long screenw, screenh; int itx = 0, ity = 0, dont_fix_size = 0; FL_Coord mx, my, nmx, nmy; + XSetWindowAttributes st_xswa; if (border == 0) border = FL_FULLBORDER; @@ -734,6 +843,10 @@ if (border == FL_FULLBORDER || (form->prop & FL_COMMAND_PROP)) fl_set_form_property(form, FL_COMMAND_PROP); + + if (fl_context->xim) + fl_create_xic(form); + return form->window; } @@ -793,6 +906,8 @@ else fl_XPutBackEvent(&xev); + +// XDestroyIC(form->xic); } #else /* suspend timeout and IO stuff. need to complete hide_form without @@ -1161,7 +1276,8 @@ } } - M_info("Shortcut", "win=%lu key=%d %d %d", form->window, key, key1, key2); + M_info("Shortcut", "win=%lu key=%d %d %d %d", + form->window, key, key1, key2); /* Check whether an object has this as shortcut. */ for (i = -1; obj1; obj1 = obj1->next, i = -1) @@ -1218,7 +1334,8 @@ } static void -fl_keyboard(FL_FORM * form, int key, FL_Coord x, FL_Coord y, void *xev) +fl_keyboard(int event, + FL_FORM * form, int key, FL_Coord x, FL_Coord y, void *xev) { FL_OBJECT *obj, *obj1, *special; @@ -1228,7 +1345,7 @@ /* focus policy is done as follows: Input object has the highiest priority. Next is the object that wants special keys which is followed - by mouseobj that has the lowest. Focusobj == FL_INPUT OBJ */ + by mouseobj that has the lowest. */ special = fl_find_first(form, FL_FIND_KEYSPECIAL, 0, 0); obj1 = special ? fl_find_object(special->next, FL_FIND_KEYSPECIAL, 0, 0) : 0; @@ -1239,33 +1356,30 @@ if (obj1 && obj1 != special) special = fl_mouseobj; - if (form->focusobj) + /* Focusobj == FL_INPUT OBJ */ + if (event == FL_KEYPRESS && form->focusobj) { FL_OBJECT *focusobj = form->focusobj; + int special_key = 0; - /* handle special keys first */ - if (key > 255) - { - if (IsLeft(key) || IsRight(key) || IsHome(key) || IsEnd(key)) - fl_handle_object(focusobj, FL_KEYBOARD, x, y, key, xev); - else if ((IsUp(key) || IsDown(key) || - IsPageUp(key) || IsPageDown(key)) && - (focusobj->wantkey & FL_KEY_TAB)) - fl_handle_object(focusobj, FL_KEYBOARD, x, y, key, xev); - else if (special && (special->wantkey & FL_KEY_SPECIAL)) - { - /* moving the cursor in input field that does not have focus - looks weird */ - if (special->objclass != FL_INPUT) - fl_handle_object(special, FL_KEYBOARD, x, y, key, xev); + /* Handle positioning keys first. + Let the FL_OBJECT tell us whether it has done anything. */ + if (IsFLCursorKey(key)) { + if (fl_handle_object_direct(focusobj, event, x, y, key, xev)) { + fl_object_qenter(focusobj); + return; + } + + if (special && (special->wantkey & FL_KEY_SPECIAL) && + special->objclass != FL_INPUT && + fl_handle_object_direct(special, event, x, y, key, xev)) { + fl_object_qenter(special); + return; } - else if (key == XK_BackSpace || key == XK_Delete) - fl_handle_object(focusobj, FL_KEYBOARD, x, y, key, xev); - return; } - /* dispatch tab & return switches focus if not FL_KEY_TAB */ - if ((key == 9 || key == 13) && !(focusobj->wantkey & FL_KEY_TAB)) + /* Dispatch tab & return switches focus if not FL_KEY_TAB */ + if ((IsTab(key) || IsReturn(key)) && !(focusobj->wantkey & FL_KEY_TAB)) { if ((((XKeyEvent *) xev)->state & fl_context->navigate_mask)) { @@ -1284,7 +1398,7 @@ fl_handle_object(obj, FL_FOCUS, x, y, 0, xev); } else if (focusobj->wantkey != FL_KEY_SPECIAL) - fl_handle_object(focusobj, FL_KEYBOARD, x, y, key, xev); + fl_handle_object(focusobj, event, x, y, key, xev); return; } @@ -1294,11 +1408,11 @@ /* space is an exception for browser */ if ((key > 255 || key == ' ') && (special->wantkey & FL_KEY_SPECIAL)) - fl_handle_object(special, FL_KEYBOARD, x, y, key, xev); + fl_handle_object(special, event, x, y, key, xev); else if (key < 255 && (special->wantkey & FL_KEY_NORMAL)) - fl_handle_object(special, FL_KEYBOARD, x, y, key, xev); + fl_handle_object(special, event, x, y, key, xev); else if (special->wantkey == FL_KEY_ALL) - fl_handle_object(special, FL_KEYBOARD, x, y, key, xev); + fl_handle_object(special, event, x, y, key, xev); #if FL_DEBUG >= ML_INFO M_info("KeyBoard", "(%d %d)pushing %d to %s\n", x, y, key, special->label); @@ -1424,8 +1538,9 @@ fl_pushobj = NULL; fl_handle_object(obj, FL_RELEASE, xx, yy, key, xev); break; - case FL_KEYBOARD: /* A key was pressed */ - fl_keyboard(form, key, xx, yy, xev); + case FL_KEYPRESS: /* A key was pressed */ + case FL_KEYRELEASE: /* A key was released */ + fl_keyboard(event, form, key, xx, yy, xev); break; case FL_STEP: /* A simple step */ obj1 = fl_find_first(form, FL_FIND_AUTOMATIC, 0, 0); @@ -1506,23 +1621,40 @@ #endif /* } */ +/* These vars are initialised in do_keyboard. + * They are global vars so that we can make them accessible to the outside + * world. CJK users will find them useful. + */ +static int kbuflen; +static char keybuf[256]; + +void fl_get_composed_string(int * ptr_kbuflen, char const ** ptr_keybuf) +{ + + if (!ptr_kbuflen) return; + *ptr_kbuflen = kbuflen; + *ptr_keybuf = keybuf; + +} + /* formevent is either FL_KEYPRESS or FL_KEYRELEASE */ static void do_keyboard(XEvent * xev, int formevent) { - Window win; - int kbuflen; + KeySym keysym = 0; + static KeySym last_pressed_keysym; + unsigned char * ch; - /* before doing anything, save the current modifier key for the handlers */ + /* Before doing anything, save the current modifier key for the handlers. */ win = xev->xkey.window; fl_keymask = xev->xkey.state; if (win && (!keyform || !fl_is_good_form(keyform))) keyform = fl_win_to_form(win); - /* switch keyboard input only if different top-level form */ + /* Switch keyboard input only if different top-level form. */ if (keyform && keyform->window != win) { M_warn("KeyEvent", "pointer/keybd focus differ"); @@ -1533,67 +1665,51 @@ keyform = fl_win_to_form(win); } - if ( keyform ) { - - KeySym keysym = 0; - unsigned char keybuf[227]; + if (!keyform) + return; - kbuflen = fl_XLookupString((XKeyEvent *) xev, (char *) keybuf, - sizeof(keybuf), &keysym); - - if (kbuflen < 0) { - - if ( kbuflen != INT_MIN ) { - - /* buffer overflow, should not happen */ - M_err("DoKeyBoard", "keyboad buffer overflow ?"); - - } else { + /* Note that the behaviour of XmbLookupString is undefined on a KeyRelease + event, so we do not attempt to call fl_XLookupString. + Rather, we store the keysym of the previous FL_KEYPRESS event + and dispatch that. */ + if (formevent == FL_KEYRELEASE) { + fl_handle_form(keyform, FL_KEYRELEASE, last_pressed_keysym, xev); + return; + } - M_err("DoKeyBoard", "fl_XLookupString failed ?"); - - } + memset(keybuf, '\0', sizeof(keybuf)); + + kbuflen = fl_XLookupString((XKeyEvent *) xev, (char *) keybuf, + sizeof(keybuf), &keysym); + if (kbuflen < 0) { + if ( kbuflen != INT_MIN ) { + /* buffer overflow, should not happen */ + M_err("DoKeyBoard", "keyboad buffer overflow ?"); } else { - - /* ignore modifier keys as they don't cause action and are - taken care of by the lookupstring routine */ - - if (IsModifierKey(keysym)) - ; - else if (IsTab(keysym)) { - - /* fake a tab key. */ - /* some system shift+tab does not generate tab */ - - fl_handle_form(keyform, formevent, 9, xev); - - } -#if (FL_DEBUG >= ML_DEBUG ) - else if (keysym == XK_F10) /* && controlkey_down(fl_keymask)) */ - hack_test(); -#endif - - /* pass all keys to the handler */ - else if (IsCursorKey(keysym) || kbuflen == 0) - fl_handle_form(keyform, formevent, keysym, xev); - else { - - unsigned char *ch; - - /* all regular keys, including mapped strings */ - - for (ch = keybuf; ch < (keybuf + kbuflen) && keyform; ch++) - fl_handle_form(keyform, formevent, *ch, xev); - - } - + M_err("DoKeyBoard", "fl_XLookupString failed ?"); } - + return; } + /* keysym == NoSymbol during multi-byte char composition. + Eg, I've typed Multi_key-a but not yet ' to give ? + Silently swallow these partial-compositions. */ + if (keysym == NoSymbol && kbuflen == 0) + return; + + /* Ignore modifier keys as they don't cause action and are + taken care of by the LookupString routine. */ + if (IsModifierKey(keysym)) + return; + + /* Dispatch the key event */ + fl_handle_form(keyform, formevent, keysym, xev); + /* Record the keysym for the next KEYRELEASE event. */ + last_pressed_keysym = keysym; } + FL_FORM_ATCLOSE fl_set_form_atclose(FL_FORM * form, FL_FORM_ATCLOSE fmclose, void *data) { @@ -1860,14 +1976,14 @@ return; case FocusIn: - if (fl_context->xic) +/* if (evform->xic) { M_info("Focus", "Setting focus window for IC"); - XSetICValues(fl_context->xic, + XSetICValues(evform->xic, XNFocusWindow, st_xev.xfocus.window, XNClientWindow, st_xev.xfocus.window, 0); - } + } */ break; case KeyPress: @@ -2785,8 +2901,16 @@ fl_XLookupString(XKeyEvent * xkey, char *buf, int buflen, KeySym * ks) { int len = INT_MIN; + FL_FORM * f; - if (!fl_context->xic) + f = fl_win_to_form(xkey->window); + + /* Note that the behaviour of XmbLookupString is undefined on a KeyRelease + event. Safest therefore to bail out in such a situation. */ +/* if (xkey->type != KeyPress) + return 0; */ + + if (!f->xic) { len = XLookupString(xkey, buf, buflen, ks, 0); } @@ -2800,14 +2924,26 @@ return 0; } - len = - XmbLookupString(fl_context->xic, xkey, buf, buflen, ks, &status); + len = XmbLookupString(f->xic, xkey, buf, buflen, ks, &status); switch (status) { case XBufferOverflow: - len = -len; +// len = -len; break; + case XLookupBoth: + break; + case XLookupChars: + *ks = NoSymbol; + break; + case XLookupKeySym: + len = 0; + break; + case XLookupNone: + *ks = NoSymbol; + len = 0; + break; + default: break; } diff -urdN xforms-1.0-release/lib/include/Basic.h xforms-1.0-i18n/lib/include/Basic.h --- xforms-1.0-release/lib/include/Basic.h Sun Jun 2 08:55:37 2002 +++ xforms-1.0-i18n/lib/include/Basic.h Tue Feb 25 19:19:40 2003 @@ -667,6 +667,12 @@ void (*pre_attach)(struct forms_ *); void *attach_data; int no_tooltip; +#ifdef XlibSpecificationRelease + XIC xic ; /* input context */ +#else + void *xic; +#endif + int reserved[10]; /* future use */ } FL_FORM; @@ -918,8 +924,15 @@ FL_EXPORT void fl_set_app_nomainform( int flag ); - - +FL_EXPORT void fl_get_composed_string( + int * ptr_kbuflen, + char const ** ptr_keybuf + ); +FL_EXPORT void fl_get_CJK_offset( + FL_OBJECT *ob, + int * x, + int * y + ); FL_EXPORT void fl_set_form_callback( FL_FORM *form, FL_FORMCALLBACKPTR callback, diff -urdN xforms-1.0-release/lib/input.c xforms-1.0-i18n/lib/input.c --- xforms-1.0-release/lib/input.c Tue Jun 4 02:57:29 2002 +++ xforms-1.0-i18n/lib/input.c Tue Feb 25 19:19:40 2003 @@ -52,6 +52,8 @@ #define FL_VALIDATE FL_INPUTVALIDATOR #define NL '\n' +#define CURSOR_SIZE 12 + enum { COMPLETE, @@ -107,6 +109,7 @@ int dead_area, attrib; int no_cursor; int field_char; + int CJK_composing; } SPEC; @@ -240,6 +243,40 @@ } } +void fl_get_CJK_offset(FL_OBJECT * ob, int * x, int * y) +{ + *x = 0; + *y = 0; + if (ob && ob->objclass == FL_INPUT) { + FL_Coord xmargin, ymargin; + FL_Coord bw = FL_abs(ob->bw); + SPEC * sp = ob->spec; + GetMargin(ob->boxtype, bw, &xmargin, &ymargin); + + *x = ob->x + sp->max_pixels + xmargin; + *y = ob->y + ob->h/2 + CURSOR_SIZE/2; + } +} + +static void activate_CJK_composition(FL_OBJECT * ob) +{ + XPoint location; + XVaNestedList preedit_list; + int x, y; + + fl_get_CJK_offset(ob, &x, &y); + + location.x = x; + location.y = y; + preedit_list = XVaCreateNestedList( 0, + XNSpotLocation, &location, + 0); + + XSetICValues(ob->form->xic, XNPreeditAttributes, preedit_list, (char *) 0); + + XFree(preedit_list); + +} static void draw_input(FL_OBJECT * ob) @@ -705,7 +742,7 @@ int ret = 1, i, j; int prev = 1; - if (key == kmap.del_prev_char || key == kmap.backspace) + if (key == XK_BackSpace) { prev = -1; if (sp->endrange >= 0) @@ -717,7 +754,7 @@ else ret = 0; } - else if (key == kmap.del_next_char) + else if (key == XK_Delete) { if (sp->endrange >= 0) delete_piece(ob, sp->beginrange, sp->endrange - 1); @@ -815,6 +852,77 @@ return ret; } +static int +draw_char(FL_OBJECT * ob, int key, int startpos) +{ + int ok = FL_VALID; + char * tmpbuf = 0; + int i = 0; + int tmppos = 0; + int tmpxoffset = 0; + SPEC *sp = ob->spec; + int slen = strlen(sp->str); + if (sp->endrange > 0) + { + delete_piece(ob, sp->beginrange, sp->endrange - 1); + slen = strlen(sp->str); + } + + if (sp->maxchars > 0 && slen >= sp->maxchars) + { + ringbell(); + return 0; + } + + if (sp->validate) + { + tmpbuf = fl_strdup(sp->str); + tmppos = sp->position; + tmpxoffset = sp->xoffset; + } + + /* merge the new character */ + for (i = slen + 1; i > sp->position; i--) + sp->str[i] = sp->str[i - 1]; + sp->str[sp->position] = key; + sp->position++; + + if (key == '\n') + { + sp->lines++; + sp->ypos++; + sp->xoffset = 0; + } + else + { + int tmp = get_substring_width(ob, startpos, sp->position); + if (tmp - sp->xoffset > sp->w) + sp->xoffset = tmp - sp->w + H_PAD; + } + + if (sp->validate) + { + ok = sp->validate(ob, tmpbuf, sp->str, key); + + if ((ok & ~FL_RINGBELL) != FL_VALID) + { + strcpy(sp->str, tmpbuf); + sp->position = tmppos; + sp->xoffset = tmpxoffset; + if (key == '\n') + { + sp->lines--; + sp->ypos--; + } + } + + if ((ok & FL_RINGBELL)) + ringbell(); + fl_free(tmpbuf); + } + return 1; +} + /* Handles a key press, returns whether something has changed */ static int handle_key(FL_OBJECT * ob, int key, unsigned kmask) @@ -827,6 +935,14 @@ int oldl = sp->lines; int oldx = sp->xoffset; int oldmax = sp->max_pixels; + int kbuflen; + char const * keybuf; + + if ((ob->type != FL_MULTILINE_INPUT) && + (IsUp(key) || IsDown(key) || IsPageUp(key) || IsPageDown(key))) { + /* Don't want to handle this key. */ + return 0; + } /* Extend field size if required */ slen = strlen(sp->str); @@ -836,7 +952,7 @@ sp->str = (char *) fl_realloc(sp->str, sp->size); } - if (ob->type == FL_MULTILINE_INPUT && key == 13) + if (ob->type == FL_MULTILINE_INPUT && IsReturn(key)) key = NL; /* Compute starting position of current line */ @@ -844,7 +960,7 @@ while (startpos > 0 && sp->str[startpos - 1] != NL) startpos--; - if (controlkey_down(kmask) && key > 255) + if (controlkey_down(kmask)) key |= FL_CONTROL_MASK; if (metakey_down(kmask)) @@ -878,70 +994,26 @@ else if (key == kmap.moveto_prev_page) key = XK_PageUp; - if (IsRegular(key)) /* Normal keys or NL */ - { - int ok = FL_VALID; - char *tmpbuf = 0; - int tmppos = 0, tmpxoffset = 0; - - if (sp->endrange >= 0) - { - delete_piece(ob, sp->beginrange, sp->endrange - 1); - slen = strlen(sp->str); - } - - if (sp->maxchars > 0 && slen >= sp->maxchars) - { - ringbell(); - return 0; - } - - if (sp->validate) - { - tmpbuf = fl_strdup(sp->str); - tmppos = sp->position; - tmpxoffset = sp->xoffset; - } - - /* merge the new character */ - for (i = slen + 1; i > sp->position; i--) - sp->str[i] = sp->str[i - 1]; - sp->str[sp->position] = key; - sp->position++; - - if (key == '\n') - { - sp->lines++; - sp->ypos++; - sp->xoffset = 0; - } - else - { - int tmp = get_substring_width(ob, startpos, sp->position); - if (tmp - sp->xoffset > sp->w) - sp->xoffset = tmp - sp->w + H_PAD; - } + /* ditto for the delete keys */ + if (key == kmap.del_prev_char || key == kmap.backspace) + key == XK_BackSpace; + else if (key == kmap.del_next_char) + key == XK_Delete; - if (sp->validate) - { - ok = sp->validate(ob, tmpbuf, sp->str, key); - if ((ok & ~FL_RINGBELL) != FL_VALID) - { - strcpy(sp->str, tmpbuf); - sp->position = tmppos; - sp->xoffset = tmpxoffset; - if (key == '\n') - { - sp->lines--; - sp->ypos--; - } - } + fl_get_composed_string(&kbuflen, &keybuf); - if ((ok & FL_RINGBELL)) - ringbell(); - fl_free(tmpbuf); - } + if(kbuflen > 1) + { + for (i=0; i<kbuflen; ++i) { + if (!draw_char(ob, keybuf[i], startpos)) + return 0; + } + } + else if (IsRegular(key)) /* Normal keys or NL */ + { + if (!draw_char(ob, key, startpos)) + return 0; } else if (IsCursorKey(key) || key == kmap.moveto_eol || key == kmap.moveto_bol || key == kmap.moveto_prev_word || @@ -956,6 +1028,7 @@ ret = handle_edit(ob, key, slen, startpos, kmask); } + sp->endrange = -1; if (ret) @@ -985,6 +1058,9 @@ fl_redraw_object(sp->input); fl_unfreeze_form(ob->form); + if(use_fontset()) + activate_CJK_composition(ob); + return ret; } @@ -1205,6 +1281,10 @@ } else if (handle_select(mx, my, ob, 0, NORMAL_SELECT)) fl_redraw_object(sp->input); + + if(use_fontset()) + activate_CJK_composition(ob); + break; case FL_DBLCLICK: case FL_TRPLCLICK: @@ -1224,6 +1304,8 @@ ret = (sp->how_return == FL_RETURN_ALWAYS || sp->how_return == FL_RETURN_CHANGED); } + if(use_fontset()) + activate_CJK_composition(ob); break; case FL_FREEMEM: fl_free(((SPEC *) (ob->spec))->str); @@ -1352,8 +1434,9 @@ sp->dummy->spec = sp; sp->input = ob; sp->field_char = ' '; + sp->CJK_composing = 0; - /* can't remember why validated input return is set to RETURN_END + /* can't remember why validated input return is set to RETURN_END but probably with some reason. Wait until 1.0 to reset it */ if (ob->type == FL_FLOAT_INPUT || ob->type == FL_INT_INPUT) @@ -1713,7 +1796,7 @@ } -#define Control(c) ((c) - 'a' + 1) +#define Control(c) ((c) | FL_CONTROL_MASK) #define Meta(c) ((c) | METAMASK) #define Dump(a) fprintf(stderr,"\t%s: %ld(0x%lx)\n",#a,kmap.a,kmap.a) @@ -2240,3 +2323,4 @@ return (obj && (obj->objclass == FL_INPUT)) ? ((SPEC*)(obj->spec))->changed:0; } + diff -urdN xforms-1.0-release/lib/objects.c xforms-1.0-i18n/lib/objects.c --- xforms-1.0-release/lib/objects.c Tue Jun 4 02:58:23 2002 +++ xforms-1.0-i18n/lib/objects.c Tue Feb 25 19:19:40 2003 @@ -1004,7 +1004,7 @@ else if (str[i] >= 'a' && str[i] <= 'z') sc[j++] = str[i] - 'a' + 1 + offset; else if (str[i] == '[') - sc[j++] = 27 + offset; + sc[j++] = XK_Escape + offset; else sc[j++] = str[i] + offset; offset = 0; @@ -1420,17 +1420,56 @@ } /* handle tooltips */ -static void -tooltip_handler(int ID, void *data) +static +FL_OBJECT * get_parent(FL_OBJECT * obj) { - FL_OBJECT *obj = data; + if (obj) { + while (obj->parent && obj->parent != obj) + obj = obj->parent; + } + return obj; +} - if (obj->tooltip && *(obj->tooltip)) - fl_show_tooltip(obj->tooltip, obj->form->x + obj->x, +static +void tooltip_handler(int ID, void *data) +{ + FL_OBJECT * const obj = get_parent(data); + char const * const tooltip = obj->tooltip; + + if (tooltip && *(tooltip)) + fl_show_tooltip(tooltip, obj->form->x + obj->x, obj->form->y + obj->y + obj->h + 1); obj->tipID = 0; } +static +void hide_tooltip(FL_OBJECT * obj, XEvent * xev) +{ + FL_OBJECT * const parent = get_parent(obj); + char const * const tooltip = parent->tooltip; + if (tooltip && *(tooltip)) { + /* If obj is part of a composite widget, it may well be that we're + leaving a child widget but are still within the parent. + If that is the case, we don't want to hide the tooltip at all. */ + int outside_parent = 1; + if (parent != obj && xev) { + int const pointer_x = xev->xmotion.x; + int const pointer_y = xev->xmotion.y; + if (pointer_x >= parent->x && pointer_x <= parent->x + parent->w && + pointer_y >= parent->y && pointer_y <= parent->y + parent->h) + outside_parent = 0; + } + if (outside_parent) { + fl_hide_tooltip(); + if (parent->tipID) { + fl_remove_timeout(parent->tipID); + parent->tipID = 0; + } + } + } +} + + /* handles an event for an object */ static int fl_handle_it(FL_OBJECT * obj, int event, FL_Coord mx, FL_Coord my, int key, @@ -1463,31 +1502,30 @@ switch (event) { case FL_ENTER: - if (obj->tooltip && *(obj->tooltip) && !obj->form->no_tooltip) - obj->tipID = fl_add_timeout(fl_context->tooltip_time, - tooltip_handler, obj); + { + /* We assign the timer to the parent widget in the case of a + composite object as that's the thing that's actually got the tip. */ + FL_OBJECT * const parent = get_parent(obj); + if (!parent->tipID) { + char const * const tooltip = parent->tooltip; + if (tooltip && *(tooltip) && !parent->form->no_tooltip) + parent->tipID = fl_add_timeout(fl_context->tooltip_time, + tooltip_handler, parent); + } obj->belowmouse = 1; break; + } case FL_LEAVE: - if (obj->tooltip && *(obj->tooltip)) - { - fl_hide_tooltip(); - if (obj->tipID) - fl_remove_timeout(obj->tipID); - obj->tipID = 0; - } + hide_tooltip(obj, xev); obj->belowmouse = 0; break; case FL_PUSH: - if (obj->tooltip && *(obj->tooltip)) - { - fl_hide_tooltip(); - if (obj->tipID) - fl_remove_timeout(obj->tipID); - obj->tipID = 0; - } + hide_tooltip(obj, xev); obj->pushed = 1; break; + case FL_KEYPRESS: + hide_tooltip(obj, xev); + break; case FL_RELEASE: if (!obj->radio) obj->pushed = 0; diff -urdN xforms-1.0-release/lib/slider.c xforms-1.0-i18n/lib/slider.c --- xforms-1.0-release/lib/slider.c Fri May 31 01:28:07 2002 +++ xforms-1.0-i18n/lib/slider.c Tue Feb 25 19:19:40 2003 @@ -293,6 +293,7 @@ } static int timdel; +static int max_timdel = 11; static int mpos; /* < 0 below knob, 0 on knob, > 0 above knob */ /* Handle a mouse position change */ @@ -305,7 +306,7 @@ /* mouse on trough */ if (mpos && (sp->rdelta + sp->ldelta) > 0.0f) { - if (timdel++ == 0 || (timdel > 11 && (timdel & 1) == 0)) + if (timdel++ == 0) { if (key == FL_LEFT_MOUSE) newval = sp->val + mpos * sp->ldelta; @@ -313,7 +314,11 @@ newval = sp->val + mpos * sp->rdelta; } else + { + if (timdel > max_timdel) + timdel = 0; return 0; + } } else newval = get_newvalue(ob, mx, my); diff -urdN xforms-1.0-release/lib/textbox.c xforms-1.0-i18n/lib/textbox.c --- xforms-1.0-release/lib/textbox.c Mon May 20 23:35:56 2002 +++ xforms-1.0-i18n/lib/textbox.c Tue Feb 25 19:19:40 2003 @@ -1148,7 +1148,7 @@ return 1; } break; - case FL_KEYBOARD: + case FL_KEYPRESS: return handle_keyboard(ob, key, xev); case FL_RELEASE: sp->lastmy = -1; @@ -1799,7 +1799,7 @@ if (*ev == FL_RELEASE && (*key > FL_MBUTTON3)) { - *ev = FL_KEYBOARD; + *ev = FL_KEYPRESS; if (xev && shiftkey_down((((XButtonEvent *) xev)->state))) { ((XButtonEvent *) xev)->state &= ~ShiftMask; diff -urdN xforms-1.0-release/lib/thumbwheel.c xforms-1.0-i18n/lib/thumbwheel.c --- xforms-1.0-release/lib/thumbwheel.c Mon May 20 23:36:01 2002 +++ xforms-1.0-i18n/lib/thumbwheel.c Tue Feb 25 19:19:40 2003 @@ -222,7 +222,7 @@ sp->oldmx = mx; sp->oldmy = my; return fl_valuator_handle_drag(ob, value); - case FL_KEYBOARD: + case FL_KEYPRESS: value = sp->val; if (IsHome(key)) value = 0.5f * (sp->min + sp->max); diff -urdN xforms-1.0-release/lib/util.c xforms-1.0-i18n/lib/util.c --- xforms-1.0-release/lib/util.c Mon May 20 23:35:57 2002 +++ xforms-1.0-i18n/lib/util.c Tue Feb 25 19:19:40 2003 @@ -84,7 +84,7 @@ { VN(FL_ENTER), VN(FL_LEAVE), VN(FL_PUSH), VN(FL_RELEASE), VN(FL_STEP), VN(FL_SHORTCUT), VN(FL_MOUSE), VN(FL_MOTION), - VN(FL_KEYBOARD), VN(FL_DRAW), VN(FL_FOCUS), VN(FL_UNFOCUS), + VN(FL_KEYPRESS), VN(FL_DRAW), VN(FL_FOCUS), VN(FL_UNFOCUS), VN(FL_FREEMEM), VN(FL_DRAWLABEL), VN(FL_DBLCLICK), VN(FL_OTHER), VN(FL_ATTRIB), VN(-1) diff -urdN xforms-1.0-release/lib/win.c xforms-1.0-i18n/lib/win.c --- xforms-1.0-release/lib/win.c Tue Jun 4 05:25:35 2002 +++ xforms-1.0-i18n/lib/win.c Tue Feb 25 19:19:40 2003 @@ -76,7 +76,7 @@ /* for input method */ - if(fl_context->xic) +// if(fl_context->xic) st_xswa.event_mask |= FocusChangeMask; st_xswa.backing_store = fl_cntl.backingStore; diff -urdN xforms-1.0-release/lib/xpopup.c xforms-1.0-i18n/lib/xpopup.c --- xforms-1.0-release/lib/xpopup.c Tue Jun 4 05:25:18 2002 +++ xforms-1.0-i18n/lib/xpopup.c Tue Feb 25 19:20:13 2003 @@ -1473,6 +1473,11 @@ static void draw_title(Display * d, Drawable w, int x, int y, char *s, int n) { + static XFontSet fset = 0; + static int junk; + char **missing_charset; + int num_missing; + static char *dd; if (!s || !*s) return; @@ -1482,6 +1487,32 @@ 0, FL_SLATEBLUE, tfsize, tfstyle + FL_EMBOSSED_STYLE, s); #else +if(use_fontset()) { + fl_set_font(tfstyle, tfsize); + fl_textcolor(puptcolor); + if(fset == 0) + { + fset = XCreateFontSet(flx->display, + "-*-*-medium-r-normal--14-*-*-*-*-*-*-*", + &missing_charset, &num_missing, &dd); + } + if(fset == 0) + { + M_err("DrawString","Bad fontset"); + exit(0); + } + + XmbDrawString(d, w, fset, flx->textgc, x - 1, y - 1, s, n); + XmbDrawString(d, w, fset, flx->textgc, x, y - 1, s, n); + XmbDrawString(d, w, fset, flx->textgc, x + 1, y - 1, s, n); + XmbDrawString(d, w, fset, flx->textgc, x - 1, y, s, n); + XmbDrawString(d, w, fset, flx->textgc, x + 1, y, s, n); + XmbDrawString(d, w, fset, flx->textgc, x - 1, y + 1, s, n); + XmbDrawString(d, w, fset, flx->textgc, x, y + 1, s, n); + XmbDrawString(d, w, fset, flx->textgc, x + 1, y + 1, s, n); + fl_textcolor(FL_WHITE); + XmbDrawString(d, w, fset, flx->textgc, x, y, s, n); +} else { fl_set_font(tfstyle, tfsize); fl_textcolor(puptcolor); XDrawString(d, w, flx->textgc, x - 1, y - 1, s, n); @@ -1494,6 +1525,7 @@ XDrawString(d, w, flx->textgc, x + 1, y + 1, s, n); fl_textcolor(FL_WHITE); XDrawString(d, w, flx->textgc, x, y, s, n); +} #endif } diff -urdN xforms-1.0-release/lib/xtext.c xforms-1.0-i18n/lib/xtext.c --- xforms-1.0-release/lib/xtext.c Mon May 20 23:35:58 2002 +++ xforms-1.0-i18n/lib/xtext.c Tue Feb 25 19:19:40 2003 @@ -34,6 +34,7 @@ * * */ + #if defined(F_ID) || defined(DEBUG) char *fl_id_xtxt = "$Id: xtext.c,v 1.0 2002/05/08 05:16:30 zhao Release $"; #endif @@ -51,6 +52,9 @@ #define NL 10 #define LINES 1024 +#define DEFAULT_FONT_NAME "-*-*-medium-r-normal--14-*-*-*-*-*-*-*" +#define use_fontset use_fontset() + static char **lines; static int *start; /* start position of these lines */ static int *startx; /* start x-FL_coordinate of these lines */ @@ -88,7 +92,7 @@ /* wrong, but looks nicer */ #define CDELTA (flx->fdesc/3) - +typedef int (*mbDrawString) (Display *, Drawable, XFontSet, GC, int, int, const char *, int); typedef int (*DrawString) (Display *, Drawable, GC, int, int, const char *, int); /* Major text drawing routine @@ -115,7 +119,23 @@ int ulpos; int max_pixels = 0; int cdelta; + static XFontStruct **fs_list; + static char **missing_charset; + static int num_missing; + static char *dd; + XFontSet fset; + mbDrawString XmbdrawString; DrawString XdrawString; + +if (use_fontset) +{ + + fset = XCreateFontSet(flx->display, + DEFAULT_FONT_NAME, &missing_charset, &num_missing, &dd); + XFontsOfFontSet(fset,&fs_list,&missing_charset); + flx->fs = fs_list[0]; +} +//#endif if (!startx) extend_workmem(nlines = LINES); @@ -123,9 +143,12 @@ /* Check whether anything has to be done */ if (curspos != 0 && (str == NULL || str[0] == '\0')) return max_pixels; +if (use_fontset) + XmbdrawString = (mbDrawString) (img ? XmbDrawImageString : XmbDrawString); +else + XdrawString = (DrawString) (img ? XDrawImageString : XDrawString); - XdrawString = (DrawString) (img ? XDrawImageString : XDrawString); - + fl_set_font(style, size); height = flx->fheight - flx->fdesc; @@ -179,7 +202,11 @@ cdelta = CDELTA; for (i = topline; i < endline; i++) { - width = XTextWidth(flx->fs, lines[i], slen[i]); +if (use_fontset) + width = XmbTextEscapement(fset, lines[i], slen[i]); +else + width = XTextWidth(flx->fs, lines[i], slen[i]); + if (width > max_pixels) { max_pixels = width; @@ -231,41 +258,28 @@ #endif lines[i] = newlabel; slen[i] = strlen(lines[i]); - startx[i] += XTextWidth(flx->fs, fl_ul_magic_char, 1) / 2; +if (use_fontset) + startx[i] += XmbTextEscapement(fset, fl_ul_magic_char, 1) / 2; +else + startx[i] += XTextWidth(flx->fs, fl_ul_magic_char, 1) / 2; + } /* Draw it */ fl_textcolor(forecol); -#if 2 - +if (use_fontset) + { + XmbdrawString(flx->display, flx->win, fset, flx->textgc, + (int) startx[i], (int) starty[i], lines[i], slen[i]); + } +else + { XdrawString(flx->display, flx->win, flx->textgc, (int) startx[i], (int) starty[i], lines[i], slen[i]); -#else - { - static XFontSet fset = 0; - static int junk; - char **missing_charset; - int num_missing; - static char *dd; - - if(fset == 0) - { - fset = XCreateFontSet(flx->display, - "-adobe-helvetica-*-r-*--*-100-*-*-*-*-*-1", - &missing_charset, &num_missing, &dd); - } - if(fset == 0) - { - M_err("DrawString","Bad fontset"); - exit(0); - } + } - XmbDrawString(flx->display, flx->win, fset, flx->textgc, - (int) startx[i], (int) starty[i], lines[i], slen[i]); - } -#endif /* setup correct underline color in proper GC */ if (ulpos > 0) @@ -293,19 +307,38 @@ slend = start[i + 1] - 1; else slend = selend; - +if (use_fontset) + { xsel = startx[i] + - XTextWidth(flx->fs, lines[i], slstart - start[i]); + XmbTextEscapement(fset, lines[i], slstart - start[i]); len = slend - slstart; + wsel = XmbTextEscapement(fset, str + slstart, len); + } +else + { + xsel = startx[i] + + XTextWidth(flx->fs, lines[i], slstart - start[i]); + len = slend - slstart; wsel = XTextWidth(flx->fs, str + slstart, len); + } + + if (wsel > w) wsel = w + 1; fl_rectf(xsel, starty[i] - height, wsel, flx->fheight, forecol); fl_textcolor(backcol); - +if(use_fontset) + { + XmbdrawString(flx->display, flx->win, fset, flx->textgc, + xsel, starty[i], str +slstart, len); + } +else + { XdrawString(flx->display, flx->win, flx->textgc, xsel, starty[i], str + slstart, len); + } + } } @@ -318,7 +351,11 @@ ; i--; - tt = XTextWidth(flx->fs, lines[i], curspos - start[i]); +if (use_fontset) + tt = XmbTextEscapement(fset, lines[i], curspos - start[i]); +else + tt = XTextWidth(flx->fs, lines[i], curspos - start[i]); + fl_set_clipping(x, y, w - 2, h); fl_rectf(startx[i] + tt, starty[i] - height, (FL_Coord) 2, flx->fheight, curscol); @@ -353,7 +390,20 @@ int width; /* string width of this line */ const char *line; /* line in which mouse lies */ int xstart; /* start x-FL_coordinate of this line */ - float toppos; /* y-FL_coord of the top line */ + float toppos; /* y-FL_coord of the top line */ + static XFontStruct **fs_list; + static char **missing_charset; + static int num_missing; + static char *dd; + XFontSet fset; +if(use_fontset) + { + + fset = XCreateFontSet(flx->display, + DEFAULT_FONT_NAME, &missing_charset, &num_missing, &dd); + XFontsOfFontSet(fset,&fs_list,&missing_charset); + flx->fs = fs_list[0]; + } /* Check whether anything has to be done */ if (!str || !*str) @@ -399,9 +449,17 @@ *yp = theline + 1; /* Calculate start FL_coordinate of the line */ - +if (use_fontset) + { + width = XmbTextEscapement(fset, (char *) line, + start[theline + 1] - start[theline]); + } +else + { width = XTextWidth(flx->fs, (char *) line, start[theline + 1] - start[theline]); + } + if (horalign == FL_ALIGN_LEFT) xstart = x; else if (horalign == FL_ALIGN_CENTER) @@ -418,6 +476,18 @@ i0 = xpos / flx->fheight + 1; len = start[theline + 1] - start[theline]; +if(use_fontset) +{ + for (i = i0; i < len; i++) + { + if (XmbTextEscapement(fset, line, i) > xpos) + { + *xp = i - 1; + return start[theline] + i - 1; + } + } +} else +{ for (i = i0; i < len; i++) { if (XTextWidth(flx->fs, line, i) > xpos) @@ -426,6 +496,7 @@ return start[theline] + i - 1; } } +} *xp = len; return start[theline + 1] - 1; @@ -655,7 +726,19 @@ char *str = (char *) cstr; int ch = *(str + n); int pre; /* stuff in front of the string, such as ^H */ - + static XFontStruct **fs_list; + static char **missing_charset; + static int num_missing; + static char *dd; + XFontSet fset; +if (use_fontset) + { + fset = XCreateFontSet(flx->display, + DEFAULT_FONT_NAME, &missing_charset, &num_missing, &dd); + XFontsOfFontSet(fset,&fs_list,&missing_charset); + flx->fs = fs_list[0]; + } + if (UL_thickness < 0) XGetFontProperty(flx->fs, XA_UNDERLINE_THICKNESS, &ul_thickness); else @@ -670,9 +753,16 @@ /* if the character is narrow, use the width of g otherwise use the width of D. Of course, if UL_width == proportional, this really does not matter */ - +if (use_fontset) + { + ul_width = XmbTextEscapement(fset, NARROW(ch) ? "h" : "D", 1); + ul_rwidth = XmbTextEscapement(fset, str + n, 1); + } +else + { ul_width = XTextWidth(fs, NARROW(ch) ? "h" : "D", 1); ul_rwidth = XTextWidth(fs, str + n, 1); + } pre = (str[0] == *fl_ul_magic_char); @@ -714,7 +804,21 @@ int ul_width; unsigned long ul_pos, ul_thickness = 0; char *str = (char *) cstr; + static XFontStruct **fs_list; + static char **missing_charset; + static int num_missing; + static char *dd; + XFontSet fset; + +if (use_fontset) + { + fset = XCreateFontSet(flx->display, + DEFAULT_FONT_NAME, &missing_charset, &num_missing, &dd); + XFontsOfFontSet(fset,&fs_list,&missing_charset); + flx->fs = fs_list[0]; + } + if (UL_thickness < 0) XGetFontProperty(flx->fs, XA_UNDERLINE_THICKNESS, &ul_thickness); else @@ -725,7 +829,9 @@ if (!XGetFontProperty(flx->fs, XA_UNDERLINE_POSITION, &ul_pos)) ul_pos = has_desc(str) ? (1 + flx->fdesc) : 1; - +if (use_fontset) + ul_width = XmbTextEscapement(fset, str, n); +else ul_width = XTextWidth(flx->fs, str, n); /* do it */ @@ -742,21 +848,48 @@ int w, tab; const char *p, *q; XFontStruct *fs = fl_get_font_struct(style, size); + XFontStruct *xfs; + mbDrawString XmbdrawString; DrawString XdrawString; - + static XFontStruct **fs_list; + static char **missing_charset; + static int num_missing; + static char *dd; + XFontSet fset; +if (use_fontset) { + fset = XCreateFontSet(flx->display, + DEFAULT_FONT_NAME,&missing_charset, &num_missing, &dd); + XFontsOfFontSet(fset,&fs_list,&missing_charset); + + xfs = fs_list[0]; +} tab = fl_get_tabpixels(fs); +if (use_fontset) + XmbdrawString = (mbDrawString) (img ? XmbDrawImageString : XmbDrawString); +else XdrawString = (DrawString) (img ? XDrawImageString : XDrawString); XSetFont(flx->display, gc, fs->fid); for (w = 0, q = s; *q && (p = strchr(q, '\t')) && (p - s) < len; q = p + 1) { - XdrawString(flx->display, win, gc, x + w, y, (char *) q, p - q); - w += XTextWidth(fs, q, p - q); +if (use_fontset) + { + XmbdrawString(flx->display, win, fset, gc, x + w, y, (char *) q, p - q); + w += XmbTextEscapement(fset, q, p - q); + } +else + { + XdrawString(flx->display, win, gc, x + w, y, (char *) q, p - q); + w += XTextWidth(fs, q, p - q); + } + w = ((w / tab) + 1) * tab; } - +if (use_fontset) + XmbdrawString(flx->display, win, fset, gc, x + w, y, (char *) q, len - (q - s)); +else XdrawString(flx->display, win, gc, x + w, y, (char *) q, len - (q - s)); + return 0; /* w + XTextWidth(fs, q, len - (q - s)); */ } -