Further improve XIM init

This commit is contained in:
Daniel Colascione 2014-03-23 04:45:17 -07:00
commit 577b2ffd2d
2 changed files with 87 additions and 69 deletions

View file

@ -2,7 +2,12 @@
* xfns.c (create_frame_xic): Pass XNStatusAttributes to XCreateIC
only if xic_style calls for it. This change allows Emacs to work
with ibus. Also, don't leak resources if create_frame_xic fails.
with ibus. Also, don't leak resources if create_frame_xic fails,
and stop caching xic_style across different displays.
(supported_xim_styles): Make const.
(best_xim_style): Remove first parameter: it's always just
supported_xim_styles. Change to look at supported_xim_styles
directly.
2014-03-23 Daniel Colascione <dancol@dancol.org>

View file

@ -1641,12 +1641,12 @@ hack_wm_protocols (struct frame *f, Widget widget)
#ifdef HAVE_X_I18N
static XFontSet xic_create_xfontset (struct frame *);
static XIMStyle best_xim_style (XIMStyles *, XIMStyles *);
static XIMStyle best_xim_style (XIMStyles *);
/* Supported XIM styles, ordered by preference. */
static XIMStyle supported_xim_styles[] =
static const XIMStyle supported_xim_styles[] =
{
XIMPreeditPosition | XIMStatusArea,
XIMPreeditPosition | XIMStatusNothing,
@ -1941,14 +1941,16 @@ xic_free_xfontset (struct frame *f)
input method XIM. */
static XIMStyle
best_xim_style (XIMStyles *user, XIMStyles *xim)
best_xim_style (XIMStyles *xim)
{
int i, j;
int nr_supported =
sizeof (supported_xim_styles) / sizeof (supported_xim_styles[0]);
for (i = 0; i < user->count_styles; ++i)
for (i = 0; i < nr_supported; ++i)
for (j = 0; j < xim->count_styles; ++j)
if (user->supported_styles[i] == xim->supported_styles[j])
return user->supported_styles[i];
if (supported_xim_styles[i] == xim->supported_styles[j])
return supported_xim_styles[i];
/* Return the default style. */
return XIMPreeditNothing | XIMStatusNothing;
@ -1956,8 +1958,6 @@ best_xim_style (XIMStyles *user, XIMStyles *xim)
/* Create XIC for frame F. */
static XIMStyle xic_style;
void
create_frame_xic (struct frame *f)
{
@ -1968,30 +1968,31 @@ create_frame_xic (struct frame *f)
XVaNestedList preedit_attr = NULL;
XRectangle s_area;
XPoint spot;
XIMStyles supported_list;
XIMStyle xic_style;
if (FRAME_XIC (f))
return;
/* Create X fontset. */
xfs = xic_create_xfontset (f);
FRAME_XIC_FONTSET (f) = xfs;
goto out;
xim = FRAME_X_XIM (f);
if (xim)
if (!xim)
goto out;
/* Determine XIC style. */
xic_style = best_xim_style (FRAME_X_XIM_STYLES (f));
/* Create X fontset. */
if (xic_style & (XIMPreeditPosition | XIMStatusArea))
{
xfs = xic_create_xfontset (f);
if (!xfs)
goto out;
FRAME_XIC_FONTSET (f) = xfs;
}
if (xic_style & XIMPreeditPosition)
{
spot.x = 0; spot.y = 1;
/* Determine XIC style. */
if (xic_style == 0)
{
supported_list.count_styles = (sizeof supported_xim_styles
/ sizeof supported_xim_styles[0]);
supported_list.supported_styles = supported_xim_styles;
xic_style = best_xim_style (&supported_list,
FRAME_X_XIM_STYLES (f));
}
preedit_attr = XVaCreateNestedList (0,
XNFontSet, xfs,
XNForeground,
@ -2006,50 +2007,62 @@ create_frame_xic (struct frame *f)
if (!preedit_attr)
goto out;
if (xic_style & XIMStatusArea)
{
s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
status_attr = XVaCreateNestedList (0,
XNArea,
&s_area,
XNFontSet,
xfs,
XNForeground,
FRAME_FOREGROUND_PIXEL (f),
XNBackground,
FRAME_BACKGROUND_PIXEL (f),
NULL);
if (!status_attr)
goto out;
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
XNStatusAttributes, status_attr,
XNPreeditAttributes, preedit_attr,
NULL);
}
else
{
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
XNPreeditAttributes, preedit_attr,
NULL);
}
if (!xic)
goto out;
FRAME_XIC (f) = xic;
FRAME_XIC_STYLE (f) = xic_style;
xfs = NULL; /* Don't free below. */
}
if (xic_style & XIMStatusArea)
{
s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
status_attr = XVaCreateNestedList (0,
XNArea,
&s_area,
XNFontSet,
xfs,
XNForeground,
FRAME_FOREGROUND_PIXEL (f),
XNBackground,
FRAME_BACKGROUND_PIXEL (f),
NULL);
if (!status_attr)
goto out;
}
if (preedit_attr && status_attr)
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
XNStatusAttributes, status_attr,
XNPreeditAttributes, preedit_attr,
NULL);
else if (preedit_attr)
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
XNPreeditAttributes, preedit_attr,
NULL);
else if (status_attr)
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
XNStatusAttributes, status_attr,
NULL);
else
xic = XCreateIC (xim,
XNInputStyle, xic_style,
XNClientWindow, FRAME_X_WINDOW (f),
XNFocusWindow, FRAME_X_WINDOW (f),
NULL);
if (!xic)
goto out;
FRAME_XIC (f) = xic;
FRAME_XIC_STYLE (f) = xic_style;
xfs = NULL; /* Don't free below. */
out:
if (xfs)