D. Implementation Tips
(1) FrontEnd Method
FrontEnd method is recognized as a performance acceleration by the trade off of the variety of the reliability.
In order to use the FrontEnd method, the IM library must query the IM
Server to see if the FrontEnd extension is available. The query is
made by using the
XIM_QUERY_EXTENSION
message. The IM Server may send
XIM_EXT_SET_EVENT_MASK
message with intercept-event-mask, forward-event-mask, and
synchronous-event-mask values set after replying
XIM_QUERY_EXTENSION_REPLY
message.
FrontEnd method can be implemented in a couple of ways depending on
how the IM Server utilize
XIM_EXT_SET_EVENT_MASK
message.
One approach is to update both of the input mask and the filter-event-mask depending on the preeidting state. The sample protocol sequence using the static event flow is as follows:
To pursuit a maximum performance regardless of the preediting mode, the IM Server may use the dynamic event flow with the following sample protocol sequence.
This method can reduce the XIM protocol traffic dramatically by updating intercept-event-mask and select-event-mask accordingly. The tradeoff of this performance improvement is that the key events may be lost or disordered in some particular situation, such as when the user types the keyboard in following sequence really fast:
<preediting on key>"some strings"<preediting off key>"another string"
Since this method requires the input mask updates to the both the IM Server and Xlib when turning on and off the preediting, and there is a time lag till the requests take effect when two client issues the input mask updates simultaneously.
Another approach of the FrontEnd method is to update the filter-event-mask
depending on the preediting state and not to update the input mask.
The IM Server must register both of the preediting on key list and off key
list by
XIM_REGISTER_TRIGGERKEYS
message.
In this method, Both the IM Server and the IM client select the same
events on the same client's window, so that the events are delivered
to both of the IM Server and the client. The preediting on and off
states are expressed by whether the key events are filtered or not.
The sample protocol sequence are as follows:
<<Using static event flow>>
<<Using the dynamic event flow>>
This method does not have the problem of the time lag when going across the preediting on and off mode, however, the amount of the performance acceleration is not as good as the method described above.
In general, the FrontEnd method requires some synchronization to some of the X protocols, such as the ChangeWindowAttribute protocol for the event mask change or the GrabKey protocol, since it relies on the X's principal event dispatching mechanism. Any X protocol bindings do not consider the synchronization might cause some mis-synchronization between the IM clients and the IM Server.
(2) Transport Layer
The Xlib XIM implementation is layered into three functions, a protocol layer, an interface layer and a transport layer. The purpose of this layering is to make the protocol independent of transport implementation. Each function of these layers are:
The protocol layer | implements overall function of XIM and calls the interface layer functions when it needs to communicate to IM Server. |
The interface layer | separates the implementation of the transport layer from the protocol layer, in other words, it provides implementation independent hook for the transport layer functions. |
The transport layer | handles actual data communication with IM Server. It is done by a set of several functions named transporters. |
The interface layer and the transport layer make various communication channels usable such as X Protocol, TCP/IP, DECnet or STREAM. The following is a sample implementation for the transporter using the X connection. Refer to "xtrans" for the transporter using Socket Transport.
At the beginning of the X Transport connection for the XIM transport mechanism, two different windows must be created either in an Xlib XIM or in an IM Server, with which the Xlib and the IM Server exchange the XIM transports by using the ClientMessage events and Window Properties. In the following, the window created by the Xlib is referred as the "client communication window", and on the other hand, the window created by the IM Server is referred as the "IMS communication window".
Connection
In order to establish a connection, a communication window is created. A ClientMessage in the following event's format is sent to the owner window of XIM_SERVER selection, which the IM Server has created.
Refer to "The Input Method Protocol" for the XIM_SERVER atom.
Table D.1. The ClientMessage sent to the IMS window.
Structure Member | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | IMS Window ID |
Atom | message_type | XInternAtom(display, "_XIM_XCONNECT", False) |
int | format | 32 |
long | data.l[0] | client communication window ID |
long | data.l[1] | client-major-transport-version (*1) |
long | data.l[2] | client-major-transport-version (*1) |
In order to establish the connection (to notify the IM Server communication window), the IM Server sends a ClientMessage in the following event's format to the client communication window.
Table D.2. The ClientMessage sent by the IM Server.
Structure Member | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | client communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_XCONNECT", False) |
int | format | 32 |
long | data.l[0] | IMS communication window ID |
long | data.l[1] | server-major-transport-version (*1) |
long | data.l[2] | server-minor-transport-version (*1) |
long | data.l[3] | dividing size between ClientMessage and Property (*2) |
(*1) major/minor-transport-version
The read/write method is decided by the combination of major/minor-transport-version, as follows:
Table D.3. The read/write method and the major/minor-transport-version
Transport-version | read/write | |
---|---|---|
major | minor | |
0 | 0 | only-CM & Property-with-CM |
1 | only-CM & multi-CM | |
2 | only-CM & multi-CM & Property-with-CM | |
1 | 0 | PropertyNotify |
2 | 0 | only-CM & PropertyNotify |
1 | only-CM & multi-CM & PropertyNotify |
only-CM : data is sent via a ClientMessage
multi-CM : data is sent via multiple ClientMessages
Property-with-CM : data is written in Property, and its Atom
is send via ClientMessage
PropertyNotify : data is written in Property, and its Atom
is send via PropertyNotify
The method to decide major/minor-transport-version is as follows:
The client sends 0 as major/minor-transport-version to the IM Server. The client must support all methods in Table D-3. The client may send another number as major/minor-transport-version to use other method than the above in the future.
The IM Server sends its major/minor-transport-version number to the client. The client sends data using the method specified by the IM Server.
If major/minor-transport-version number is not available, it is regarded as 0.
(*2) dividing size between ClientMessage and Property
If data is sent via both of multi-CM and Property, specify the dividing size between ClientMessage and Property. The data, which is smaller than this size, is sent via multi-CM (or only-CM), and the data, which is lager than this size, is sent via Property.
read/write
The data is transferred via either ClientMessage or Window Property in the X Window System.
Format for the data from the Client to the IM Server
ClientMessage
If data is sent via ClientMessage event, the format is as follows:
Table D.4. The ClientMessage event's format (first or middle)
Structure Member | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | IMS communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_MOREDATA", False) |
int | format | 8 |
char | data.b[20] | (read/write DATA : 20 byte) |
Table D.5. The ClientMessage event's format (only or last)
Structure Member | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | IMS communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_PROTOCOL", False) |
int | format | 8 |
char | data.b[20] | (read/write DATA : MAX 20 byte) (*1) |
(*1) If the data is smaller than 20 byte, all data other than available data must be 0.
Property
In the case of large data, data will be sent via the Window Property for the efficiency. There are the following two methods to notify Property, and transport-version is decided which method is used.
The XChangeProperty function is used to store data in the client communication window, and Atom of the stored data is notified to the IM Server via ClientMessage event.
The XChangeProperty function is used to store data in the client communication window, and Atom of the stored data is notified to the IM Server via PropertyNotify event.
The arguments of the XChangeProperty are as follows:
Table D.6. The XChangeProperty event's format
Argument | Contents | |
---|---|---|
Display | *display | The display to which connects |
Window | window | IMS communication window ID |
Atom | property | read/write property Atom (*1) |
Atom | type | XA_STRING |
int | format | 8 |
int | mode | PropModeAppend |
u_char | *data | read/write DATA |
int | nelements | length of DATA |
The read/write property ATOM allocates the following strings by
XInternAtom
.
"_clientXXX"
The client changes the property with the mode of PropModeAppend and the IM Server will read it with the delete mode i.e. (delete = True).
If Atom is notified via ClientMessage event, the format of the ClientMessage is as follows:
Table D.7. The ClientMessage event's format to send Atom of property
Structure Members | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | IMS communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_PROTOCOL", False) |
int | format | 32 |
long | data.l[0] | length of read/write property Atom |
long | data.l[1] | read/write property Atom |
Format for the data from the IM Server to the Client
ClientMessage
The format of the ClientMessage is as follows:
Table D.8. The ClientMessage event's format (first or middle)
Structure Members | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | client communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_MOREDATA", False) |
int | format | 8 |
char | data.b[20] | (read/write DATA : 20 byte) |
Table D.9. The ClientMessage event's format (only or last)
Structure Members | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | client communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_PROTOCOL", False) |
int | format | 8 |
char | data.b[20] | (read/write DATA : MAX 20 byte) (*1) |
(*1) If the data size is smaller than 20 bytes, all data other than available data must be 0.
Property
In the case of large data, data will be sent via the Window Property for the efficiency. There are the following two methods to notify Property, and transport-version is decided which method is used.
The XChangeProperty function is used to store data in the IMS communication window, and Atom of the property is sent via the ClientMessage event.
The XChangeProperty function is used to store data in the IMS communication window, and Atom of the property is sent via PropertyNotify event.
The arguments of the XChangeProperty are as follows:
Table D.10. The XChangeProperty event's format
Argument | Contents | |
---|---|---|
Display | *display | The display which to connects |
Window | window | client communication window ID |
Atom | property | read/write property Atom (*1) |
Atom | type | XA_STRING |
int | format | 8 |
int | mode | PropModeAppend |
u_char | *data | read/write DATA |
int | nelements | length of DATA |
(*1) The read/write property ATOM allocates some strings, which are not
allocated by the client, by XInternAtom
.
The IM Server changes the property with the mode of PropModeAppend and the client reads it with the delete mode, i.e. (delete = True).
If Atom is notified via ClientMessage event, the format of the ClientMessage is as follows:
Table D.11. The ClientMessage event's format to send Atom of property
Structure Member | Contents | |
---|---|---|
int | type | ClientMessage |
u_long | serial | Set by the X Window System |
Bool | send_event | Set by the X Window System |
Display | *display | The display to which connects |
Window | window | client communication window ID |
Atom | message_type | XInternAtom(display, "_XIM_PROTOCOL", False) |
int | format | 32 |
long | data.l[0] | length of read/write property ATOM |
long | data.l[1] | read/write property ATOM |
Closing Connection
If the client disconnect with the IM Server, shutdown function should free the communication window properties and etc..