Made IM context optional functionality

This commit is contained in:
Jack Andersen 2016-01-06 11:02:23 -10:00
parent 939c0250be
commit c96f961c4d
2 changed files with 75 additions and 72 deletions

View File

@ -163,7 +163,7 @@ class ApplicationXlib final : public IApplication
std::unordered_map<Window, IWindow*> m_windows; std::unordered_map<Window, IWindow*> m_windows;
Display* m_xDisp = nullptr; Display* m_xDisp = nullptr;
XIM m_xIM; XIM m_xIM = nullptr;
XFontSet m_fontset; XFontSet m_fontset;
XIMStyle m_bestStyle = 0; XIMStyle m_bestStyle = 0;
int m_xDefaultScreen = 0; int m_xDefaultScreen = 0;
@ -260,45 +260,42 @@ public:
if (XSetLocaleModifiers("") == nullptr) if (XSetLocaleModifiers("") == nullptr)
Log.report(LogVisor::Warning, "Cannot set locale modifiers."); Log.report(LogVisor::Warning, "Cannot set locale modifiers.");
if ((m_xIM = XOpenIM(m_xDisp, nullptr, nullptr, nullptr)) == nullptr) if ((m_xIM = XOpenIM(m_xDisp, nullptr, nullptr, nullptr)))
{ {
Log.report(LogVisor::FatalError, "Couldn't open input method."); char** missing_charsets;
return; int num_missing_charsets = 0;
} char* default_string;
m_fontset = XCreateFontSet(m_xDisp,
"-adobe-helvetica-*-r-*-*-*-120-*-*-*-*-*-*,\
-misc-fixed-*-r-*-*-*-130-*-*-*-*-*-*",
&missing_charsets, &num_missing_charsets,
&default_string);
char** missing_charsets; /* figure out which styles the IM can support */
int num_missing_charsets = 0; XIMStyles* im_supported_styles;
char* default_string; XIMStyle app_supported_styles;
m_fontset = XCreateFontSet(m_xDisp, XGetIMValues(m_xIM, XNQueryInputStyle, &im_supported_styles, nullptr);
"-adobe-helvetica-*-r-*-*-*-120-*-*-*-*-*-*,\ /* set flags for the styles our application can support */
-misc-fixed-*-r-*-*-*-130-*-*-*-*-*-*", app_supported_styles = XIMPreeditNone | XIMPreeditNothing | XIMPreeditPosition;
&missing_charsets, &num_missing_charsets, app_supported_styles |= XIMStatusNone | XIMStatusNothing;
&default_string); /*
* now look at each of the IM supported styles, and
/* figure out which styles the IM can support */ * chose the "best" one that we can support.
XIMStyles* im_supported_styles; */
XIMStyle app_supported_styles; for (int i=0 ; i<im_supported_styles->count_styles ; ++i)
XGetIMValues(m_xIM, XNQueryInputStyle, &im_supported_styles, nullptr); {
/* set flags for the styles our application can support */ XIMStyle style = im_supported_styles->supported_styles[i];
app_supported_styles = XIMPreeditNone | XIMPreeditNothing | XIMPreeditPosition; if ((style & app_supported_styles) == style) /* if we can handle it */
app_supported_styles |= XIMStatusNone | XIMStatusNothing; m_bestStyle = ChooseBetterStyle(style, m_bestStyle);
/* }
* now look at each of the IM supported styles, and /* if we couldn't support any of them, print an error and exit */
* chose the "best" one that we can support. if (m_bestStyle == 0)
*/ {
for (int i=0 ; i<im_supported_styles->count_styles ; ++i) Log.report(LogVisor::FatalError, "interaction style not supported.");
{ return;
XIMStyle style = im_supported_styles->supported_styles[i]; }
if ((style & app_supported_styles) == style) /* if we can handle it */ XFree(im_supported_styles);
m_bestStyle = ChooseBetterStyle(style, m_bestStyle);
} }
/* if we couldn't support any of them, print an error and exit */
if (m_bestStyle == 0)
{
Log.report(LogVisor::FatalError, "interaction style not supported.");
return;
}
XFree(im_supported_styles);
m_xDefaultScreen = DefaultScreen(m_xDisp); m_xDefaultScreen = DefaultScreen(m_xDisp);
X_CURSORS.m_pointer = XCreateFontCursor(m_xDisp, XC_left_ptr); X_CURSORS.m_pointer = XCreateFontCursor(m_xDisp, XC_left_ptr);

View File

@ -510,7 +510,7 @@ class WindowXlib : public IWindow
Colormap m_colormapId; Colormap m_colormapId;
Window m_windowId; Window m_windowId;
XIMStyle m_bestStyle; XIMStyle m_bestStyle;
XIC m_xIC; XIC m_xIC = nullptr;
GraphicsContextGLX m_gfxCtx; GraphicsContextGLX m_gfxCtx;
uint32_t m_visualId; uint32_t m_visualId;
@ -603,26 +603,24 @@ public:
* Now go create an IC using the style we chose. * Now go create an IC using the style we chose.
* Also set the window and fontset attributes now. * Also set the window and fontset attributes now.
*/ */
XPoint pt = {0,0}; if (xIM)
XVaNestedList nlist;
m_xIC = XCreateIC(xIM, XNInputStyle, bestInputStyle,
XNClientWindow, m_windowId,
XNFocusWindow, m_windowId,
XNPreeditAttributes, nlist = XVaCreateNestedList(0,
XNSpotLocation, &pt,
XNFontSet, fontset,
nullptr),
nullptr);
XFree(nlist);
if (m_xIC == nullptr)
{ {
Log.report(LogVisor::FatalError, "Couldn't create input context."); XPoint pt = {0,0};
return; XVaNestedList nlist;
m_xIC = XCreateIC(xIM, XNInputStyle, bestInputStyle,
XNClientWindow, m_windowId,
XNFocusWindow, m_windowId,
XNPreeditAttributes, nlist = XVaCreateNestedList(0,
XNSpotLocation, &pt,
XNFontSet, fontset,
nullptr),
nullptr);
XFree(nlist);
long im_event_mask;
XGetICValues(m_xIC, XNFilterEvents, &im_event_mask, nullptr);
XSelectInput(display, m_windowId, swa.event_mask | im_event_mask);
XSetICFocus(m_xIC);
} }
long im_event_mask;
XGetICValues(m_xIC, XNFilterEvents, &im_event_mask, nullptr);
XSelectInput(display, m_windowId, swa.event_mask | im_event_mask);
XSetICFocus(m_xIC);
/* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */ /* The XInput 2.1 extension enables per-pixel smooth scrolling trackpads */
XIEventMask mask = {XIAllMasterDevices, XIMaskLen(XI_LASTEVENT)}; XIEventMask mask = {XIAllMasterDevices, XIMaskLen(XI_LASTEVENT)};
@ -905,20 +903,23 @@ public:
void claimKeyboardFocus(const int coord[2]) void claimKeyboardFocus(const int coord[2])
{ {
XLockDisplay(m_xDisp); if (m_xIC)
if (!coord)
{ {
XUnsetICFocus(m_xIC); XLockDisplay(m_xDisp);
if (!coord)
{
XUnsetICFocus(m_xIC);
XUnlockDisplay(m_xDisp);
return;
}
getWindowFrame(m_wrect.location[0], m_wrect.location[1], m_wrect.size[0], m_wrect.size[1]);
XPoint pt = {short(coord[0]), short(m_wrect.size[1] - coord[1])};
XVaNestedList list = XVaCreateNestedList(0, XNSpotLocation, &pt, nullptr);
XSetICValues(m_xIC, XNPreeditAttributes, list, nullptr);
XFree(list);
XSetICFocus(m_xIC);
XUnlockDisplay(m_xDisp); XUnlockDisplay(m_xDisp);
return;
} }
getWindowFrame(m_wrect.location[0], m_wrect.location[1], m_wrect.size[0], m_wrect.size[1]);
XPoint pt = {short(coord[0]), short(m_wrect.size[1] - coord[1])};
XVaNestedList list = XVaCreateNestedList(0, XNSpotLocation, &pt, nullptr);
XSetICValues(m_xIC, XNPreeditAttributes, list, nullptr);
XFree(list);
XSetICFocus(m_xIC);
XUnlockDisplay(m_xDisp);
} }
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz) bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz)
@ -1141,6 +1142,7 @@ public:
}; };
} }
#if 0
/* This procedure sets the application's size constraints and returns /* This procedure sets the application's size constraints and returns
* the IM's preferred size for either the Preedit or Status areas, * the IM's preferred size for either the Preedit or Status areas,
* depending on the value of the name argument. The area argument is * depending on the value of the name argument. The area argument is
@ -1167,6 +1169,7 @@ public:
XSetICValues(m_xIC, name, list, nullptr); XSetICValues(m_xIC, name, list, nullptr);
XFree(list); XFree(list);
} }
#endif
void _incomingEvent(void* e) void _incomingEvent(void* e)
{ {
@ -1230,13 +1233,16 @@ public:
EModifierKey modifierKey; EModifierKey modifierKey;
unsigned int state = event->xkey.state; unsigned int state = event->xkey.state;
event->xkey.state &= ~ControlMask; event->xkey.state &= ~ControlMask;
std::string utf8Frag = translateUTF8(&event->xkey, m_xIC);
ITextInputCallback* inputCb = m_callback->getTextInputCallback(); ITextInputCallback* inputCb = m_callback->getTextInputCallback();
if (utf8Frag.size()) if (m_xIC)
{ {
if (inputCb) std::string utf8Frag = translateUTF8(&event->xkey, m_xIC);
inputCb->insertText(utf8Frag); if (utf8Frag.size())
return; {
if (inputCb)
inputCb->insertText(utf8Frag);
return;
}
} }
char charCode = translateKeysym(&event->xkey, specialKey, modifierKey); char charCode = translateKeysym(&event->xkey, specialKey, modifierKey);
EModifierKey modifierMask = translateModifiers(state); EModifierKey modifierMask = translateModifiers(state);