int XUtf8LookupString(XIC ic, XKeyPressedEvent* event, char* buffer_return, int bytes_buffer, KeySym* keysym, Status* status_return) { long ucs = -1; int len; len = XmbLookupString(ic, event, buffer_return, bytes_buffer / 5, keysym, status_return); if (*status_return == XBufferOverflow) { return len * 5; } if (*keysym > 0 && *keysym < 0x100 && len == 1) { if (*keysym < 0x80) { ucs = (unsigned char)buffer_return[0]; } else { ucs = *keysym; } } else if (((*keysym >= 0x100 && *keysym <= 0xf000) || (*keysym & 0xff000000U) == 0x01000000)) { ucs = XKeysymToUcs(*keysym); } else { ucs = -2; } if (ucs > 0) { len = XConvertUcsToUtf8((unsigned)ucs, (char *)buffer_return); } else if (len > 0) { XIM im; if (!ic) return 0; im = XIMOfIC(ic); if (!im) return 0; len = XConvertEucToUtf8(XLocaleOfIM(im), buffer_return, len, bytes_buffer); } return len; }
se_text_xviewer* se_text_xviewer_create( se_env* env ) { se_text_xviewer* viewer = g_malloc0( sizeof(se_text_xviewer) ); if ( !viewer ) { se_error( "can not malloc a viewer obj" ); } viewer->env = env; int width = 800; int height = 600; viewer->view = XCreateSimpleWindow( env->display, env->root, 0, 0, width, height, 0, BlackPixel(env->display, env->screen), WhitePixel(env->display, env->screen) ); viewer->key_handler = se_text_xviewer_key_event; viewer->mouse_handler = se_text_xviewer_mouse_event; viewer->configure_change_handler = se_text_xviewer_configure_change_handler; viewer->show = se_text_xviewer_show; viewer->repaint = se_text_xviewer_repaint; viewer->redisplay = se_text_xviewer_redisplay; viewer->updateSize = se_text_xviewer_updateSize; se_text_xviewer_draw_create( viewer ); viewer->content = g_malloc0( SE_MAX_COLUMNS * SE_MAX_ROWS ); XIMStyles *im_supported_styles; XIMStyle app_supported_styles; XIMStyle style; XIMStyle best_style; XGetIMValues( env->xim, XNQueryInputStyle, &im_supported_styles, NULL ); app_supported_styles = XIMPreeditNone | XIMPreeditNothing | XIMPreeditArea | XIMStatusNone | XIMStatusNothing | XIMStatusArea; best_style = 0; se_debug( "styles count: %d", im_supported_styles->count_styles ); for(int i=0; i < im_supported_styles->count_styles; i++) { style = im_supported_styles->supported_styles[i]; dump_style( style ); if ((style & app_supported_styles) == style) /* if we can handle it */ best_style = ChooseBetterStyle(style, best_style); } /* if we couldn't support any of them, print an error and exit */ if (best_style == 0) { se_error("commonly supported interaction style."); exit(1); } XFree(im_supported_styles); dump_style( best_style ); viewer->xic = XCreateIC(env->xim, XNInputStyle, best_style, XNClientWindow, viewer->view, NULL); if ( viewer->xic == NULL ) { se_debug(" create xic failed" ); exit(1); } se_debug( "XLocaleOfIM: %s", XLocaleOfIM( env->xim ) ); return viewer; }
/*********************************************************************** * X11DRV Ime creation * * Should always be called with the x11 lock held */ static void X11DRV_OpenIM(Display *display, XPointer ptr, XPointer data) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIMStyle ximStyleCallback, ximStyleNone; XIMStyles *ximStyles = NULL; INT i; XIM xim; XIMCallback destroy; xim = XOpenIM(display, NULL, NULL, NULL); if (xim == NULL) { WARN("Could not open input method.\n"); return; } destroy.client_data = NULL; destroy.callback = X11DRV_DestroyIM; if (XSetIMValues(xim, XNDestroyCallback, &destroy, NULL)) { WARN("Could not set destroy callback.\n"); } TRACE("xim = %p\n", xim); TRACE("X display of IM = %p\n", XDisplayOfIM(xim)); TRACE("Using %s locale of Input Method\n", XLocaleOfIM(xim)); XGetIMValues(xim, XNQueryInputStyle, &ximStyles, NULL); if (ximStyles == 0) { WARN("Could not find supported input style.\n"); XCloseIM(xim); return; } else { TRACE("ximStyles->count_styles = %d\n", ximStyles->count_styles); ximStyleRoot = 0; ximStyleNone = 0; ximStyleCallback = 0; for (i = 0; i < ximStyles->count_styles; ++i) { int style = ximStyles->supported_styles[i]; TRACE("ximStyles[%d] = %s%s%s%s%s\n", i, (style&XIMPreeditArea)?"XIMPreeditArea ":"", (style&XIMPreeditCallbacks)?"XIMPreeditCallbacks ":"", (style&XIMPreeditPosition)?"XIMPreeditPosition ":"", (style&XIMPreeditNothing)?"XIMPreeditNothing ":"", (style&XIMPreeditNone)?"XIMPreeditNone ":""); if (!ximStyle && (ximStyles->supported_styles[i] == ximStyleRequest)) { ximStyle = ximStyleRequest; TRACE("Setting Style: ximStyle = ximStyleRequest\n"); } else if (!ximStyleRoot &&(ximStyles->supported_styles[i] == STYLE_ROOT)) { ximStyleRoot = STYLE_ROOT; TRACE("Setting Style: ximStyleRoot = STYLE_ROOT\n"); } else if (!ximStyleCallback &&(ximStyles->supported_styles[i] == STYLE_CALLBACK)) { ximStyleCallback = STYLE_CALLBACK; TRACE("Setting Style: ximStyleCallback = STYLE_CALLBACK\n"); } else if (!ximStyleNone && (ximStyles->supported_styles[i] == STYLE_NONE)) { TRACE("Setting Style: ximStyleNone = STYLE_NONE\n"); ximStyleNone = STYLE_NONE; } } XFree(ximStyles); if (ximStyle == 0) ximStyle = ximStyleRoot; if (ximStyle == 0) ximStyle = ximStyleNone; if (ximStyleCallback == 0) { TRACE("No callback style avalable\n"); ximStyleCallback = ximStyle; } } thread_data->xim = xim; XUnregisterIMInstantiateCallback(display, NULL, NULL, NULL, X11DRV_OpenIM, NULL); wine_tsx11_unlock(); IME_UpdateAssociation(NULL); wine_tsx11_lock(); }
/*********************************************************************** * X11DRV Ime creation * * Should always be called with the x11 lock held */ static BOOL open_xim( Display *display ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIMStyle ximStyleCallback, ximStyleNone; XIMStyles *ximStyles = NULL; INT i; XIM xim; XIMCallback destroy; xim = XOpenIM(display, NULL, NULL, NULL); if (xim == NULL) { WARN("Could not open input method.\n"); return FALSE; } destroy.client_data = NULL; destroy.callback = X11DRV_DestroyIM; if (XSetIMValues(xim, XNDestroyCallback, &destroy, NULL)) { WARN("Could not set destroy callback.\n"); } TRACE("xim = %p\n", xim); TRACE("X display of IM = %p\n", XDisplayOfIM(xim)); TRACE("Using %s locale of Input Method\n", XLocaleOfIM(xim)); XGetIMValues(xim, XNQueryInputStyle, &ximStyles, NULL); if (ximStyles == 0) { WARN("Could not find supported input style.\n"); XCloseIM(xim); return FALSE; } else { TRACE("ximStyles->count_styles = %d\n", ximStyles->count_styles); ximStyleRoot = 0; ximStyleNone = 0; ximStyleCallback = 0; for (i = 0; i < ximStyles->count_styles; ++i) { int style = ximStyles->supported_styles[i]; TRACE("ximStyles[%d] = %s%s%s%s%s\n", i, (style&XIMPreeditArea)?"XIMPreeditArea ":"", (style&XIMPreeditCallbacks)?"XIMPreeditCallbacks ":"", (style&XIMPreeditPosition)?"XIMPreeditPosition ":"", (style&XIMPreeditNothing)?"XIMPreeditNothing ":"", (style&XIMPreeditNone)?"XIMPreeditNone ":""); if (!ximStyle && (ximStyles->supported_styles[i] == ximStyleRequest)) { ximStyle = ximStyleRequest; TRACE("Setting Style: ximStyle = ximStyleRequest\n"); } else if (!ximStyleRoot &&(ximStyles->supported_styles[i] == STYLE_ROOT)) { ximStyleRoot = STYLE_ROOT; TRACE("Setting Style: ximStyleRoot = STYLE_ROOT\n"); } else if (!ximStyleCallback &&(ximStyles->supported_styles[i] == STYLE_CALLBACK)) { ximStyleCallback = STYLE_CALLBACK; TRACE("Setting Style: ximStyleCallback = STYLE_CALLBACK\n"); } else if (!ximStyleNone && (ximStyles->supported_styles[i] == STYLE_NONE)) { TRACE("Setting Style: ximStyleNone = STYLE_NONE\n"); ximStyleNone = STYLE_NONE; } } XFree(ximStyles); if (ximStyle == 0) ximStyle = ximStyleRoot; if (ximStyle == 0) ximStyle = ximStyleNone; if (ximStyleCallback == 0) { TRACE("No callback style avalable\n"); ximStyleCallback = ximStyle; } } thread_data->xim = xim; if ((ximStyle & (XIMPreeditNothing | XIMPreeditNone)) == 0 || (ximStyle & (XIMStatusNothing | XIMStatusNone)) == 0) { char **list; int count; thread_data->font_set = XCreateFontSet(display, "fixed", &list, &count, NULL); TRACE("ximFontSet = %p\n", thread_data->font_set); TRACE("list = %p, count = %d\n", list, count); if (list != NULL) { int i; for (i = 0; i < count; ++i) TRACE("list[%d] = %s\n", i, list[i]); XFreeStringList(list); } } else thread_data->font_set = NULL; wine_tsx11_unlock(); IME_UpdateAssociation(NULL); wine_tsx11_lock(); return TRUE; }