X-Git-Url: https://repo.or.cz/w/wmaker-crm.git/blobdiff_plain/59fc927dc9f183802621138534fa6eaafe5593ba..688a56e8ab67b56550e2874d9d7423f0d435bfd9:/WINGs/winputmethod.c diff --git a/WINGs/winputmethod.c b/WINGs/winputmethod.c dissimilarity index 96% index 79b17fec..01ecdc70 100644 --- a/WINGs/winputmethod.c +++ b/WINGs/winputmethod.c @@ -1,241 +1,211 @@ - - -#include - -#include "WINGsP.h" - - -typedef struct W_IMContext { - XIM xim; - XIMStyle ximstyle; -} WMIMContext; - - - -static void -instantiateIM_cb(Display *display, XPointer client_data, XPointer call_data) -{ - W_InitIM((W_Screen *)client_data); -} - - -static void -destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data) -{ - W_Screen *scr = (W_Screen *)client_data; - W_View *target; - - if (scr->imctx->xim != xim) - return; - - target = scr->rootView->childrenList; - while (target!=NULL) { - W_DestroyIC(target); - target = target->nextSister; - } - - wfree(scr->imctx); - scr->imctx = NULL; - - XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, - instantiateIM_cb, (XPointer)scr); -} - - -void -W_InitIM(W_Screen *scr) -{ - XIM xim; - - if (scr->imctx) - return; - - xim = XOpenIM(scr->display, NULL, NULL, NULL); - - if (xim) { - XIMStyles *im_styles; - XIMCallback cb; - int i; - - scr->imctx = wmalloc(sizeof(WMIMContext)); - scr->imctx->xim = xim; - - cb.callback = destroyIM_cb; - cb.client_data = (XPointer)scr; - if (XSetIMValues(scr->imctx->xim, XNDestroyCallback, &cb, NULL)) - wwarning("could not add destroy callback for input method"); - XUnregisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, - instantiateIM_cb, (XPointer)scr); - /* Get available input style */ - XGetIMValues(scr->imctx->xim, XNQueryInputStyle, &im_styles, NULL); - - scr->imctx->ximstyle = 0; - - for (i=0; icount_styles && scr->imctx->ximstyle==0; i++) { - if ((im_styles->supported_styles[i] & XIMPreeditPosition) && - (im_styles->supported_styles[i] & XIMStatusNothing)) { - scr->imctx->ximstyle = XIMPreeditPosition | XIMStatusNothing; - } else if ((im_styles->supported_styles[i] & XIMPreeditNothing) && - (im_styles->supported_styles[i] & XIMStatusNothing)) { - scr->imctx->ximstyle = XIMPreeditNothing | XIMStatusNothing; - } - } - XFree(im_styles); - } else { - XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, - instantiateIM_cb, (XPointer)scr); - } -} - - -void -W_CreateIC(WMView *view) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - XVaNestedList preedit_attr = NULL; - - if (view->xic || !view->flags.realized || !scr->imctx) - return; - - if (scr->imctx->ximstyle & XIMPreeditPosition) { - XPoint spot; - XRectangle rect; - int ofs; - - ofs = (view->size.height - WMFontHeight(scr->normalFont))/2; - - rect.x = ofs; - rect.y = ofs; - rect.height = WMFontHeight(scr->normalFont); - rect.width = view->size.width - ofs*2; - spot.x = rect.x; - spot.y = rect.y + rect.height; - - // this really needs to be changed, but I don't know how yet -Dan - // it used to be like this with fontsets, but no longer applies to xft - preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, - XNArea, &rect, XNFontInfo, - scr->normalFont->font, NULL); - } - - view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle, - XNClientWindow, view->window, - preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, - NULL); - - if (preedit_attr) - XFree(preedit_attr); - - if (view->xic) { - unsigned long fevent = 0; - XGetICValues(view->xic, XNFilterEvents, &fevent, NULL); - XSelectInput(scr->display, view->window, - ButtonPressMask | ButtonReleaseMask | ExposureMask | - KeyPressMask | FocusChangeMask| ButtonMotionMask |fevent); - } -} - - -void -W_DestroyIC(WMView *view) -{ - if (view->xic) { - XDestroyIC(view->xic); - view->xic = 0; - } -} - - -static void -setPreeditArea(W_View *view) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - XVaNestedList preedit_attr = NULL; - - if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) { - XRectangle rect; - int ofs; - - ofs = (view->size.height - WMFontHeight(scr->normalFont))/2; - rect.x = ofs; - rect.y = ofs; - rect.height = WMFontHeight(scr->normalFont); - rect.width = view->size.width - ofs*2; - - preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL); - XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL); - - if (preedit_attr) { - XFree(preedit_attr); - } - } -} - - -void -W_FocusIC(WMView *view) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - - if (view->xic) { - XSetICFocus(view->xic); - XSetICValues(view->xic, XNFocusWindow, view->window, NULL); - - if (scr->imctx->ximstyle & XIMPreeditPosition) { - setPreeditArea(view); - } - } -} - - -void -W_UnFocusIC(WMView *view) -{ - if (view->xic) { - XUnsetICFocus(view->xic); - } -} - - -void -W_SetPreeditPositon(W_View *view, int x, int y) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - XVaNestedList preedit_attr = NULL; - - if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) { - XPoint spot; - int ofs; - - ofs = (view->size.height - WMFontHeight(scr->normalFont))/2; - spot.x = x; - spot.y = y + view->size.height - ofs - 3; - preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); - XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL); - if (preedit_attr) { - XFree(preedit_attr); - } - } -} - - -int -W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer, int buflen, - KeySym *keysym, Status *status) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - - XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime); - - if (view->xic) { -#ifdef X_HAVE_UTF8_STRING - return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status); -#else - return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *)status); -#endif - } else { - return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *)status); - } -} - - + +#include + +#include "WINGsP.h" + +typedef struct W_IMContext { + XIM xim; + XIMStyle ximstyle; +} WMIMContext; + +static void instantiateIM_cb(Display * display, XPointer client_data, XPointer call_data) +{ + W_InitIM((W_Screen *) client_data); +} + +static void destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data) +{ + W_Screen *scr = (W_Screen *) client_data; + W_View *target; + + if (scr->imctx->xim != xim) + return; + + target = scr->rootView->childrenList; + while (target != NULL) { + W_DestroyIC(target); + target = target->nextSister; + } + + wfree(scr->imctx); + scr->imctx = NULL; + + XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr); +} + +void W_InitIM(W_Screen * scr) +{ + XIM xim; + + if (scr->imctx) + return; + + xim = XOpenIM(scr->display, NULL, NULL, NULL); + + if (xim) { + XIMStyles *im_styles; + XIMCallback cb; + int i; + + scr->imctx = wmalloc(sizeof(WMIMContext)); + scr->imctx->xim = xim; + + cb.callback = destroyIM_cb; + cb.client_data = (XPointer) scr; + if (XSetIMValues(scr->imctx->xim, XNDestroyCallback, &cb, NULL)) + wwarning("could not add destroy callback for input method"); + XUnregisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr); + /* Get available input style */ + XGetIMValues(scr->imctx->xim, XNQueryInputStyle, &im_styles, NULL); + + scr->imctx->ximstyle = 0; + + for (i = 0; i < im_styles->count_styles && scr->imctx->ximstyle == 0; i++) { + if ((im_styles->supported_styles[i] & XIMPreeditPosition) && + (im_styles->supported_styles[i] & XIMStatusNothing)) { + scr->imctx->ximstyle = XIMPreeditPosition | XIMStatusNothing; + } else if ((im_styles->supported_styles[i] & XIMPreeditNothing) && + (im_styles->supported_styles[i] & XIMStatusNothing)) { + scr->imctx->ximstyle = XIMPreeditNothing | XIMStatusNothing; + } + } + XFree(im_styles); + } else { + XRegisterIMInstantiateCallback(scr->display, NULL, NULL, NULL, instantiateIM_cb, (XPointer) scr); + } +} + +void W_CreateIC(WMView * view) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + XVaNestedList preedit_attr = NULL; + + if (view->xic || !view->flags.realized || !scr->imctx) + return; + + if (scr->imctx->ximstyle & XIMPreeditPosition) { + XPoint spot; + XRectangle rect; + int ofs; + + ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2; + + rect.x = ofs; + rect.y = ofs; + rect.height = WMFontHeight(scr->normalFont); + rect.width = view->size.width - ofs * 2; + spot.x = rect.x; + spot.y = rect.y + rect.height; + + // this really needs to be changed, but I don't know how yet -Dan + // it used to be like this with fontsets, but no longer applies to xft + preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, + XNArea, &rect, XNFontInfo, scr->normalFont->font, NULL); + } + + view->xic = XCreateIC(scr->imctx->xim, XNInputStyle, scr->imctx->ximstyle, + XNClientWindow, view->window, + preedit_attr ? XNPreeditAttributes : NULL, preedit_attr, NULL); + + if (preedit_attr) + XFree(preedit_attr); + + if (view->xic) { + unsigned long fevent = 0; + XGetICValues(view->xic, XNFilterEvents, &fevent, NULL); + XSelectInput(scr->display, view->window, + ButtonPressMask | ButtonReleaseMask | ExposureMask | + KeyPressMask | FocusChangeMask | ButtonMotionMask | fevent); + } +} + +void W_DestroyIC(WMView * view) +{ + if (view->xic) { + XDestroyIC(view->xic); + view->xic = 0; + } +} + +static void setPreeditArea(W_View * view) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + XVaNestedList preedit_attr = NULL; + + if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) { + XRectangle rect; + int ofs; + + ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2; + rect.x = ofs; + rect.y = ofs; + rect.height = WMFontHeight(scr->normalFont); + rect.width = view->size.width - ofs * 2; + + preedit_attr = XVaCreateNestedList(0, XNArea, &rect, NULL); + XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL); + + if (preedit_attr) { + XFree(preedit_attr); + } + } +} + +void W_FocusIC(WMView * view) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + + if (view->xic) { + XSetICFocus(view->xic); + XSetICValues(view->xic, XNFocusWindow, view->window, NULL); + + if (scr->imctx->ximstyle & XIMPreeditPosition) { + setPreeditArea(view); + } + } +} + +void W_UnFocusIC(WMView * view) +{ + if (view->xic) { + XUnsetICFocus(view->xic); + } +} + +void W_SetPreeditPositon(W_View * view, int x, int y) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + XVaNestedList preedit_attr = NULL; + + if (view->xic && (scr->imctx->ximstyle & XIMPreeditPosition)) { + XPoint spot; + int ofs; + + ofs = (view->size.height - WMFontHeight(scr->normalFont)) / 2; + spot.x = x; + spot.y = y + view->size.height - ofs - 3; + preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + XSetICValues(view->xic, XNPreeditAttributes, preedit_attr, NULL); + if (preedit_attr) { + XFree(preedit_attr); + } + } +} + +int +W_LookupString(W_View * view, XKeyPressedEvent * event, char *buffer, int buflen, KeySym * keysym, Status * status) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + + XSetInputFocus(scr->display, view->window, RevertToParent, CurrentTime); + + if (view->xic) { +#ifdef X_HAVE_UTF8_STRING + return Xutf8LookupString(view->xic, event, buffer, buflen, keysym, status); +#else + return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status); +#endif + } else { + return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status); + } +}