IM Server Developers Kit - C Language Interface Hidetoshi Tajima X11R6 Xi18n Implementation Group May 15, 1994 1. Functions List 1.1. Open IM Servive XIMS IMOpenIM(Display display,...) display specifies the connection to the X server. ... specifies the variable length argument list to set IMValues. For further information, see the Section 2 "IMValues". IMOpenIM initializes the connection for the Input Method Service, and also sets one or more IMValues which are specified by a variable length argument list programming interface, and when succeeding to open the connection, IMOpenIM allocates a new XIMS structure and returns it, otherwise IMOpenIM returns NULL. XIMS is an opaque data structure to abstract the Input Method Service. First, IMOpenIM initializes a preconnection method by which clients can search for the IMserver. The convention of the preconnection varies with the IMProtocol model as below, however, you don't have to pay much attention to such difference, because IMOpenIM encapsulates it. Preconnection for R5 Ximp IMserver must create the selection owner window of the ATOM for the string, such as "_XIMP_%locale" or something, which are used by clients to search for the IMserver. Preconnection for R6 IMProtocol IMserver must create the selection owner window of the ATOM for the string, such as "@server=%im_name", and registers the ATOM with the list of "XIM_SERVERS" property of the default root window, which contains a list of ATOMs, each of which represents each available IMservers on the display. Second, IMOpenIM initialize a transport connection on which clients and the IMserver can send and receive IMProtocols with each other. The procedures to initialize the transport connection varies with the transport mechanism as below, however, you don't have to pay any attention to such difference, either, because IMOpenIM also encapsulates it. Transport connection for X IMserver must intern a number of ATOMs for the properties which are used to set some IMserver specific feature and characteristic. Transport connection for TCP/IP IMserver must open a listening socket to wait for connection request from clients. 1.2. Set IM Attributes char *IMSetIMValues(XIMS ims,...) ims specifies the input method service. ... specifies the variable length argument list to set IMValues. IMSetIMValues registers one or more IMValues, which are specified by a variable length argument list programming interface, with the XIMS structure. Note that IMOpenIM is also used to set all IMValues, and some IMValues must be set when IMOpenIM is called. IMSetIMValues returns NULL if it succeeds to set all the IMValues, otherwise, it returns the name of the first argument whose value could not be registered. 1.3. Get IM Attributes char *IMGetIMValues(XIMS ims,...) ims specifies the input method service. ... specifies the variable length argument list to get IMValues. IMGetIMValues gets one or more IMValues, which are specified by a variable length argument list programming interface, from the XIMS structure. IMGetIMValues returns NULL if it succeeds to get all the IMValues, otherwise, it returns the name of the first argument whose value could not be obtained. 1.4. Close IM Service void IMCloseIM(XIMS ims) ims specifies the input method service to be closed. IMCloseIM closes the connection which was opened by IMOpenIM. IMCloseIM frees all the allocated data in the XIMS structure, then frees the XIMS itself. 1.5. Start Preediting int IMPreeditStart(XIMS ims, XPointer im_protocol) ims specifies the input method service. im_protocol specifies the Input Protocol data. IMPreeditStart is used to start preeditting in case of Dynamic Event Flow. The structure for im_protocol varies with the IMProtocol models: /* R5 Ximp */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; } XIMPPreeditStateStruct; /* R6 IMProtocol */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; } IMPreeditStateStruct; 1.6. Stop Preediting int IMPreeditEnd(XIMS ims, XPointer im_protocol) ims specifies the input method service. im_protocol specifies the Input Protocol data. IMPreeditEnd is used to stop preeditting in case of Dynamic Event Flow. However, if you registered off-keys list using IMOffKeysList IMValue, you might not need to use IMPreeditEnd, because IMdkit calls IMPreeditEnd internally when it receives a key event matching one of the registered off-keys. So, you are greatly encouraged to use IMPreeditEnd only when you did *NOT* register any off-keys list. 1.7. Forward back KeyEvent void IMForwardEvent(XIMS ims, XPointer im_protocol) ims specifies the input method service. im_protocol specifies the Input Protocol data. IMForwardEvent is used to send back a non-filtered KeyPress/KeyRelease Event. The structure for im_protocol varies with the IMProtocol models: /* R5 Ximp */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; CARD32 keycode; CARD32 state; CARD32 time; } XIMPKeyEventStruct; /* R6 IMProtocol */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID */ BITMASK16 sync_bit; /* precessed synchronously or not */ CARD16 serial_number; XEvent event; /* X event to be filtered */ } IMForwardEventStruct; 1.8. Commit Conversion String void IMCommitString(XIMS ims, XPointer im_protocol) ims specifies the input method service. im_protocol specifies the Input Protocol data. IMCommitString is used to send a committed string, which may contain a localized text converted by the IMserver. The structure for im_protocol varies with the IMProtocol models: /* R5 Ximp */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; char *ctext; } XIMPCommitStringStruct; /* R6 IMProtocol */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID */ CARD16 flag; /* bit combination to tell the receiver what to do */ #0001 : process it synchroously, return XIM_SYNC_REPLY #0002 : Lookup Chars #0004 : Lookup KeySym #0006 : Lookup Both = Lookup Chars and KeySym */ KeySym keysym; /* returned keysym */ char *commit_string; /* string to commit to XIM client */ } IMCommitStruct; 1.9. Call Callback int IMCallCallback(XIMS ims, XPointer im_protocol) ims specifies the input method service. im_protocol specifies the Input Protocol data. IMCallCallback is used for your IMserver to send a callback request asynchronously with the previous IMProtocol request. The type of the callback request must be set in the proper members of the im_protocol data structure by your IMserver. In addition, it's up to you to declare a new IMProtocol structure before you begin the callback requests. The structures for im_protocol varies with the IMProtocol models: /* R6 IMProtocol */ The type of the callback request must be set in major_code and minor_code members in the IMProtocol structure, e.g., you can start geometry management callback as follows; IMGeometryCBStruct geometry; ... geometry.major_code = XIM_GEOMETRY; geometry.connect_id = previous_request->any.connect_id; ... IMCallCallback(ims, (IMProtocol)&geometry); The structures for R6 IMProtocol callbacks contain: /* for Geometry Callback */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; } IMGeometryCBStruct; /* for Preedit Callback */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; union { int return_value; /* PreeditStart */ XIMPreeditDrawCallbackStruct draw; /* PreeditDraw */ XIMPreeditCaretCallbackStruct caret; /* PreeditCaret */ } todo; } IMPreeditCBStruct; /* for Status Callback */ typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; union { XIMStatusDrawCallbackStruct draw; } todo; } IMStatusCBStruct; The structures for R5 Ximp callbacks contain: /* for Geometry Callback */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; } XIMPAnyStruct; /* for Preedit Callback */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; union { int return_value; /* PreeditStart */ XIMPreeditDrawCallbackStruct draw; /* PreeditDraw */ XIMPreeditCaretCallbackStruct caret; /* PreeditCaret */ } todo; } XIMPPreeditCBStruct; /* for Status Callback */ typedef struct { INT32 type; CARD32 icid; Window focus_win; long fwin_sel_mask; CARD32 ximp_type_mask; Window client_win; union { XIMStatusDrawCallbackStruct draw; /* StatusDraw */ } todo; } XIMPStatusCBStruct; 2. IMValues 2.1. IMModifiers The IMModifiers argument, of type string, specifies the name of the IMProtocol model. At the current release, only three names are accepted by IMdkit. "Xi18n" specifies the R6 standard IMProtocol model "XIMP" specifies the R5 Ximp model. The IMModifiers argument must be set only once when IMOpenIM is called, and never be changed on the fly. 2.2. IMServerWindow The IMServerWindow argument, of type Window, specifies the window which identifies a method of preconnection with XIM clients. In addition to this primary purpose, the IMServerWindow might be used for any other purposes, which depends on the IMProtocol model to be used. If this argument is unspecified, a default window might be provided by IMdkit, which depends on the IMProtocol model to be used, and if it is specified, it must be done only once by either IMOpenIM or IMSetIMValues, and never be changed on the fly. 2.3. IMServerName The IMServerName argument, of type string, specifies the name of the IMserver. This argument might be a part of the IMserver identifiers by which XIM clients will search for the IMserver. The IMServerName argument must be set only once when IMOpenIM is called, and never be changed on the fly. 2.4. IMLocale The IMLocale argument, of type string, specifies a list of locales the IMserver supports. This argument might be a part of the IMserver identifiers which is used for XIM clients to search for the IMserver. The IMLocale argument must be set only once when IMOpenIM is called, and never be changed on the fly. 2.5. IMServerTransport The IMServerTransport argument, of type string, specifies the name for the transport connection mechanism the IMserver uses. This argument might be a part of the IMserver identifiers which is used for XIM clients to search for the IMserver. The preregistered formats for this argument are as follows.(*1) (*1) Reter to "The Input Method Protocol", Appendix B: The list of transport specific IM Server address format registered TCP/IP Names ------------ Syntax for Internet domain names: ::= "tcp/"":" where is either symbolic or numeric decimal form of the host machine name, and is the port on which the IMserver is listening for connections. Syntax for system internal domain names: ::= "locale/"":" where is a path name of socket address. DECnet Names ------------ Syntax for DECnet names: ::= "decnet/""::IMSERVER$" where is either symbolic or numeric decimal form of the DECnet address, and is normal, case-insensitive DECnet object name. X Names ------- Syntax for X names: ::= "X/" The IMServerTransport argument must be set only once when IMOpenIM is called, and never be changed on the fly. 2.6. IMInputStyles The IMInputStyles argument, of type XIMStyles, specifies a list of the input styles the IMserver supports. If this argument is unspecified, a default list might be provided by IMdkit, which depends on the IMProtocol model to be used, and it can be set by either IMOpenIM or IMSetIMValues, but should not be changed on the fly. 2.7. IMProtocolHandler The IMProtocolHandler argument, of type IMProtoHandler, specifies the callback function which is called each time when IMMainLoop receives an IMProtocol input from XIM clients. The generic prototype of the IMProtocolHandler function is; typedef int (*IMProtoHandler)(); int ProtocolHandlerProc(ims, call_data) XIMS ims; XPointer call_data; call_data points to a IMProtocol structure. 2.8. IMOnKeysList The IMOnKeysList argument, of type XIMTriggerKeys, specifies the list of preediting start-keys for Dynamic Event Flow model. The IMOnKeysList IMValue is mandatary for IMserver to support Dynamic Event Flow Model, so that the IMlibrary can send the IMserver a request to start preediting with the apperance of one of these registered on-keys. If the IMOnKeysList is left unspecified, no default will be provided, and Static Event Flow model will be used. XIMTriggerKeys structure is defined by IMdkit as follows: typedef struct { CARD32 keysym; CARD32 modifier; CARD32 modifier_mask; } XIMTriggerKey; typedef struct { unsigned short count_keys; XIMTriggerKey *keylist; } XIMTriggerKeys; 2.9. IMOffKeysList The IMOnKeysList argument, of type XIMTriggerKeys, specifies the list of preediing end-keys for Dynamic Event Flow model. The IMOffKeysList IMValue is optional for IMserver to support Dynamic Event Flow Model. When it is specified, the IMlibrary can send the IMserver a request to stop preediting with the apperance of one of these registered off-keys, while it's unspecified, the IMserver calls IMPreeditEnd to notify the IMlibrary to stop preeditting when the IMserver would like to stop preeditring. If the IMOffKeysList is left unspecified, no default will be provided. 2.10. IMEncodingList The IMEncodingList argument, of type XIMEncodings, specifies the list of encodings the IMserver supports. XIM client will be notified of this argument immediately after it makes a connection with the IMserver. The IMEncdoingList argument is used to specify which encodings can be used to exchange localized-text between the IMserver and XIM clients. If it's left unspecified, only "COMPOUND_TEXT" encoding will be used as a fallback default. XIMEncodings structure is defined by IMdkit as follows: typedef char *XIMEncoding; typedef struct { unsigned short count_encodings; XIMEncoding *supported_encodings; } XIMEncodings; 2.11. IMFilterEventMask The IMFilterEventMask argument, of type long, specifies the events which should be filtered by the IMserver during the preeditting is on going. If it's left unspecified, KeyPressMask (1L<<0) will be fallback default. 2.12. IMProtocolDepend The IMProtocolDepend argument is used to specify special IM values for each IMProtocol model, if any. This attribute is passed to IMOpenIM, IMSetIMValues or IMGetIMValues as a nested variable length list generated with XVaCreateNestedList(). At this release, the names in the IMProtocolDepend list are defined only for R5 Ximp model, as below. 2.12.1. R5 Ximp dependent IM Values XIMPVersion The XIMPVersion argument, of type string, specifies the version of R5 Ximp model. value meaning --------------------------------------------- "3.5" supports Ximp version 3.5 model "4.0" supports Ximp version 4.0 model XIMPType The XIMPVersion argument, pointer to a list of type unsigned long, specifies a list of bitmask combinations, each of which indicates the event flow model your IMserver supports. All possible values to be appeared in the list are defined as follows.(*) (*) Refer to "Protocol Specification for the Distributes Input System on the X Window System, Version 11", which contains in X11R5 contribuion. XIMP_BE_TYPE1 back-end type, which IMlibrary recognizes registered keys and notifies a server to start processing key events. XIMP_FE_TYPE1 front-end type, which IMlibrary recognizes registered keys and notifies a server to start processing key events. XIMP_BE_TYPE2 back-end type, which IMlibrary does not recognize any registered keys and. IMserver will always the first to process key events. XIMP_FE_TYPE2 front-end type, which IMlibrary does not recognize any registered keys and. IMserver will always the first to process key events. XIMP_FE_TYPE3 front-end type, which key events are always passed to both IMserver and IMlibrary. Both of them recognize registered keys. XIMP_SYNC_BE_TYPE1 XIMP_BE_TYPE1 & KeyPress is transfered synchronously. XIMP_SYNC_BE_TYPE2 XIMP_BE_TYPE2 & KeyPress is transfered synchronously. XIMPExtension The XIMPExtension argument is used to set/unset the pre-registered extensions to be valid. This list is also a nested variable length list generated with XVaCreateNestedList(). At this release, the pre-registered extensins appeared in the XIMPExtension list are defined as below. XIMPExtStatusWin If it is appeared in the list, the XNExtXimp_StatusWindow input context attribute is valid to set the status window. The attribute value isn't evaluated. XIMPExtBackFront If it is appeared in the list, the XNExtXimp_Backfront input context is valid to select the front-end method or back-end method. The attribute value isn't evaluated. XIMPExtConversion If it is appeared in the list, the XNExtXimp_Conversion input context is valid to set the input mode. The attribute value isn't evaluated. 3. X IMProtocol Strucutures For each X IMProtocol input, a corresponding structure is defined in public header files of IMdkit. defines all IMProtocol structures for R6 standard IMProtocol model, and defines all for R5 Ximp model. 3.1. R6 IMProtocol 3.1.1. IMProtocol union data structure In R6 standard IMProtocol model, all the event structures have the following common members: typedef struct { int major_code; /* major code of last IMProtocol */ int minor_code; /* minor code of last IMProtocol */ CARD16 connect_id; /* client connection ID */ } IMAnyStruct; The major_code and minor_code specify the IMProtocol type constant name that uniquely identifies itself. In addition to the individual structures declared for each IMProtocol type, the IMProtocol structure is a union of the individual structures declared for each IMProtocol type. Depending on the type, you should access members of each IMProtocol by using the IMProtocol union. typedef union _IMProtocol { int major_code; IMAnyStruct any; IMConnectStruct imconnect; IMDisConnectStruct imdisconnect; IMOpenStruct imopen; IMCloseStruct imclose; IMQueryExtensionStruct queryext; IMGetIMValuesStruct getim; IMEncodingNegotiationStruct encodingnego; IMExtSetEventMaskStruct extsetevent; IMExtForwardKeyEventStruct extforward; IMExtMoveStruct extmove; IMSetEventMaskStruct setevent; IMChangeICStruct changeic; IMDestroyICStruct destroyic; IMResetICStruct resetic; IMChangeFocusStruct changefocus; IMCommitStruct commitstring; IMForwardEventStruct forwardevent; IMTriggerNotifyStruct triggernotify; IMErrorStruct imerror; IMGeometryCBStruct geometry_callback; IMPreeditCBStruct preedit_callback; IMStatusCBStruct status_callback; long pad[32]; } IMProtocol; The first two entries of any IMProtocol structure are always the major_code and minor_code members, which specifies the IMProtocol type. The third member is the connect_id member, just provided for IMdkit internal use to distinguish a client from each other. 3.1.2. Protocol Processing Some of IMProtocol requests sent by the IMlibrary are processed internally by IMdkit without passing them to your IMservers, because IMdkit can determin the answer to such IMProtocol requests only by using the IMValues which you have set in the XIMS structure. At this release, the following four IMProtocol requests is processed in IMdkit itself, and wouldn't forward to your IMserver: o XIM_CONNECT -> XIM_CONNECT_REPLY o XIM_DISCONNECT -> XIM_DISCONNECT_REPLY o XIM_QUERY_EXTENSION -> XIM_QUERY_EXTENSION_REPLY o XIM_GET_IM_VALUES -> XIM_GET_IM_VALUES_REPLY So, you don't have to know the details of the corresponding IMProtocol structures for these IMProtocol requests. On the other hand, you will need to deal with the following requests for yourselves: o XIM_OPEN o XIM_CLOSE o XIM_SET_IC_FOCUS and XIM_UNSET_IC_FOCUS o XIM_DESTROY_IC o XIM_RESET_IC o XIM_CREATE_IC, XIM_SET_IC_VALUES and XIM_GET_IC_VALUES o XIM_TRIGGER_NOTIFY o XIM_FORWARD_EVENT However, you don't have to receive any raw packets, but can receive the corresponding IMProtocol structures in your IMProtocolHandler callback function. Further, you don't have to send a reply for yourselves, but IMdkit will send a reply soon after your IMProtocolHandler returns. If your IMProtocolHandler returns True, IMdkit will send the proper reply to the previous request, and if it returns False, IMdkit will send XIM_ERROR reply to the XIM client. The following IMProtocol structures are what you will actually receive instead of IMProtocol requests in your IMProtocolHandler function. IMOpenStruct ------------ The IMOpenStruct structure is used for XIM_OPEN and XIM_OPEN_REPLY requests. The structure contains: typedef struct { int length; char *name; } XIMStr; typedef struct { int major_code; int minor_code; CARD16 connect_id; XIMStr lang; } IMOpenStruct; Your IMserver should check lang field to know which language service is required by the new client, which is identified with connect_id member. IMCloseStruct ------------- The IMCloseStruct structure is used for XIM_CLOSE and XIM_CLOSE_REPLY requests. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; } IMCloseStruct; Your IMserver should check connect_id member to know which input method connection should be closed. IMChangeFocusStruct ------------------- The IMChangeFocusStruct structure is used for XIM_SET_IC_FOCUS and XIM_UNSET_IC_FOCUS requests. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID to change focus */ } IMChangeFocusStruct; Your IMserver should check icid member to know which input context should be focusd or unfocusd. IMDestroyICStruct ----------------- The IMDestroyICStruct structure is used for XIM_DESTROY_IC and request. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID to destroy */ } IMDestroyICStruct; Your IMserver should check icid member to know which input context should be destroyed. IMResetICStruct --------------- The IMResetICStruct structure is used for XIM_RESET_IC request. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID to reset */ CARD16 length; /* length of committed string below */ char *commit_string; /* string to commit to XIM client */ } IMResetICStruct; Your IMserver should check icid member to know which input context should be reset. IMChangeICStruct ---------------- The IMChangeICStruct structure is used for XIM_CREATE_IC, XIM_SET_IC_VALUES and XIM_GET_IC_VALUES requests. The structures contain: /* * value type for IC defined in XimProto.h */ #define XimType_SeparatorOfNestedList 0 #define XimType_CARD8 1 #define XimType_CARD16 2 #define XimType_CARD32 3 #define XimType_STRING8 4 #define XimType_Window 5 #define XimType_XIMStyles 10 #define XimType_XRectangle 11 #define XimType_XPoint 12 #define XimType_XFontSet 13 #define XimType_XIMOptions 14 #define XimType_XIMHotKeyTriggers 15 #define XimType_XIMHotKeyState 16 #define XimType_XIMStringConversion 17 #define XimType_NEST 0x7fff typedef struct { int attribute_id; /* ID for this IC */ CARD16 name_length; /* length of IC name below */ char *name; /* IC name */ int value_length; /* length of IC value below */ void *value; /* IC value */ int type; /* value type for IC, see above */ } XICAttribute; typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID: for each CREATE, different ID is expected to be returned. for each SET, it shows the ID to set. for each GET, it shows the ID to get. */ CARD16 preedit_attr_num; /* number of preedit_attr list below */ CARD16 status_attr_num; /* number of preedit_attr list below */ CARD16 ic_attr_num; /* number of ic_attr list below */ XICAttribute *preedit_attr; /* IC values for preedit attribute */ XICAttribute *status_attr; /* IC values for status attribute */ XICAttribute *ic_attr; /* IC values for other attributes */ } IMChangeICStruct; When XIM_SET_IC_VALUES or XIM_GET_IC_VALUES, your IMserver should check icid member to know which input context should be specified. When XIM_CREATE_IC, your IMserver should set icid member to identify the input context newly created. IMTriggerNotifyStruct --------------------- The IMTriggerNotifyStruct structure is used for XIM_TRIGGER_NOTIFY request. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; CARD32 flag; CARD32 key_index; CARD32 event_mask; } IMTriggerNotifyStruct; IMForwardEventStruct -------------------- The IMForwardEventStruct structure is used for XIM_FORWARD_EVENT request. The structure contains: typedef struct { int major_code; int minor_code; CARD16 connect_id; CARD16 icid; /* input context ID */ BITMASK16 sync_bit; /* precessed synchronously or not */ CARD16 serial_number; XEvent event; /* X event to be filtered */ } IMForwardEventStruct; 3.2. R5 Ximp IMProtocol 3.2.1. XIMProtocol union data structure In R5 Ximp IMProtocol model, all the event structures have the following common members: typedef struct { INT32 type; /* message type */ CARD32 icid; /* input context ID */ Window focus_win; /* focus window */ long fwin_sel_mask; /* focus window select-mask */ CARD32 ximp_type_mask; /* Ximp event flow type */ Window client_win; /* client window */ } XIMPAnyStruct; The type member specifies the Ximp IMProtocol type constant name that uniquely identies itself. In addition to the individual structures declared for each Ximp XIMProtocol type, the Ximp IMProtocol structure is a union of the individual structures declared for each Ximp IMProtocol type. Depending on the type, you should access members of each Ximp IMProtocol by using the XIMProtocol union. typedef union _IMPProtocol { int type; XIMPAnyStruct any; XIMPKeyEventStruct keyevent; XIMPICValuesStruct create; XIMPICValuesStruct setvalue; XIMPICValuesStruct getvalue; XIMPAnyStruct destroy; XIMPAnyStruct regkey; XIMPAnyStruct setfocus; XIMPAnyStruct unsetfocus; XIMPClientWindowStruct clientwin; XIMPFocusWindowStruct focuswin; XIMPMoveStruct move; XIMPEventMaskNotifyStruct evmasknotify; XIMPExtensionStruct extension; XIMPReadPropStruct readprop; XIMPResetStruct reset; XIMPCommitStringStruct commitstring; XIMPErrorStruct error; XIMPAnyStruct geometry_cb; XIMPPreeditCBStruct preedit_cb; XIMPStatusCBStruct status_cb; long pad[24]; } IMPProtocol; The first entry of any XIMProtocol structure is always the type member, which specifies the Ximp IMProtocol type. 4. Writing IMservers When writing an IMserver that uses the IMdkit, you should make sure that your IMserver performs the following: 1. Include in your IMserver programs. 2. Include . This header file defines all the necessary data types and IMdkit functions that you need to use. 3. Include for R6 standard IMProtocol, or for R5 Ximp IMProtocol, respectively. 4. Call the IMOpenIM function with all the necessary IMValues to initialize the connection. The names of each IMValues have a global symbol that begins with IM to help catch spelling errors. For example, IMModifiers is defined for the XIMProtocol model, and IMLocale is defined for the locale resource. For further information, see "Section 1.1 Open IM Service" and Section 2 "IMValues" 5. To set additional IMValues or override the existing IMValues you set by IMOpenIM, use IMSetIMValues. You can also use IMGetIMValues to look up at existing IMValues. Note that some of IMValues must be set at the IM service creation time, and never be changed by IMSetIMValues. 6. You must set the IMProtocol callback routine by the IMProtocolHandler argument with IMOpenIM or IMSetIMValues functions. This callback is called whenever the IMProtocol is delivered by XIM clients. 7. Now you should select all the necessary X events for your windows with XSelectInput function, and map the windows with XMapWindow function, then sit in a loop processing events as follows. for (;;) { XEvent event; XNextEvent(your_display, &event); if (XFilterEvent(&event, NULL) == True) continue; YourXEventHandler(&event); } Here, all the IMProtocols you need are passed to your IMProtocol callback routine by X Filtering mechanism of XFilterEvent function, and all unfiltered X events you want are passed to YourXEventHandler function above. 8. Link your IMserver with libXimd (the IMdkit library) and libX11 (the core X library). The following provides a sample command line: cc -o sampleIM sampleIM.c -lXimd -lX11