mirror of https://github.com/AxioDL/boo.git
Working Input Method support
This commit is contained in:
parent
aab693ff2f
commit
a933edcc40
|
@ -139,6 +139,7 @@ public:
|
|||
virtual void modKeyDown(EModifierKey mod, bool isRepeat)
|
||||
{(void)mod;(void)isRepeat;}
|
||||
virtual void modKeyUp(EModifierKey mod) {(void)mod;}
|
||||
virtual void utf8FragmentDown(const std::string& str) {(void)str;}
|
||||
virtual void focusLost() {}
|
||||
virtual void focusGained() {}
|
||||
virtual void windowMoved(const SWindowRect& rect)
|
||||
|
@ -220,7 +221,7 @@ public:
|
|||
virtual bool isFullscreen() const=0;
|
||||
virtual void setFullscreen(bool fs)=0;
|
||||
|
||||
virtual void claimKeyboardFocus()=0;
|
||||
virtual void claimKeyboardFocus(const int coord[2])=0;
|
||||
virtual bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz)=0;
|
||||
virtual std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz)=0;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
|
|||
|
||||
namespace boo
|
||||
{
|
||||
static LogVisor::LogModule Log("boo::ApplicationXCB");
|
||||
static LogVisor::LogModule Log("boo::ApplicationXlib");
|
||||
XlibCursors X_CURSORS;
|
||||
|
||||
int XCB_GLX_EVENT_BASE = 0;
|
||||
|
@ -266,7 +266,6 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
/* Create the fontset */
|
||||
char** missing_charsets;
|
||||
int num_missing_charsets = 0;
|
||||
char* default_string;
|
||||
|
@ -275,28 +274,14 @@ public:
|
|||
-misc-fixed-*-r-*-*-*-130-*-*-*-*-*-*",
|
||||
&missing_charsets, &num_missing_charsets,
|
||||
&default_string);
|
||||
/*
|
||||
* if there are charsets for which no fonts can
|
||||
* be found, print a warning message.
|
||||
*/
|
||||
if (num_missing_charsets > 0)
|
||||
{
|
||||
std::string warn("The following charsets are missing:\n");
|
||||
|
||||
for(int i=0 ; i<num_missing_charsets ; ++i)
|
||||
warn += std::string(missing_charsets[i]) + '\n';
|
||||
XFreeStringList(missing_charsets);
|
||||
warn += "The string '" + std::string(default_string) + "' will be used in place.";
|
||||
Log.report(LogVisor::Warning, warn.c_str());
|
||||
}
|
||||
|
||||
/* figure out which styles the IM can support */
|
||||
XIMStyles* im_supported_styles;
|
||||
XIMStyle app_supported_styles;
|
||||
XGetIMValues(m_xIM, XNQueryInputStyle, &im_supported_styles, nullptr);
|
||||
/* set flags for the styles our application can support */
|
||||
app_supported_styles = XIMPreeditNone | XIMPreeditNothing | XIMPreeditArea;
|
||||
app_supported_styles |= XIMStatusNone | XIMStatusNothing | XIMStatusArea;
|
||||
app_supported_styles = XIMPreeditNone | XIMPreeditNothing | XIMPreeditPosition;
|
||||
app_supported_styles |= XIMStatusNone | XIMStatusNothing;
|
||||
/*
|
||||
* now look at each of the IM supported styles, and
|
||||
* chose the "best" one that we can support.
|
||||
|
|
|
@ -185,7 +185,7 @@ struct WindowWayland : IWindow
|
|||
|
||||
}
|
||||
|
||||
void claimKeyboardFocus()
|
||||
void claimKeyboardFocus(const int coord[2])
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,18 @@ void GLXEnableVSync(Display* disp, GLXWindow drawable);
|
|||
|
||||
extern int XINPUT_OPCODE;
|
||||
|
||||
static uint32_t translateKeysym(XKeyEvent* ev, ESpecialKey& specialSym, EModifierKey& modifierSym, XIC xIC)
|
||||
static std::string translateUTF8(XKeyEvent* ev, XIC xIC)
|
||||
{
|
||||
char chs[512];
|
||||
KeySym ks;
|
||||
Status stat;
|
||||
int len = Xutf8LookupString(xIC, ev, chs, 512, &ks, &stat);
|
||||
if (len > 1 && (stat == XLookupChars || stat == XLookupBoth))
|
||||
return std::string(chs, len);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static char translateKeysym(XKeyEvent* ev, ESpecialKey& specialSym, EModifierKey& modifierSym)
|
||||
{
|
||||
KeySym sym = XLookupKeysym(ev, 0);
|
||||
|
||||
|
@ -112,21 +123,10 @@ static uint32_t translateKeysym(XKeyEvent* ev, ESpecialKey& specialSym, EModifie
|
|||
modifierSym = EModifierKey::Alt;
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
unsigned n;
|
||||
XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
|
||||
uint32_t utf = xkb_keysym_to_utf32(sym);
|
||||
if ((n & 0x01) != 0 ^ (state & ShiftMask) != 0)
|
||||
return toupper(utf);
|
||||
else
|
||||
return utf;
|
||||
#endif
|
||||
uint32_t utf = 0;
|
||||
KeySym sym;
|
||||
Status stat;
|
||||
XmbLookupString(xIC, ev, (char*)&utf, 4, &sym, &stat);
|
||||
if (stat == XLookupChars || stat == XLookupBoth)
|
||||
return utf;
|
||||
char ch = 0;
|
||||
KeySym ks;
|
||||
XLookupString(ev, (char*)&ch, 1, &ks, nullptr);
|
||||
return ch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -603,13 +603,17 @@ public:
|
|||
* Now go create an IC using the style we chose.
|
||||
* Also set the window and fontset attributes now.
|
||||
*/
|
||||
XVaNestedList list = XVaCreateNestedList(0, XNFontSet, fontset, nullptr);
|
||||
XPoint pt = {0,0};
|
||||
XVaNestedList nlist;
|
||||
m_xIC = XCreateIC(xIM, XNInputStyle, bestInputStyle,
|
||||
XNClientWindow, m_windowId,
|
||||
XNPreeditAttributes, list,
|
||||
XNStatusAttributes, list,
|
||||
XNFocusWindow, m_windowId,
|
||||
XNPreeditAttributes, nlist = XVaCreateNestedList(0,
|
||||
XNSpotLocation, &pt,
|
||||
XNFontSet, fontset,
|
||||
nullptr),
|
||||
nullptr);
|
||||
XFree(list);
|
||||
XFree(nlist);
|
||||
if (m_xIC == nullptr)
|
||||
{
|
||||
Log.report(LogVisor::FatalError, "Couldn't create input context.");
|
||||
|
@ -899,9 +903,20 @@ public:
|
|||
}
|
||||
} m_clipData;
|
||||
|
||||
void claimKeyboardFocus()
|
||||
void claimKeyboardFocus(const int coord[2])
|
||||
{
|
||||
XLockDisplay(m_xDisp);
|
||||
if (!coord)
|
||||
{
|
||||
XUnsetICFocus(m_xIC);
|
||||
XUnlockDisplay(m_xDisp);
|
||||
return;
|
||||
}
|
||||
getWindowFrame(m_wx, m_wy, m_ww, m_wh);
|
||||
XPoint pt = {short(coord[0]), short(m_wh - coord[1])};
|
||||
XVaNestedList list = XVaCreateNestedList(0, XNSpotLocation, &pt, nullptr);
|
||||
XSetICValues(m_xIC, XNPreeditAttributes, list, nullptr);
|
||||
XFree(list);
|
||||
XSetICFocus(m_xIC);
|
||||
XUnlockDisplay(m_xDisp);
|
||||
}
|
||||
|
@ -998,63 +1013,12 @@ public:
|
|||
reply.xselection.property = se->property;
|
||||
if (se->target == S_ATOMS->m_targets)
|
||||
{
|
||||
#if 0
|
||||
if (se->selection == XA_PRIMARY)
|
||||
{
|
||||
std::vector<Atom> x(sel_formats.GetCount());
|
||||
for (int i=0 ; i<sel_formats.GetCount() ; ++i)
|
||||
{
|
||||
x[i] = XAtom(sel_formats[i]);
|
||||
}
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, XA_ATOM,
|
||||
32, 0, (unsigned char*)x.data(),
|
||||
sel_formats.GetCount());
|
||||
}
|
||||
else if (se->selection == S_ATOMS->m_clipboard)
|
||||
{
|
||||
std::vector<Atom> x(data.GetCount());
|
||||
for (int i=0 ; i<data.GetCount() ; ++i)
|
||||
{
|
||||
x[i] = data.GetKey(i);
|
||||
}
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, XA_ATOM,
|
||||
32, 0, (unsigned char*)x.data(),
|
||||
data.GetCount());
|
||||
}
|
||||
#endif
|
||||
Atom ValidTargets[] = {GetClipboardTypeAtom(m_clipData.m_type)};
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, XA_ATOM,
|
||||
32, 0, (unsigned char*)ValidTargets, m_clipData.m_type != EClipboardType::None);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (se->selection == XA_PRIMARY)
|
||||
{
|
||||
String fmt = XAtomName(se->target);
|
||||
int i = sel_formats.Find(fmt);
|
||||
if (i >= 0 && sel_ctrl)
|
||||
{
|
||||
String d = sel_ctrl->GetSelectionData(fmt);
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, se->target, 8, PropModeReplace,
|
||||
d, d.GetLength());
|
||||
}
|
||||
else
|
||||
reply.xselection.property = 0;
|
||||
}
|
||||
else if (se->selection == S_ATOMS->m_clipboard)
|
||||
{
|
||||
int i = data.Find(se->target);
|
||||
if (i >= 0)
|
||||
{
|
||||
String d = data[i].Render();
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, se->target, 8, PropModeReplace,
|
||||
d, d.GetLength());
|
||||
}
|
||||
else
|
||||
reply.xselection.property = 0;
|
||||
}
|
||||
#endif
|
||||
if (se->target == GetClipboardTypeAtom(m_clipData.m_type))
|
||||
{
|
||||
XChangeProperty(m_xDisp, se->requestor, se->property, se->target, 8, PropModeReplace,
|
||||
|
@ -1256,27 +1220,6 @@ public:
|
|||
m_ww = event->xconfigure.width;
|
||||
m_wh = event->xconfigure.height;
|
||||
|
||||
if (m_bestStyle & XIMPreeditArea)
|
||||
{
|
||||
XRectangle preedit_area;
|
||||
preedit_area.width = event->xconfigure.width*4/5;
|
||||
preedit_area.height = 0;
|
||||
GetPreferredGeometry(XNPreeditAttributes, &preedit_area);
|
||||
preedit_area.x = event->xconfigure.width - preedit_area.width;
|
||||
preedit_area.y = event->xconfigure.height - preedit_area.height;
|
||||
SetGeometry(XNPreeditAttributes, &preedit_area);
|
||||
}
|
||||
if (m_bestStyle & XIMStatusArea)
|
||||
{
|
||||
XRectangle status_area;
|
||||
status_area.width = event->xconfigure.width/5;
|
||||
status_area.height = 0;
|
||||
GetPreferredGeometry(XNStatusAttributes, &status_area);
|
||||
status_area.x = 0;
|
||||
status_area.y = event->xconfigure.height - status_area.height;
|
||||
SetGeometry(XNStatusAttributes, &status_area);
|
||||
}
|
||||
|
||||
if (m_callback)
|
||||
{
|
||||
SWindowRect rect =
|
||||
|
@ -1293,7 +1236,13 @@ public:
|
|||
EModifierKey modifierKey;
|
||||
unsigned int state = event->xkey.state;
|
||||
event->xkey.state &= ~ControlMask;
|
||||
uint32_t charCode = translateKeysym(&event->xkey, specialKey, modifierKey, m_xIC);
|
||||
std::string utf8Frag = translateUTF8(&event->xkey, m_xIC);
|
||||
if (utf8Frag.size())
|
||||
{
|
||||
m_callback->utf8FragmentDown(utf8Frag);
|
||||
return;
|
||||
}
|
||||
char charCode = translateKeysym(&event->xkey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(state);
|
||||
if (charCode)
|
||||
m_callback->charKeyDown(charCode, modifierMask, false);
|
||||
|
@ -1312,7 +1261,7 @@ public:
|
|||
EModifierKey modifierKey;
|
||||
unsigned int state = event->xkey.state;
|
||||
event->xkey.state &= ~ControlMask;
|
||||
uint32_t charCode = translateKeysym(&event->xkey, specialKey, modifierKey, m_xIC);
|
||||
char charCode = translateKeysym(&event->xkey, specialKey, modifierKey);
|
||||
EModifierKey modifierMask = translateModifiers(state);
|
||||
if (charCode)
|
||||
m_callback->charKeyUp(charCode, modifierMask);
|
||||
|
|
Loading…
Reference in New Issue