/* ***************************************************************************** Copyright (c) Digital Equipment Corporation, 1994 All Rights Reserved. Unpublished rights reserved under the copyright laws of the United States. The software contained on this media is proprietary to and embodies the confidential technology of Digital Equipment Corporation. Possession, use, duplication or dissemination of the software and media is authorized only pursuant to a valid written license from Digital Equipment Corporation. RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. Government is subject to restrictions as set forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. ***************************************************************************** * * IMS_example.c * * This is an example of how to write an Input Method Server for X11R5 * In this example, there are only 26 composed characters, which are * formed by 2 consecutive key inputs which are equal. These key inputs * should be from a-z, case insensitive. The lookup string * will be found from an array, which is some kind of small-scale dictionary. * * You should load Iso-latin 1 keymap files in order to work properly for * this example. * * You can start this example using four of the languages: * Korean, Traditional Chinese, Simplied Chinese and Japanese * * To start this IMServer, set the xnllanguage resource properly, for example, * if you want to input Korean text, you should set the session language to * Korean, or simply start as * $IMS_example -xnllanguage "ko_KR.deckorean" * * To connect a client to this IMS, simply start up this IMS as a background * job, then start the client with the correct language setting and XMODIFIERS * environment. For example, * %define XMODIFIERS "@im=exam" * %mc decw$cardfiler -xnllanguage "ko_KR.deckorean" */ #include #include #ifdef VMS #include #else #include #endif static char my_dictionary[26][2] = {0xa1, 0xa1, 0xa1, 0xa2, 0xa1, 0xa3, 0xa1, 0xa4, 0xa1, 0xa5, 0xa1, 0xa6, 0xa1, 0xa7, 0xa1, 0xa8, 0xa1, 0xa9, 0xa1, 0xaa, 0xa1, 0xab, 0xa1, 0xac, 0xa1, 0xad, 0xa1, 0xae, 0xa1, 0xaf, 0xa1, 0xb1, 0xa1, 0xb2, 0xa1, 0xb3, 0xa1, 0xb4, 0xa1, 0xb5, 0xa1, 0xb6, 0xa1, 0xb7, 0xa1, 0xb8, 0xa1, 0xb9, 0xa1, 0xba, 0xa1, 0xbb}; typedef struct { char data[1]; int num_char; } MyDataRec, *MyData; /* This is the input context specific data */ static int CreateICCallback(w, client_data, widget_data) Widget w; Opaque *client_data; Opaque **widget_data; { MyData my_data = (MyData)XtMalloc(sizeof(MyDataRec)); if (!my_data) return 0; /* fail */ my_data->num_char = 0; *widget_data = (Opaque *)my_data; return 1; /* success */ } static int DestroyICCallback(w, client_data, widget_data) Widget w; Opaque *client_data; { MyData my_data = (MyData)DIMsUserData(w); if (my_data) XtFree((char *)my_data); return 1; /* success */ } static int GetFilterEventsCallback(w, client_data, mask) Widget w; Opaque *client_data; unsigned long **mask; { *mask = (unsigned long *) XtMalloc(sizeof(unsigned long)); /* Since this IMS supports root-window style only, so just KeyPress events are necessary */ **mask = (unsigned long)(KeyPressMask); } static int ProcessEventCallback(w, client_data, event, send_back) Widget w; Opaque *client_data; XEvent *event; Boolean *send_back; { MyData my_data = (MyData)DIMsUserData(w); Display *dpy = XtDisplay(w); *send_back = True; switch (event->type) { case KeyPress : { KeyCode keycode = event->xkey.keycode; KeySym keysym; char second_char; XTextProperty text_property; char *text_list[1]; char text[3]; keysym = XKeycodeToKeysym( dpy, keycode, 0 ); if ((keysym >= XK_A && keysym <= XK_Z) || (keysym >= XK_a && keysym <=XK_z)) { if (my_data->num_char) { if (keysym >= XK_a) second_char = keysym - XK_a; else second_char = keysym - XK_A; if (second_char == my_data->data[0]) { /* two consecutive key are equal, send commit string */ text[0] = my_dictionary[second_char][0]; text[1] = my_dictionary[second_char][1]; text[2] = '\0'; text_list[0] = text; XmbTextListToTextProperty(dpy, text_list, 1, XCompoundTextStyle, &text_property); DIMsCommit(w, (char *)text_property.value, strlen((char *)text_property.value)+1); XtFree((char *)text_property.value); *send_back = False; /* the key is used by IMS, no need to return to client */ } my_data->num_char = 0; /* reset to 0*/ } else { my_data->num_char = 1; if (keysym >= XK_a) my_data->data[0] = keysym - XK_a; else my_data->data[1] = keysym - XK_A; *send_back = False; } } break; } default : break; } } main(argc, argv) int argc; char **argv; { Widget toplevel; XtAppContext app_context; DIMsClassCtx zh_tw_ctx, ja_jp_ctx, zh_cn_ctx, ko_kr_ctx; char *server_strings[] = {"exam"}; XIMStyle support_styles[1] = {XIMPreeditNothing | XIMStatusNothing}; DIMsLocaleInfoRec locale; DIMsStringListRec server_names; DIMsSupportStylesRec im_styles; Cardinal n; Arg al[30]; XtSetLanguageProc(NULL, NULL, NULL); toplevel = XtAppInitialize(&app_context, "example", NULL, 0, &argc, argv, NULL, NULL, 0); /* set up DIMs Class */ /* This example targets to work for 4 locales: zh_TW, ja_JP, zh_CN, ko_KR Therefore 4 DIMs class contexts are created */ /* create contexts for locales zh_TW, ja_JP, zh_CN, ko_KR */ locale.language = "zh_TW"; locale.num_support_codesets = 0; locale.support_codesets = NULL; server_names.num_of_strings = 1; server_names.string_names = server_strings; im_styles.num_support_styles = 1; im_styles.support_styles = support_styles; n = 0; XtSetArg( al[n], DIMsNlocale, &locale);n++; XtSetArg( al[n], DIMsNserverName, &server_names);n++; XtSetArg( al[n], DIMsNsupportStyles, &im_styles);n++; XtSetArg( al[n], DIMsNcreateICCb, CreateICCallback);n++; XtSetArg( al[n], DIMsNdestroyICCb, DestroyICCallback);n++; XtSetArg( al[n], DIMsNprocessEventCb, ProcessEventCallback);n++; XtSetArg( al[n], DIMsNgetFilterEventsCb, GetFilterEventsCallback);n++; zh_tw_ctx = DIMsClassCtxCreate(NULL, "zh_tw_exam", al, n); locale.language = "ja_JP"; XtSetArg( al[0], DIMsNlocale, &locale); ja_jp_ctx = DIMsClassCtxCreate(zh_tw_ctx, "ja_jp_exam", al, n); locale.language = "zh_CN"; XtSetArg( al[0], DIMsNlocale, &locale); zh_cn_ctx = DIMsClassCtxCreate(zh_tw_ctx, "zh_cn_exam", al, n); locale.language = "ko_KR"; XtSetArg( al[0], DIMsNlocale, &locale); ko_kr_ctx = DIMsClassCtxCreate(zh_tw_ctx, "ko_kr_exam", al, n); /* Initialize IMSSL */ DIMsSLInitialize(toplevel, zh_tw_ctx); /* Realize widget hierrachy */ XtRealizeWidget(toplevel); /* Initialize protocol layer */ DIMsProtoInit(toplevel, app_context); XtAppMainLoop(app_context); }