1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-28 01:12:30 +01:00

added preliminary X Input Methods support

This commit is contained in:
dan
2004-10-28 04:17:18 +00:00
parent 79864ba94c
commit ca61675597
11 changed files with 245 additions and 46 deletions

View File

@@ -3,6 +3,8 @@ Changes since version 0.91.0:
- fixed crash with info panel and alt-tabbing - fixed crash with info panel and alt-tabbing
- updated Japanese translations (Takeo Hashimoto <HashimotoTakeo@mac.com>) - updated Japanese translations (Takeo Hashimoto <HashimotoTakeo@mac.com>)
- allow disable of switch panel when SwitchPanelImages=None - allow disable of switch panel when SwitchPanelImages=None
- added X Input Methods support in WINGs
Changes since version 0.90.0: Changes since version 0.90.0:
............................. .............................

View File

@@ -1047,6 +1047,8 @@ main(int argc, char **argv)
testColorPanel(scr); testColorPanel(scr);
testTextField(scr);
#if 0 #if 0
testBox(scr); testBox(scr);

View File

@@ -385,6 +385,7 @@ typedef struct W_View {
WMPixmap *dragImage; WMPixmap *dragImage;
int helpContext; int helpContext;
XIC xic;
struct { struct {
unsigned int realized:1; unsigned int realized:1;
@@ -612,6 +613,22 @@ void W_DragDestinationInfoClear(WMDraggingInfo *info);
void W_FreeViewXdndPart(WMView *view); void W_FreeViewXdndPart(WMView *view);
/* XIM */
void W_InitIM(WMScreen *scr);
void W_CreateIC(WMView *view);
void W_DestroyIC(WMView *view);
void W_FocusIC(WMView *view);
void W_UnFocusIC(WMView *view);
void W_SetPreeditPositon(W_View *view, int x, int y);
int W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer,
int buflen, KeySym *keysym, Status *status);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -53,7 +53,6 @@ W_ReadConfigurations(void)
if (defaults) { if (defaults) {
char *buttonName; char *buttonName;
unsigned button; unsigned button;
char *str;
WINGsConfiguration.systemFont = WINGsConfiguration.systemFont =
WMGetUDStringForKey(defaults, "SystemFont"); WMGetUDStringForKey(defaults, "SystemFont");

View File

@@ -213,6 +213,10 @@ WMHandleEvent(XEvent *event)
return True; return True;
} }
if (XFilterEvent(event, None) == True) {
return False;
}
mask = eventMasks[event->xany.type]; mask = eventMasks[event->xany.type];
window = event->xany.window; window = event->xany.window;

View File

@@ -631,9 +631,6 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
scrPtr->xftdraw = XftDrawCreate(scrPtr->display, W_DRAWABLE(scrPtr), scrPtr->xftdraw = XftDrawCreate(scrPtr->display, W_DRAWABLE(scrPtr),
scrPtr->visual, scrPtr->colormap); scrPtr->visual, scrPtr->colormap);
/* create input method stuff */
W_InitIMStuff(scrPtr);
/* Create missing CUT_BUFFERs */ /* Create missing CUT_BUFFERs */
{ {
Atom *rootWinProps; Atom *rootWinProps;
@@ -773,6 +770,9 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
return NULL; return NULL;
} }
/* create input method stuff */
W_InitIM(scrPtr);
scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON, scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON,
CHECK_BUTTON_ON_WIDTH, CHECK_BUTTON_ON_WIDTH,
CHECK_BUTTON_ON_HEIGHT, False); CHECK_BUTTON_ON_HEIGHT, False);

View File

@@ -5,83 +5,237 @@
#include "WINGsP.h" #include "WINGsP.h"
typedef struct W_IMContext { typedef struct W_IMContext {
XIM xim; XIM xim;
XIMStyle ximstyle;
struct W_ICContext *icList;
} WMIMContext; } WMIMContext;
typedef struct W_ICContext {
struct W_ICContext *next;
struct W_ICContext *prev;
XIC xic; static void
} WMICContext; instantiateIM_cb(Display *display, XPointer client_data, XPointer call_data)
Bool
W_InitIMStuff(WMScreen *scr)
{ {
WMIMContext *ctx; W_InitIM((W_Screen *)client_data);
}
ctx = scr->imctx = wmalloc(sizeof(WMIMContext));
ctx->xim = XOpenIM(scr->display, NULL, NULL, NULL); static void
if (ctx->xim == NULL) { destroyIM_cb(XIM xim, XPointer client_data, XPointer call_data)
wwarning("could not open IM"); {
return False; 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 void
W_CloseIMStuff(WMScreen *scr) W_InitIM(W_Screen *scr)
{ {
if (!scr->imctx) XIM xim;
if (scr->imctx)
return; return;
if (scr->imctx->xim) xim = XOpenIM(scr->display, NULL, NULL, NULL);
XCloseIM(scr->imctx->xim);
wfree(scr->imctx); if (xim) {
scr->imctx = NULL; 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
WMICContext*
W_CreateIC(WMView *view) W_CreateIC(WMView *view)
{ {
WMScreen *scr = W_VIEW_SCREEN(view); WMScreen *scr = W_VIEW_SCREEN(view);
WMICContext *ctx; XVaNestedList preedit_attr = NULL;
ctx->prev = NULL; if (view->xic || !view->flags.realized || !scr->imctx)
ctx->next = scr->imctx->icList; return;
if (scr->imctx->icList)
scr->imctx->icList->prev = ctx;
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 void
W_DestroyIC(WMICContext *ctx) W_DestroyIC(WMView *view)
{ {
XDestroyIC(ctx->xic); 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 int
W_LookupString(WMView *view, XKeyEvent *event, W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer, int buflen,
char buffer, int bufsize, KeySym ksym) 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);
}
} }

View File

@@ -672,6 +672,8 @@ handlePush(Scroller *sPtr, int pushX, int pushY, int alternate)
handleMotion(sPtr, pushX, pushY); */ handleMotion(sPtr, pushX, pushY); */
break; break;
case WSDecrementWheel:
case WSIncrementWheel:
case WSKnobSlot: case WSKnobSlot:
case WSNoPart: case WSNoPart:
/* dummy */ /* dummy */

View File

@@ -2299,6 +2299,7 @@ autoSelectText(Text *tPtr, int clicks)
} }
# if 0
static void static void
fontChanged(void *observerData, WMNotification *notification) fontChanged(void *observerData, WMNotification *notification)
{ {
@@ -2312,6 +2313,7 @@ fontChanged(void *observerData, WMNotification *notification)
if (tPtr->flags.ownsSelection) if (tPtr->flags.ownsSelection)
WMSetTextSelectionFont(tPtr, font); WMSetTextSelectionFont(tPtr, font);
} }
#endif
static void static void

View File

@@ -71,7 +71,7 @@ typedef struct W_TextField {
unsigned int waitingSelection:1; /* requested selection, but unsigned int waitingSelection:1; /* requested selection, but
* didnt get yet */ * didnt get yet */
/**/
unsigned int notIllegalMovement:1; unsigned int notIllegalMovement:1;
} flags; } flags;
} TextField; } TextField;
@@ -312,6 +312,13 @@ selectionNotification(void *observerData, WMNotification *notification)
} }
static void
realizeObserver(void *self, WMNotification *not)
{
W_CreateIC(((TextField*)self)->view);
}
WMTextField* WMTextField*
WMCreateTextField(WMWidget *parent) WMCreateTextField(WMWidget *parent)
{ {
@@ -364,6 +371,8 @@ WMCreateTextField(WMWidget *parent)
WMSelectionOwnerDidChangeNotification, WMSelectionOwnerDidChangeNotification,
(void*)XA_PRIMARY); (void*)XA_PRIMARY);
WMAddNotificationObserver(realizeObserver, tPtr,
WMViewRealizedNotification, tPtr->view);
tPtr->flags.cursorOn = 1; tPtr->flags.cursorOn = 1;
@@ -762,8 +771,11 @@ paintCursor(TextField *tPtr)
cx, tPtr->offsetWidth, cx, cx, tPtr->offsetWidth, cx,
tPtr->view->size.height - tPtr->offsetWidth - 1); tPtr->view->size.height - tPtr->offsetWidth - 1);
if (tPtr->flags.secure) W_SetPreeditPositon(tPtr->view, cx, 0);
if (tPtr->flags.secure) {
wfree(text); wfree(text);
}
} }
@@ -953,9 +965,9 @@ handleEvents(XEvent *event, void *data)
CHECK_CLASS(data, WC_TextField); CHECK_CLASS(data, WC_TextField);
switch (event->type) { switch (event->type) {
case FocusIn: case FocusIn:
W_FocusIC(tPtr->view);
if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view))!=tPtr->view) if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view))!=tPtr->view)
return; return;
tPtr->flags.focused = 1; tPtr->flags.focused = 1;
@@ -973,6 +985,7 @@ handleEvents(XEvent *event, void *data)
break; break;
case FocusOut: case FocusOut:
W_UnFocusIC(tPtr->view);
tPtr->flags.focused = 0; tPtr->flags.focused = 0;
#if 0 #if 0
if (tPtr->timerID) if (tPtr->timerID)
@@ -1021,7 +1034,8 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
controled = (event->xkey.state & ControlMask ? True : False); controled = (event->xkey.state & ControlMask ? True : False);
modified = shifted || controled; modified = shifted || controled;
count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL); count = W_LookupString(tPtr->view, &event->xkey, buffer, 63, &ksym, NULL);
//count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL);
buffer[count] = '\0'; buffer[count] = '\0';
switch (ksym) { switch (ksym) {
@@ -1613,6 +1627,8 @@ destroyTextField(TextField *tPtr)
WMDeleteTimerHandler(tPtr->timerID); WMDeleteTimerHandler(tPtr->timerID);
#endif #endif
W_DestroyIC(tPtr->view);
WMReleaseFont(tPtr->font); WMReleaseFont(tPtr->font);
/*// use lostSelection() instead of WMDeleteSelectionHandler here?*/ /*// use lostSelection() instead of WMDeleteSelectionHandler here?*/
WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime); WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime);

View File

@@ -130,6 +130,8 @@ createView(W_Screen *screen, W_View *parent)
adoptChildView(parent, view); adoptChildView(parent, view);
} }
view->xic = 0;
view->refCount = 1; view->refCount = 1;
view->eventHandlers = WMCreateArrayWithDestructor(4, wfree); view->eventHandlers = WMCreateArrayWithDestructor(4, wfree);
@@ -213,7 +215,6 @@ W_RealizeView(W_View *view)
assert(view->size.width > 0); assert(view->size.width > 0);
assert(view->size.height > 0); assert(view->size.height > 0);
if (view->parent && !view->parent->flags.realized) { if (view->parent && !view->parent->flags.realized) {
wwarning("trying to realize widget of unrealized parent"); wwarning("trying to realize widget of unrealized parent");
return; return;