*** src/command.c.orig Tue Oct 27 00:16:37 1998 --- src/command.c Thu Nov 5 21:20:34 1998 *************** *** 76,83 **** #endif /* OFFIX_DND */ #ifndef NO_XLOCALE - static char rs_inputMethod[] = ""; /* XtNinputMethod */ - static char *rs_preeditType = NULL; /* XtNpreeditType */ static XIC Input_Context; /* input context */ #endif /* NO_XLOCALE */ --- 76,81 ---- *************** *** 290,296 **** ttydev = tty_name; # define PTYCHAR1 "pqrstuvwxyz" ! # define PTYCHAR2 "0123456789abcdef" for (c1 = (char *) PTYCHAR1; *c1; c1++) { ptydev[len - 2] = ttydev[len - 2] = *c1; for (c2 = (char *) PTYCHAR2; *c2; c2++) { --- 288,294 ---- ttydev = tty_name; # define PTYCHAR1 "pqrstuvwxyz" ! # define PTYCHAR2 "0123456789abcdefghijklmnopqrstuv" for (c1 = (char *) PTYCHAR1; *c1; c1++) { ptydev[len - 2] = ttydev[len - 2] = *c1; for (c2 = (char *) PTYCHAR2; *c2; c2++) { *************** *** 892,898 **** DndSelection = XInternAtom(Xdisplay, "DndSelection", False); #endif /* OFFIX_DND */ ! init_xlocale(); /* get number of available file descriptors */ #ifdef _POSIX_VERSION --- 890,898 ---- DndSelection = XInternAtom(Xdisplay, "DndSelection", False); #endif /* OFFIX_DND */ ! #ifndef NO_XLOCALE ! XRegisterIMInstantiateCallback(Xdisplay, NULL, NULL, NULL, IMInstantiateCallback, NULL); ! #endif /* get number of available file descriptors */ #ifdef _POSIX_VERSION *************** *** 933,1056 **** * This is more or less stolen straight from XFree86 xterm. * This should support all European type languages. */ ! /* INTPROTO */ void init_xlocale(void) { ! #ifndef NO_XLOCALE ! char *p, *s, *tmp, buf[32]; ! XIM xim = NULL; ! XIMStyle input_style = 0; ! XIMStyles *xim_styles = NULL; ! int found; ! ! Input_Context = NULL; ! tmp = MALLOC(1024); ! ! # if !defined(NO_XSETLOCALE) || !defined(NO_SETLOCALE) setlocale(LC_CTYPE, ""); # endif ! if (rs_inputMethod == NULL || !*rs_inputMethod) { ! if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) ! xim = XOpenIM(Xdisplay, NULL, NULL, NULL); ! } else { ! STRNCPY(tmp, rs_inputMethod, 1023); ! tmp[1023] = '\0'; ! for (s = tmp; *s; s++) { ! char *end, *next_s; ! ! for (; *s && isspace(*s); s++) ! /* */ ; ! if (!*s) ! break; ! for (end = s; (*end && (*end != ',')); end++) ! /* */ ; ! for (next_s = end--; ((end >= s) && isspace(*end)); end--) ! /* */ ; ! *++end = '\0'; ! if (*s) { ! STRCPY(buf, "@im="); ! strcat(buf, s); ! if ((p = XSetLocaleModifiers(buf)) != NULL && *p && ! (xim = XOpenIM(Xdisplay, NULL, NULL, NULL)) != NULL) ! break; ! } ! if (!*(s = next_s)) ! break; ! } ! } ! ! if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p) ! xim = XOpenIM(Xdisplay, NULL, NULL, NULL); ! ! if (xim == NULL) { ! print_error("Failed to open input method"); ! FREE(tmp); ! return; ! } ! if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles) { ! print_error("input method doesn't support any style"); ! XCloseIM(xim); ! FREE(tmp); ! return; ! } ! STRNCPY(tmp, (rs_preeditType ? rs_preeditType : "Root"), 1023); ! for (found = 0, s = tmp; *s && !found; ) { ! unsigned short i; ! char *end, *next_s; ! ! for (; *s && isspace(*s); s++) ! /* */ ; ! if (!*s) ! break; ! for (end = s; (*end && (*end != ',')); end++) ! /* */ ; ! for (next_s = end--; ((end >= s) && isspace(*end));) ! *end-- = 0; ! ! if (!strcmp(s, "OverTheSpot")) ! input_style = (XIMPreeditPosition | XIMStatusArea); ! else if (!strcmp(s, "OffTheSpot")) ! input_style = (XIMPreeditArea | XIMStatusArea); ! else if (!strcmp(s, "Root")) ! input_style = (XIMPreeditNothing | XIMStatusNothing); ! ! for (i = 0; i < xim_styles->count_styles; i++) ! if (input_style == xim_styles->supported_styles[i]) { ! found = 1; ! break; ! } ! s = next_s; ! } ! XFree(xim_styles); ! FREE(tmp); ! ! if (found == 0) { ! print_error("input method doesn't support my preedit type"); ! XCloseIM(xim); ! return; ! } ! /* ! * This program only understands the Root preedit_style yet ! * Then misc.preedit_type should default to: ! * "OverTheSpot,OffTheSpot,Root" ! * /MaF ! */ ! if (input_style != (XIMPreeditNothing | XIMStatusNothing)) { ! print_error("This program only supports the \"Root\" preedit type"); ! XCloseIM(xim); ! return; ! } ! Input_Context = XCreateIC(xim, XNInputStyle, input_style, ! XNClientWindow, TermWin.parent, ! XNFocusWindow, TermWin.parent, ! NULL); ! ! if (Input_Context == NULL) { ! print_error("Failed to create input context"); ! XCloseIM(xim); ! } ! #endif /* NO_XLOCALE */ } /*}}} */ --- 933,950 ---- * This is more or less stolen straight from XFree86 xterm. * This should support all European type languages. */ ! /* EXTPROTO */ void init_xlocale(void) { ! #ifdef MULTICHAR_SET ! # ifdef KANJI ! setlocale(LC_CTYPE, "ja_JP.EUC"); ! # else setlocale(LC_CTYPE, ""); # endif ! #endif ! setTermFontSet(); } /*}}} */ *************** *** 1118,1137 **** PrivMode((!numlock_state), PrivMode_aplKP); } #ifndef NO_XLOCALE ! if (!XFilterEvent(ev, *(&ev->xkey.window))) { ! if (Input_Context != NULL) { ! Status status_return; ! ! len = XmbLookupString(Input_Context, &ev->xkey, kbuf, ! sizeof(kbuf), &keysym, ! &status_return); ! } else { ! len = XLookupString(&ev->xkey, kbuf, ! sizeof(kbuf), &keysym, ! &compose); ! } ! } else ! len = 0; #else /* NO_XLOCALE */ len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, &compose); /* --- 1012,1030 ---- PrivMode((!numlock_state), PrivMode_aplKP); } #ifndef NO_XLOCALE ! len = 0; ! if (Input_Context != NULL) { ! Status status_return; ! ! kbuf[0] = '\0'; ! len = XmbLookupString(Input_Context, &ev->xkey, kbuf, ! sizeof(kbuf), &keysym, ! &status_return); ! } else { ! len = XLookupString(&ev->xkey, kbuf, ! sizeof(kbuf), &keysym, ! &compose); ! } #else /* NO_XLOCALE */ len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, &compose); /* *************** *** 1698,1708 **** for (;;) { v_doPending(); /* output any pending chars */ while (XPending(Xdisplay)) { /* process pending X events */ - XEvent ev; - refreshed = 0; ! XNextEvent(Xdisplay, &ev); ! process_x_event(&ev); /* in case button actions pushed chars to cmdbuf */ if (cmdbuf_ptr < cmdbuf_endp) --- 1591,1598 ---- for (;;) { v_doPending(); /* output any pending chars */ while (XPending(Xdisplay)) { /* process pending X events */ refreshed = 0; ! XProcessEvent(Xdisplay); /* in case button actions pushed chars to cmdbuf */ if (cmdbuf_ptr < cmdbuf_endp) *************** *** 1775,1780 **** --- 1665,1673 ---- refreshed = 1; scr_refresh(refresh_type); scrollbar_show(1); + #ifndef NO_XLOCALE + IMSendSpot(); + #endif } } } *************** *** 2307,2312 **** --- 2200,2208 ---- scr_refresh(refresh_type); refresh_count = refresh_limit = 0; scrollbar_show(1); + #ifndef NO_XLOCALE + IMSendSpot(); + #endif } break; } *************** *** 3146,3151 **** --- 3042,3050 ---- } } Gr_do_graphics(cmd, nargs, args, text); + # ifndef NO_XLOCALE + IMSendSpot(); + # endif #endif } /*}}} */ *************** *** 3384,3389 **** --- 3283,3556 ---- v_buffer = v_bufstr - start; /* restore clobbered pointer */ } } + } + + #ifndef NO_XLOCALE + /* INTPROTO */ + void + setSize( XRectangle *size ) + { + size->x = TermWin_internalBorder ; + size->y = TermWin_internalBorder ; + size->width = Width2Pixel ( TermWin.ncol ) ; + size->height = Height2Pixel( TermWin.nrow ) ; + return ; + } + + /* INTPROTO */ + void + setColor( unsigned long *fg, unsigned long *bg ) + { + *fg = PixColors[ Color_fg ] ; + *bg = PixColors[ Color_bg ] ; + return ; + } + + /* INTPROTO */ + void + IMSendSpot( void ) + { + XPoint spot ; + XVaNestedList preedit_attr ; + XIMStyle input_style; + + if( Input_Context == NULL ) + return ; + else { + XGetICValues(Input_Context,XNInputStyle,&input_style,NULL); + if (!(input_style & XIMPreeditPosition)) + return; + } + setPosition( &spot ) ; + + preedit_attr = XVaCreateNestedList( 0, XNSpotLocation, &spot, NULL ) ; + XSetICValues( Input_Context, XNPreeditAttributes, preedit_attr, NULL ) ; + XFree( preedit_attr ) ; + return ; + } + + /* INTPROTO */ + void + setTermFontSet( void ) + { + char *string ; + long length, i ; + + if( TermWin.fontset != NULL ){ + XFreeFontSet( Xdisplay, TermWin.fontset ) ; + TermWin.fontset = NULL ; + } + + length = 0 ; + for( i = 0 ; i < NFONTS ; i ++ ){ + if( rs[ Rs_font + i ] ) + length += strlen( rs[ Rs_font + i ] ) + 1 ; + # ifdef MULTICHAR_SET + if( rs[ Rs_mfont + i ] ) + length += strlen( rs[ Rs_mfont + i ] ) + 1 ; + # endif + } + if( ( string = malloc( length ) ) != NULL ){ + char **missing_charsetlist, *def_string ; + int missing_charsetcount ; + + string[ 0 ] = '\0' ; + for( i = 0 ; i < NFONTS ; i ++ ){ + if( rs[ Rs_font + i ] ){ + strcat( string, rs[ Rs_font + i ] ) ; + strcat( string, "," ) ; + } + # ifdef MULTICHAR_SET + if( rs[ Rs_mfont + i ] ){ + strcat( string, rs[ Rs_mfont + i ] ) ; + strcat( string, "," ) ; + } + # endif + } + length = strlen( string ) ; + if( length > 0 && string[ length - 1 ] == ',' ){ + string[ length - 1 ] = '\0' ; + length -- ; + } + if( length > 0 ){ + TermWin.fontset = XCreateFontSet + ( Xdisplay, string, + &missing_charsetlist, &missing_charsetcount, &def_string ) ; + } + free( string ) ; + } else { + TermWin.fontset = NULL ; + } + return ; + } + + /* INTPROTO */ + void + IMDestroyCallback(XIM xim, XPointer client_data, XPointer call_data) + { + Input_Context = NULL; + XRegisterIMInstantiateCallback(Xdisplay, NULL, NULL, NULL, IMInstantiateCallback, NULL); + } + + /* INTPROTO */ + void + IMInstantiateCallback(Display *display, XPointer client_data, XPointer call_data) + { + char *p, *s, buf[32], tmp[1024]; + XIM xim = NULL; + XIMStyle input_style = 0; + XIMStyles *xim_styles = NULL; + int found; + XPoint spot ; + XRectangle rect ; + unsigned long fg, bg ; + XVaNestedList preedit_attr = NULL ; + XIMCallback ximcallback; + + if (Input_Context) return; + + ximcallback.callback = IMDestroyCallback; + ximcallback.client_data = NULL; + + if (rs[Rs_inputMethod] == NULL + # ifdef KANJI + || !rs[Rs_inputMethod] /* required ? */ + # endif + ) { + if ((p = XSetLocaleModifiers("")) != NULL && *p) + xim = XOpenIM(Xdisplay, NULL, NULL, NULL); + } else { + strcpy(tmp, rs[Rs_inputMethod]); + for (s = tmp; *s; /*nil */ ) { + char *end, *next_s; + + while (*s && isspace(*s)) + s++; + if (!*s) + break; + end = s; + while (*end && (*end != ',')) + end++; + next_s = end--; + while ((end >= s) && isspace(*end)) + end--; + *(end + 1) = '\0'; + + if (*s) { + strcpy(buf, "@im="); + strcat(buf, s); + if ((p = XSetLocaleModifiers(buf)) != NULL && *p && + (xim = XOpenIM(Xdisplay, NULL, NULL, NULL)) != NULL) + break; + } + if (!*next_s) + break; + s = (next_s + 1); + } + } + + if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p) + xim = XOpenIM(Xdisplay, NULL, NULL, NULL); + + if (xim == NULL) { + return; + } + + XSetIMValues(xim, XNDestroyCallback, &ximcallback, NULL); + + if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles) { + print_error("input method doesn't support any style"); + XCloseIM(xim); + return; + } + + strcpy(tmp, (rs[Rs_preeditType] ? rs[Rs_preeditType] : "OverTheSpot")); + for (found = 0, s = tmp; *s && !found; /*nil */ ) { + unsigned short i; + char *end, *next_s; + + while (*s && isspace(*s)) + s++; + if (!*s) + break; + end = s; + while (*end && (*end != ',')) + end++; + next_s = end--; + while ((end >= s) && isspace(*end)) + *end-- = 0; + + if (!strcmp(s, "OverTheSpot")) + input_style = (XIMPreeditPosition | XIMStatusNothing); + else if (!strcmp(s, "OffTheSpot")) + input_style = (XIMPreeditArea | XIMStatusArea); + else if (!strcmp(s, "Root")) + input_style = (XIMPreeditNothing | XIMStatusNothing); + + for (i = 0; i < xim_styles->count_styles; i++) { + if (input_style == xim_styles->supported_styles[i]) { + found = 1; + break; + } + } + s = next_s; + } + XFree(xim_styles); + + if (found == 0) { + print_error("input method doesn't support my preedit type"); + XCloseIM(xim); + return; + } + + if ((input_style != (XIMPreeditNothing | XIMStatusNothing)) && + (input_style != (XIMPreeditPosition | XIMStatusNothing))) { + print_error("This program does not support the preedit type"); + XCloseIM(xim); + return; + } + if (input_style & XIMPreeditPosition) { + setSize ( &rect ) ; + setPosition( &spot ) ; + setColor ( &fg, &bg ) ; + + preedit_attr = XVaCreateNestedList + ( 0, + XNArea, &rect, + XNSpotLocation, &spot, + XNFontSet, TermWin.fontset, + XNForeground, fg, + XNBackground, bg, + XNLineSpace, Height2Pixel(1) - 1, + NULL ) ; + } + + Input_Context = XCreateIC(xim, XNInputStyle, input_style, + XNClientWindow, TermWin.parent, + XNFocusWindow, TermWin.parent, + preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, + NULL); + XFree(preedit_attr); + if (Input_Context == NULL) { + print_error("Failed to create input context"); + XCloseIM(xim); + } + } + #endif /* NO_XLOCALE */ + + /* INTPROTO */ + void + XProcessEvent( Display *display ) + { + XEvent xev ; + XNextEvent( display, &xev ) ; + #ifndef NO_XLOCALE + if( !XFilterEvent( &xev, xev.xany.window ) ) + process_x_event( &xev ) ; + #else + process_x_event( &xev ) ; + #endif + return ; } /*}}} */