static void _ecore_imf_context_xim_del(Ecore_IMF_Context *ctx) { Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data); EINA_SAFETY_ON_NULL_RETURN(imf_context_data); imf_context_data->finalizing = EINA_TRUE; if (imf_context_data->im_info && !imf_context_data->im_info->ics->next) { if (imf_context_data->im_info->reconnecting == EINA_TRUE) { Ecore_X_Display *dsp; dsp = ecore_x_display_get(); XUnregisterIMInstantiateCallback(dsp, NULL, NULL, NULL, _ecore_imf_xim_instantiate_cb, (XPointer)imf_context_data->im_info); } else if (imf_context_data->im_info->im) { XIMCallback im_destroy_callback; im_destroy_callback.client_data = NULL; im_destroy_callback.callback = NULL; XSetIMValues(imf_context_data->im_info->im, XNDestroyCallback, &im_destroy_callback, NULL); } } _ecore_imf_xim_ic_client_window_set(ctx, 0); _ecore_imf_xim_context_data_destroy(imf_context_data); }
/*********************************************************************** * 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; }
void X11InputMethod::AttachToXIM(X11Types::Display* display) { if (m_xim != 0) return; if (!SetLocaleModifier(0, 0, FALSE) ) { // Recovery to avoid bug DSK-297409 which really is about a broken distribution OpString8 lc_ctype; lc_ctype.Set(setlocale(LC_CTYPE, 0)); BOOL ok = FALSE; OpAutoVector<OpString8> list; OP_STATUS rc = GetAlternativeLocaleFormat(lc_ctype, list); if (OpStatus::IsError(rc) || list.GetCount()==0) { ok = SetLocaleModifier(0, "C", FALSE); } else { for (UINT32 i=0; !ok && i<list.GetCount(); i++) ok = SetLocaleModifier(0, list.Get(i)->CStr(), FALSE); } if(!ok) { fprintf(stderr, "opera: You appear to have an invalid locale set. This may prevent you from being able to type\n"); return; } } m_xim = XOpenIM(display, NULL, NULL, NULL); if (m_xim == NULL) { // Recovery to avoid bug DSK-304220 (broken XMODIFIERS) SetLocaleModifier("@im=", m_lc_modifier.value.CStr(), TRUE); m_xim = XOpenIM(display, NULL, NULL, NULL); if (m_xim == NULL) { fprintf(stderr, "opera: XOpenIM failed. This may prevent you from being able to type\n"); return; } } { // local scope XIMCallback cb; cb.client_data = (XPointer)this; cb.callback = XIMDestroyCallback; const char * setvalueerr = XSetIMValues(m_xim, XNDestroyCallback, &cb, NULL); if (setvalueerr != 0) fprintf(stderr, "opera: Failed to set XIM destroy callback\n"); } XIMStyles* xim_styles = 0; char* im_values = XGetIMValues(m_xim, XNQueryInputStyle, &xim_styles, NULL); if(im_values != NULL || xim_styles == NULL) { fprintf(stderr, "opera: input method does not support any styles\n"); } if(xim_styles) { unsigned long callbacks = 0; for (int i = 0; i < xim_styles->count_styles; i++) { // We try to find the style with the most support for preedit and status callbacks if ((xim_styles->supported_styles[i] & XIMPreeditCallbacks) && (xim_styles->supported_styles[i] & callbacks) == callbacks) { m_xim_style = xim_styles->supported_styles[i]; callbacks |= XIMPreeditCallbacks; } if ((xim_styles->supported_styles[i] & XIMStatusCallbacks) && (xim_styles->supported_styles[i] & callbacks) == callbacks) { m_xim_style = xim_styles->supported_styles[i]; callbacks |= XIMStatusCallbacks; } if ((xim_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) && !callbacks) { m_xim_style = xim_styles->supported_styles[i]; } } if (m_xim_style == 0) { fprintf(stderr, "opera: input method does not support the style we support\n"); } XFree(xim_styles); } }
static void setup_im (GtkOXIMInfo *info) { XIMValuesList *ic_values = NULL; XIMCallback im_destroy_callback; GdkDisplay *display; if (info->im == NULL) return; im_destroy_callback.client_data = (XPointer)info; im_destroy_callback.callback = (XIMProc)xim_destroy_callback; XSetIMValues (info->im, XNDestroyCallback, &im_destroy_callback, NULL); XGetIMValues (info->im, XNQueryInputStyle, &info->xim_styles, XNQueryICValuesList, &ic_values, NULL); info->settings = gtk_settings_get_for_screen (info->screen); if (!g_object_class_find_property (G_OBJECT_GET_CLASS (info->settings), "gtk-im-preedit-style")) gtk_settings_install_property (g_param_spec_enum ("gtk-im-preedit-style", P_("IM Preedit style"), P_("How to draw the input method preedit string"), GTK_TYPE_IM_PREEDIT_STYLE, GTK_IM_PREEDIT_CALLBACK, G_PARAM_READWRITE)); if (!g_object_class_find_property (G_OBJECT_GET_CLASS (info->settings), "gtk-im-status-style")) gtk_settings_install_property (g_param_spec_enum ("gtk-im-status-style", P_("IM Status style"), P_("How to draw the input method statusbar"), GTK_TYPE_IM_STATUS_STYLE, GTK_IM_STATUS_CALLBACK, G_PARAM_READWRITE)); info->preedit_set = g_signal_connect_swapped (info->settings, "notify::gtk-im-preedit-style", G_CALLBACK (preedit_style_change), info); info->supports_string_conversion = FALSE; if (ic_values) { int i; for (i = 0; i < ic_values->count_values; i++) if (strcmp (ic_values->supported_values[i], XNStringConversionCallback) == 0) { info->supports_string_conversion = TRUE; break; } #if 0 for (i = 0; i < ic_values->count_values; i++) g_print ("%s\n", ic_values->supported_values[i]); for (i = 0; i < xim_styles->count_styles; i++) g_print ("%#x\n", xim_styles->supported_styles[i]); #endif XFree (ic_values); } preedit_style_change (info); display = gdk_screen_get_display (info->screen); info->display_closed_cb = g_signal_connect (display, "closed", G_CALLBACK (xim_info_display_closed), info); }