New function for XIM instantiate callback. New function where call to

Tue Jun 10 11:23:48 2003  Hidetoshi Tajima  <hidetoshi.tajima@sun.com>

	* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
	function for XIM instantiate callback.
	* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
	where call to XOpenIM() or XRegisterIMInstantiateCallback() is
	actually made.
	* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
	for XIM's destroy callback.
	* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
	is set or not - if it's not set, call xim_info_try_im() to try to
	initiaize it.
	* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
	filter_key_release flag of the context.
	* modules/input/gtkimcontextxim.c (get_ic_real): removed
	* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
	code from the removed get_ic_real().

	For XIM instantiation, destruction and re-instantiation. With
	this, Gtk+ apps will be able to connect or reconnect to the XIM,
	when it starts after the apps, or when the XIM gets lost and recover.
	(#113099, #107782).
This commit is contained in:
Hidetoshi Tajima 2003-06-10 18:24:29 +00:00 committed by Hidetoshi Tajima
parent 801531ca88
commit 66933a6bdd
6 changed files with 284 additions and 96 deletions

View File

@ -1,3 +1,26 @@
Tue Jun 10 11:23:48 2003 Hidetoshi Tajima <hidetoshi.tajima@sun.com>
* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
function for XIM instantiate callback.
* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
where call to XOpenIM() or XRegisterIMInstantiateCallback() is
actually made.
* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
for XIM's destroy callback.
* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
is set or not - if it's not set, call xim_info_try_im() to try to
initiaize it.
* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
filter_key_release flag of the context.
* modules/input/gtkimcontextxim.c (get_ic_real): removed
* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
code from the removed get_ic_real().
For XIM instantiation, destruction and re-instantiation. With
this, Gtk+ apps will be able to connect or reconnect to the XIM,
when it starts after the apps, or when the XIM gets lost and recover.
(#113099, #107782).
Mon Jun 10 01:12:31 2003 Kristian Rietveld <kris@gtk.org>
Merged from stable.

View File

@ -1,3 +1,26 @@
Tue Jun 10 11:23:48 2003 Hidetoshi Tajima <hidetoshi.tajima@sun.com>
* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
function for XIM instantiate callback.
* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
where call to XOpenIM() or XRegisterIMInstantiateCallback() is
actually made.
* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
for XIM's destroy callback.
* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
is set or not - if it's not set, call xim_info_try_im() to try to
initiaize it.
* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
filter_key_release flag of the context.
* modules/input/gtkimcontextxim.c (get_ic_real): removed
* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
code from the removed get_ic_real().
For XIM instantiation, destruction and re-instantiation. With
this, Gtk+ apps will be able to connect or reconnect to the XIM,
when it starts after the apps, or when the XIM gets lost and recover.
(#113099, #107782).
Mon Jun 10 01:12:31 2003 Kristian Rietveld <kris@gtk.org>
Merged from stable.

View File

@ -1,3 +1,26 @@
Tue Jun 10 11:23:48 2003 Hidetoshi Tajima <hidetoshi.tajima@sun.com>
* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
function for XIM instantiate callback.
* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
where call to XOpenIM() or XRegisterIMInstantiateCallback() is
actually made.
* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
for XIM's destroy callback.
* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
is set or not - if it's not set, call xim_info_try_im() to try to
initiaize it.
* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
filter_key_release flag of the context.
* modules/input/gtkimcontextxim.c (get_ic_real): removed
* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
code from the removed get_ic_real().
For XIM instantiation, destruction and re-instantiation. With
this, Gtk+ apps will be able to connect or reconnect to the XIM,
when it starts after the apps, or when the XIM gets lost and recover.
(#113099, #107782).
Mon Jun 10 01:12:31 2003 Kristian Rietveld <kris@gtk.org>
Merged from stable.

View File

@ -1,3 +1,26 @@
Tue Jun 10 11:23:48 2003 Hidetoshi Tajima <hidetoshi.tajima@sun.com>
* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
function for XIM instantiate callback.
* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
where call to XOpenIM() or XRegisterIMInstantiateCallback() is
actually made.
* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
for XIM's destroy callback.
* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
is set or not - if it's not set, call xim_info_try_im() to try to
initiaize it.
* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
filter_key_release flag of the context.
* modules/input/gtkimcontextxim.c (get_ic_real): removed
* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
code from the removed get_ic_real().
For XIM instantiation, destruction and re-instantiation. With
this, Gtk+ apps will be able to connect or reconnect to the XIM,
when it starts after the apps, or when the XIM gets lost and recover.
(#113099, #107782).
Mon Jun 10 01:12:31 2003 Kristian Rietveld <kris@gtk.org>
Merged from stable.

View File

@ -1,3 +1,26 @@
Tue Jun 10 11:23:48 2003 Hidetoshi Tajima <hidetoshi.tajima@sun.com>
* modules/input/gtkimcontextxim.c (xim_instantiate_callback): New
function for XIM instantiate callback.
* modules/input/gtkimcontextxim.c (xim_info_try_im): New function
where call to XOpenIM() or XRegisterIMInstantiateCallback() is
actually made.
* modules/input/gtkimcontextxim.c (xim_destroy_callback): New function
for XIM's destroy callback.
* modules/input/gtkimcontextxim.c (get_im): add a check if info->im
is set or not - if it's not set, call xim_info_try_im() to try to
initiaize it.
* modules/input/gtkimcontextxim.c (reinitialize_ic): reset
filter_key_release flag of the context.
* modules/input/gtkimcontextxim.c (get_ic_real): removed
* modules/input/gtkimcontextxim.c (gtk_im_context_xim_get_ic): move
code from the removed get_ic_real().
For XIM instantiation, destruction and re-instantiation. With
this, Gtk+ apps will be able to connect or reconnect to the XIM,
when it starts after the apps, or when the XIM gets lost and recover.
(#113099, #107782).
Mon Jun 10 01:12:31 2003 Kristian Rietveld <kris@gtk.org>
Merged from stable.

View File

@ -41,6 +41,8 @@ struct _GtkXIMInfo
gulong preedit_set;
XIMStyles *xim_styles;
GSList *ics;
guint reconnecting :1;
};
/* A context status window; these are kept in the status_windows list. */
@ -86,6 +88,10 @@ static void status_window_hide (GtkIMContextXIM *context_xim);
static void status_window_set_text (GtkIMContextXIM *context_xim,
const gchar *text);
static void xim_destroy_callback (XIM xim,
XPointer client_data,
XPointer call_data);
static XIC gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim);
static GObjectClass *parent_class;
@ -250,10 +256,17 @@ static void
setup_im (GtkXIMInfo *info)
{
XIMValuesList *ic_values = NULL;
XIMCallback im_destroy_callback;
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,
@ -335,45 +348,107 @@ xim_info_display_closed (GdkDisplay *display,
g_free (info);
}
static void
xim_instantiate_callback (Display *display, XPointer client_data,
XPointer call_data)
{
GtkXIMInfo *info = (GtkXIMInfo*)client_data;
XIM im = NULL;
im = XOpenIM (display, NULL, NULL, NULL);
if (!im)
return;
info->im = im;
setup_im (info);
XUnregisterIMInstantiateCallback (display, NULL, NULL, NULL,
xim_instantiate_callback,
(XPointer)info);
info->reconnecting = FALSE;
}
/* initialize info->im */
static void
xim_info_try_im (GtkXIMInfo *info)
{
GdkScreen *screen = info->screen;
GdkDisplay *display = gdk_screen_get_display (screen);
g_assert (info->im == NULL);
if (info->reconnecting)
return;
if (XSupportsLocale ())
{
if (!XSetLocaleModifiers (""))
g_warning ("Unable to set locale modifiers with XSetLocaleModifiers()");
info->im = XOpenIM (GDK_DISPLAY_XDISPLAY (display), NULL, NULL, NULL);
if (!info->im)
{
XRegisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY(display),
NULL, NULL, NULL,
xim_instantiate_callback,
(XPointer)info);
info->reconnecting = TRUE;
return;
}
setup_im (info);
g_signal_connect (display, "closed",
G_CALLBACK (xim_info_display_closed), info);
}
}
static void
xim_destroy_callback (XIM xim,
XPointer client_data,
XPointer call_data)
{
GtkXIMInfo *info = (GtkXIMInfo*)client_data;
info->im = NULL;
g_signal_handler_disconnect (info->settings, info->status_set);
g_signal_handler_disconnect (info->settings, info->preedit_set);
reinitialize_all_ics (info);
xim_info_try_im (info);
return;
}
static GtkXIMInfo *
get_im (GdkWindow *client_window,
const char *locale)
{
GSList *tmp_list;
GtkXIMInfo *info;
XIM im = NULL;
GdkScreen *screen = gdk_drawable_get_screen (client_window);
GdkDisplay *display = gdk_screen_get_display (screen);
info = NULL;
tmp_list = open_ims;
while (tmp_list)
{
info = tmp_list->data;
if (info->screen == screen &&
strcmp (info->locale, locale) == 0)
return info;
{
if (info->im)
return info;
else
break;
}
tmp_list = tmp_list->next;
}
info = NULL;
if (XSupportsLocale ())
if (info == NULL)
{
if (!XSetLocaleModifiers (""))
g_warning ("Unable to set locale modifiers with XSetLocaleModifiers()");
im = XOpenIM (GDK_DISPLAY_XDISPLAY (display), NULL, NULL, NULL);
if (!im)
g_warning ("Unable to open XIM input method, falling back to XLookupString()");
info = g_new (GtkXIMInfo, 1);
open_ims = g_slist_prepend (open_ims, info);
info->screen = screen;
info->locale = g_strdup (locale);
info->im = im;
info->xim_styles = NULL;
info->preedit_style_setting = 0;
info->status_style_setting = 0;
@ -381,13 +456,11 @@ get_im (GdkWindow *client_window,
info->preedit_set = 0;
info->status_set = 0;
info->ics = NULL;
setup_im (info);
g_signal_connect (display, "closed",
G_CALLBACK (xim_info_display_closed), info);
info->reconnecting = FALSE;
info->im = NULL;
}
xim_info_try_im (info);
return info;
}
@ -448,6 +521,11 @@ reinitialize_ic (GtkIMContextXIM *context_xim)
g_signal_emit_by_name (context_xim, "preedit_changed");
}
}
/*
reset filter_key_release flag, otherwise keystrokes will be doubled
until reconnecting to XIM.
*/
context_xim->filter_key_release = FALSE;
}
static void
@ -1078,85 +1156,80 @@ set_status_callback (GtkIMContextXIM *context_xim)
NULL);
}
static XIC
get_ic_real (GtkIMContextXIM *context_xim)
{
XIC xic = 0;
const char *name1 = NULL;
XVaNestedList list1 = NULL;
const char *name2 = NULL;
XVaNestedList list2 = NULL;
XIMStyle im_style = 0;
if (context_xim->im_info->im == NULL)
return (XIC)0;
if (context_xim->use_preedit &&
(context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditCallbacks)
{
im_style |= XIMPreeditCallbacks;
name1 = XNPreeditAttributes;
list1 = set_preedit_callback (context_xim);
}
else if ((context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditNone)
im_style |= XIMPreeditNone;
else
im_style |= XIMPreeditNothing;
if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusCallbacks)
{
im_style |= XIMStatusCallbacks;
if (name1 == NULL)
{
name1 = XNStatusAttributes;
list1 = set_status_callback (context_xim);
}
else
{
name2 = XNStatusAttributes;
list2 = set_status_callback (context_xim);
}
}
else if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusNone)
im_style |= XIMStatusNone;
else
im_style |= XIMStatusNothing;
xic = XCreateIC (context_xim->im_info->im,
XNInputStyle, im_style,
XNClientWindow, GDK_DRAWABLE_XID (context_xim->client_window),
name1, list1,
name2, list2,
NULL);
if (list1)
XFree (list1);
if (list2)
XFree (list2);
if (xic)
{
/* Don't filter key released events with XFilterEvents unless
* input methods ask for. This is a workaround for Solaris input
* method bug in C and European locales. It doubles each key
* stroke if both key pressed and released events are filtered.
* (bugzilla #81759)
*/
guint32 mask = 0;
XGetICValues (xic,
XNFilterEvents, &mask,
NULL);
context_xim->filter_key_release = (mask & KeyReleaseMask);
}
return xic;
}
static XIC
gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim)
{
if (!context_xim->ic && context_xim->im_info)
context_xim->ic = get_ic_real (context_xim);
if (context_xim->im_info == NULL || context_xim->im_info->im == NULL)
return NULL;
if (!context_xim->ic)
{
const char *name1 = NULL;
XVaNestedList list1 = NULL;
const char *name2 = NULL;
XVaNestedList list2 = NULL;
XIMStyle im_style = 0;
XIC xic = 0;
if (context_xim->use_preedit &&
(context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditCallbacks)
{
im_style |= XIMPreeditCallbacks;
name1 = XNPreeditAttributes;
list1 = set_preedit_callback (context_xim);
}
else if ((context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditNone)
im_style |= XIMPreeditNone;
else
im_style |= XIMPreeditNothing;
if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusCallbacks)
{
im_style |= XIMStatusCallbacks;
if (name1 == NULL)
{
name1 = XNStatusAttributes;
list1 = set_status_callback (context_xim);
}
else
{
name2 = XNStatusAttributes;
list2 = set_status_callback (context_xim);
}
}
else if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusNone)
im_style |= XIMStatusNone;
else
im_style |= XIMStatusNothing;
xic = XCreateIC (context_xim->im_info->im,
XNInputStyle, im_style,
XNClientWindow, GDK_DRAWABLE_XID (context_xim->client_window),
name1, list1,
name2, list2,
NULL);
if (list1)
XFree (list1);
if (list2)
XFree (list2);
if (xic)
{
/* Don't filter key released events with XFilterEvents unless
* input methods ask for. This is a workaround for Solaris input
* method bug in C and European locales. It doubles each key
* stroke if both key pressed and released events are filtered.
* (bugzilla #81759)
*/
guint32 mask = 0;
XGetICValues (xic,
XNFilterEvents, &mask,
NULL);
context_xim->filter_key_release = (mask & KeyReleaseMask);
}
context_xim->ic = xic;
}
return context_xim->ic;
}