#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#define NEED_EVENTS
#include "Xlibint.h"
#include "Xlcint.h"
#include "XlcGeneric.h"
#ifndef MAXINT
#define MAXINT (~((unsigned int)1 << (8 * sizeof(int)) - 1))
#endif
typedef struct _StaticXIM *StaticXIM;
typedef struct _XIMStaticXIMRec {
XlcConv ctom_conv;
XlcConv ctow_conv;
} XIMStaticXIMRec;
typedef enum {
CREATE_IC = 1,
SET_ICVAL = 2,
GET_ICVAL = 3
} XICOp_t;
typedef struct _StaticXIM {
XIMMethods methods;
XIMCoreRec core;
XIMStaticXIMRec *private;
} StaticXIMRec;
static Status _CloseIM(
XIM
);
static char *_SetIMValues(
XIM, XIMArg *
);
static char *_GetIMValues(
XIM, XIMArg*
);
static XIC _CreateIC(
XIM, XIMArg*
);
static _Xconst XIMMethodsRec local_im_methods = {
_CloseIM,
_SetIMValues,
_GetIMValues,
_CreateIC,
NULL,
NULL
};
static void _DestroyIC(
XIC
);
static void _SetFocus(
XIC
);
static void _UnsetFocus(
XIC
);
static char* _SetICValues(
XIC, XIMArg *
);
static char* _GetICValues(
XIC, XIMArg *
);
static char *_MbReset(
XIC
);
static wchar_t *_WcReset(
XIC
);
static int _MbLookupString(
XIC, XKeyEvent *, char *, int, KeySym *, Status *
);
static int _WcLookupString(
XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *
);
static _Xconst XICMethodsRec local_ic_methods = {
_DestroyIC,
_SetFocus,
_UnsetFocus,
_SetICValues,
_GetICValues,
_MbReset,
_WcReset,
NULL,
_MbLookupString,
_WcLookupString,
NULL
};
XIM
_XDefaultOpenIM(
XLCd lcd,
Display *dpy,
XrmDatabase rdb,
char *res_name,
char *res_class)
{
StaticXIM im;
XIMStaticXIMRec *local_impart;
XlcConv ctom_conv, ctow_conv;
int i;
char *mod;
char buf[BUFSIZ];
if (!(ctom_conv = _XlcOpenConverter(lcd,
XlcNCompoundText, lcd, XlcNMultiByte))) {
return((XIM)NULL);
}
if (!(ctow_conv = _XlcOpenConverter(lcd,
XlcNCompoundText, lcd, XlcNWideChar))) {
return((XIM)NULL);
}
if ((im = (StaticXIM)Xmalloc(sizeof(StaticXIMRec))) == (StaticXIM)NULL) {
return((XIM)NULL);
}
if ((local_impart = (XIMStaticXIMRec*)Xmalloc(sizeof(XIMStaticXIMRec)))
== (XIMStaticXIMRec *)NULL) {
Xfree(im);
return((XIM)NULL);
}
memset(im, 0, sizeof(StaticXIMRec));
memset(local_impart, 0, sizeof(XIMStaticXIMRec));
buf[0] = '\0';
i = 0;
if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
#define MODIFIER "@im="
mod = strstr(lcd->core->modifiers, MODIFIER);
if (mod) {
mod += strlen(MODIFIER);
while (*mod && *mod != '@' && i < BUFSIZ - 1) {
buf[i++] = *mod++;
}
buf[i] = '\0';
}
}
#undef MODIFIER
if ((im->core.im_name = Xmalloc(i+1)) == NULL)
goto Error2;
strcpy(im->core.im_name, buf);
im->private = local_impart;
im->methods = (XIMMethods)&local_im_methods;
im->core.lcd = lcd;
im->core.ic_chain = (XIC)NULL;
im->core.display = dpy;
im->core.rdb = rdb;
im->core.res_name = NULL;
im->core.res_class = NULL;
local_impart->ctom_conv = ctom_conv;
local_impart->ctow_conv = ctow_conv;
if ((res_name != NULL) && (*res_name != '\0')){
im->core.res_name = (char *)Xmalloc(strlen(res_name)+1);
strcpy(im->core.res_name,res_name);
}
if ((res_class != NULL) && (*res_class != '\0')){
im->core.res_class = (char *)Xmalloc(strlen(res_class)+1);
strcpy(im->core.res_class,res_class);
}
return (XIM)im;
Error2 :
Xfree(im->private);
Xfree(im->core.im_name);
Xfree(im);
_XlcCloseConverter(ctom_conv);
_XlcCloseConverter(ctow_conv);
return(NULL);
}
static Status
_CloseIM(XIM xim)
{
StaticXIM im = (StaticXIM)xim;
_XlcCloseConverter(im->private->ctom_conv);
_XlcCloseConverter(im->private->ctow_conv);
XFree(im->private);
XFree(im->core.im_name);
if (im->core.res_name) XFree(im->core.res_name);
if (im->core.res_class) XFree(im->core.res_class);
return 1;
}
static char *
_SetIMValues(
XIM xim,
XIMArg *arg)
{
return(arg->name);
}
static char *
_GetIMValues(
XIM xim,
XIMArg *values)
{
XIMArg *p;
XIMStyles *styles;
for (p = values; p->name != NULL; p++) {
if (strcmp(p->name, XNQueryInputStyle) == 0) {
styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
*(XIMStyles **)p->value = styles;
styles->count_styles = 1;
styles->supported_styles =
(XIMStyle*)Xmalloc(styles->count_styles * sizeof(XIMStyle));
styles->supported_styles[0] = (XIMPreeditNone | XIMStatusNone);
} else {
break;
}
}
return (p->name);
}
static char*
_SetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
{
XIMArg *p;
char *return_name = NULL;
for (p = values; p != NULL && p->name != NULL; p++) {
if(strcmp(p->name, XNInputStyle) == 0) {
if (mode == CREATE_IC)
ic->core.input_style = (XIMStyle)p->value;
} else if (strcmp(p->name, XNClientWindow) == 0) {
ic->core.client_window = (Window)p->value ;
} else if (strcmp(p->name, XNFocusWindow) == 0) {
ic->core.focus_window = (Window)p->value ;
} else if (strcmp(p->name, XNPreeditAttributes) == 0
|| strcmp(p->name, XNStatusAttributes) == 0) {
return_name = _SetICValueData(ic, (XIMArg*)p->value, mode);
if (return_name) break;
} else {
return_name = p->name;
break;
}
}
return(return_name);
}
static char*
_GetICValueData(XIC ic, XIMArg *values, XICOp_t mode)
{
XIMArg *p;
char *return_name = NULL;
for (p = values; p->name != NULL; p++) {
if(strcmp(p->name, XNInputStyle) == 0) {
*((XIMStyle *)(p->value)) = ic->core.input_style;
} else if (strcmp(p->name, XNClientWindow) == 0) {
*((Window *)(p->value)) = ic->core.client_window;
} else if (strcmp(p->name, XNFocusWindow) == 0) {
*((Window *)(p->value)) = ic->core.focus_window;
} else if (strcmp(p->name, XNFilterEvents) == 0) {
*((unsigned long *)(p->value))= ic->core.filter_events;
} else if (strcmp(p->name, XNPreeditAttributes) == 0
|| strcmp(p->name, XNStatusAttributes) == 0) {
return_name = _GetICValueData(ic, (XIMArg*)p->value, mode);
if (return_name) break;
} else {
return_name = p->name;
break;
}
}
return(return_name);
}
static XIC
_CreateIC(XIM im, XIMArg *arg)
{
XIC ic;
if ((ic = (XIC)Xmalloc(sizeof(XICRec))) == (XIC)NULL) {
return ((XIC)NULL);
}
memset(ic, 0, sizeof(XICRec));
ic->methods = (XICMethods)&local_ic_methods;
ic->core.im = im;
ic->core.filter_events = KeyPressMask;
if (_SetICValueData(ic, arg, CREATE_IC) != NULL)
goto err_return;
if (!(ic->core.input_style))
goto err_return;
return (XIC)ic;
err_return:
XFree(ic);
return ((XIC)NULL);
}
static void
_DestroyIC(XIC ic)
{
}
static void
_SetFocus(XIC ic)
{
}
static void
_UnsetFocus(XIC ic)
{
}
static char*
_SetICValues(XIC ic, XIMArg *args)
{
char *ret = NULL;
if (!ic) {
return (args->name);
}
ret = _SetICValueData(ic, args, SET_ICVAL);
return(ret);
}
static char*
_GetICValues(XIC ic, XIMArg *args)
{
char *ret = NULL;
if (!ic) {
return (args->name);
}
ret = _GetICValueData(ic, args, GET_ICVAL);
return(ret);
}
static char *
_MbReset(XIC xic)
{
return(NULL);
}
static wchar_t *
_WcReset(XIC xic)
{
return(NULL);
}
static int
_MbLookupString(
XIC xic,
XKeyEvent *ev,
char * buffer,
int bytes,
KeySym *keysym,
Status *status)
{
XComposeStatus NotSupportedYet ;
int length;
length = XLookupString(ev, buffer, bytes, keysym, &NotSupportedYet);
if (keysym && *keysym == NoSymbol){
*status = XLookupNone;
} else if (length > 0) {
*status = XLookupBoth;
} else {
*status = XLookupKeySym;
}
return(length);
}
static int
_WcLookupString(
XIC xic,
XKeyEvent *ev,
wchar_t * buffer,
int wlen,
KeySym *keysym,
Status *status)
{
XComposeStatus NotSupportedYet ;
int length;
char *mb_buf = (char *)Xmalloc(wlen);
length = XLookupString(ev, mb_buf, wlen, keysym, &NotSupportedYet);
if (keysym && *keysym == NoSymbol){
*status = XLookupNone;
} else if (length > 0) {
*status = XLookupBoth;
} else {
*status = XLookupKeySym;
}
mbstowcs(buffer, mb_buf, length);
XFree(mb_buf);
return(length);
}