Language Engine Interface Specification 1.2

Draft Version 1.3

Jul 26 2005

Masaki Katakai



IM Engine Library





1. ABSTRACT

This document describes how to develop Language Engine Modules to be connected to iiimd by using IM Engine (aka. SunIM) library. When you have written Language Engine Module once with IM Engine library, the module will connect any client that supports Internet-Intranet Input Method(IIIM) protocol through iiimd. It would not be possible to create a program that can talk with IM client directly using IIIM protocol, however, IM Engine library provides a useful set of programming interface (IML - Input Method Logic) to control various kinds of operation for input method, pre-edit drawing, status drawing, look-up-choice, object downloading etc.

2. IM Engine Library Overview

IM Engine library is a programming interface for language engine module. IM Engine developer can use that interface to construct input engine that can connect with any client, can be platform independent Language Engine, can be multilingual Language Engine.

IM Engine library is independent from both iiimd and Language Engines, and constructed by four objects,  Interface(IF), Input Method Logic(IML),Memory Manager(MM), Namespace(NS).

2.1 IF Method

Language Engine Module needs to define a set of functions, called IF Method, in it. These IF methods will be loaded by iiimd dynamically and will be invoked by iiimd when iiimd receives protocol associated with the Language Engine from IM client. For example, when an input field is created on the user desktop, if_CreateSC() IF method is invoked by iiimd. This IF method is responsible for creating a session, the Language Engine Module can do something. if_SendEvent() is invoked whenever any input event occurs on the client. The Language Engine Module can look into the event, then can do something for action, such as pre-edit drawing, pop up lookup choice and committing the pre-edit.

2.2 IML Method

IML Methods is a set of functions and is provided for Language Engines in order to control input method through iiimd. For example, language engine module can draw a pre-edit text and pop up a lookup choice window by calling the IML methods. IMText now supports Color feedback for each character.

2.3 MM Method

MM Methods is a set of functions for memory allocation and deallocation. These methods are contained in IML Methods. Since a Language Engine is built as a module plugged into iiimd, It is difficult that each Language Engine manages a memory correctly.To ease the memory management, MM methods provide memory pool which has their lifespan.

2.4 NS Method

NS Methods is a set of functions and is provided for Language Engines to capsulize some platform-depended functionalities. Without these features, implementing reading/writing user's configuration files in your Language Engine is too difficult to be platform independent.

Since IIIM should not depend on the specific platforms, and IM client and Language Engine should be worked on separate platforms, Language Engine should use Namespace Methods.

3. Programming Interface

3.1 C/C++ programming interface

IM Engine library is provided under MIT/X license and supports both C and C++ programming interfaces. So Language Engine can be developed as a commercial product if you want.

3.2 MT-Safe

IF methods defined in Language Engine Module should be MT-Safe. iiimd is now multi-threading per each IM connection. However, Language engine can specify the module will run multi-thread or single-thread. Please refer IF_NEED_THREAD_LOCK IF attribute.

3.3 Locale Independent

IM Engine library only supports UNICODE based encoding. All IF methods and IML methods take IMText structure for the argument which are based on UNICODE encoding. Language Engine Module should not use any locale dependent routines in the module, for such as setlocale().

3.4 Module

Language Engine should be developed as a dynamic module loaded by iiimd. So Language Engine should not call the function which effects the process itself,such as fork(), exit(),assert().

4. Common Data Structure

4.1 Bool

Some functions return Bool for indicating whether function failed or not. When the function failed, it returns False.

Boolean Value

#ifndef Bool
typedef enum {                 
  False = 0,
  True = 1
} Bool;
#endif

Symbol
Value
True
1
False
0

4.2 UTFCHAR

UTFCHAR is used to represent UTF-16 coded character. Since UTF-16 encode needs at least 16bit per each, UTFCHAR should have an enough size for containing 16bit data. Current implementation defines UTFCHAR type as unsigned short, but Language Engine developer should not assume that UTFCHAR and unsigned short are the same. It may change at the future release.


UTFCHAR
typedef UTFCHAR unsigned short

4.3 IMHRN

IMHRN structure is a pair of ASCII and Unicode coded string. Since we cannot assume that all IM clients display Unicode coded string properly, Language Engine may use this value to make IM client show at least ASCII coded string.



IMHRN
typedef struct IMHRN_ {
    char *id;             
    UTFCHAR *name;            
}   IMHRN, *IMHRNList;

id
Specifies the id of this structure. Should be ASCII coded.
name
UTF-16 coded string. Should be terminated by 0.

4.3.1 IMLocale

IMLocale structure is used to identify languages supported by a Language Engine. IMLocale structure is the same as IMHRN.

IMLocale
typedef IMHRN IMLocale
id
Specifies the id of locale. Should be spelled out as specified in RFC 1766, making use only of registered tag values or of user-defined language tag starting with the characters "x-". The behavior of user-defined language attribute is undefined.

For example, to specify a language to Japanese, the tag should be used is "ja" (composed of ISO 639 language id) or, alternatively, "ja-JP" (composed of ISO 639 language id plus ISO 3166 country id).

name
Specifies the name of the locale.

4.3.2 IMLEName

IMLEName structure is used to identify your Language Engine. IMLEName structure is the same as IMHRN.

IMLEName
typedef IMHRN IMLEName
id
Specifies the id of the Language Engine.
name
Specifies the name of the Language Engine.

4.4 IMArg, IMArgList

IMArg structure is provided for exchanging data between Language Engine and iiimd.
IF methods, which need to communicate with Language Engine, take IMArgList for sending information to
Language Engine and receiving it from Language Engine.

IMArg
typedef struct _IMArg {
  int id;
  char *value;
} IMArg, *IMArgList;

id
Specifies  a type which describes  the value. Should be one of IF,SC,UI Attributes type
value
Specifies a corresponding value.

4.4.1 Setting Value to IMArg Structure

To set the corresponding value to IMArg structure,  IMSetArg macro is defined.

IMSetArg
#define IMSetArg(arg, n, d) \
        ((void)( (arg).id = (n), (arg).value = (IMArgVal)(d) ))

4.5 IMFeedback

IMFeedback structure is used for representing the feedback of the input string. Editing text with feedback is useful for IM user to understand what he compose.

4.5.1 IMFeedbackType

IMFeedbackType is used for specifying feedback's type. Each feedback should have the type decribed the following.

IMFeedbackType
Symbol
Value
Description
IM_DECORATION_FEEDBACK 0
Specifies a decoration of a character into value field. The value should be any of IMNormal, IMReverse,IMUnderline. This type is required, and the other type are optional.
IM_FOREGROUND_RGB_FEEDBACK 1
Specifies a foreground color into the value field which is a combination value of RGB. IM_RGB_COLOR(RED,GREEN,BLUE) macro is predefined. If the value is not specified, the default foreground color will be used on client side.
IM_BACKGROUND_RGB_FEEDBACK 2
Specifies a background color into the value field which is a combination value of RGB. IM_RGB_COLOR(RED,GREEN,BLUE) macro is predefined. If the value is not specified, the default background color will be used on client side.
IM_UNDERLINE_RGB_FEEDBACK 3
Specifies a underline color into the value field which is a combination value of RGB. IM_RGB_COLOR(RED,GREEN,BLUE) macro is predefined. Note that it's only effective when IMUnderline is specified with IM_DECORATION_FEEDBACK in the first element. If the value is not specified, the default foreground color will be used on client side.
Note:This feature isn't supported in this version.

4.5.2 IMFeedback

IMFeedback structure is a paif of feedback type and value.

IMFeedback

typedef struct _IMFeedback {
  IMFeedbackType type;
  int   value;
} IMFeedback;

type
Specifies the type of IMFeedback. Should be one of IMFeedbackType.
value
Specifies a value corresponding with IMFeedbackType.

4.5.2.1 Value correspongind with IMFeedbackType

Value corresponding with IMFeedbackType
Feedback Type
Possible Values
IM_DECORATION_FEEDBACK
  • IMNormal(0)
  • IMReverse(1)
  • IMUnderline(2)
  • IM_FOREGROUND_RGB_FEEDBACK
    IM_BACKGROUND_RGB_FEEDBACK
    IM_UNDERLINE_RGB_FEEDBACK
     (Red << 16) + (Green << 8) + (Blue << 0)

    4.5.4 IMFeedbackList

    IMFeedbackList structure holds feedbacks for one character.

    IMFeedbackList

    typedef struct _IMFeedbackList {
      unsigned int count_feedbacks;
      IMFeedback  *feedbacks;
    } IMFeedbackList;

    count_feedbacks
    Specifies the number of IMFeedback
    feedbacks
    Specifies the list of IMFeedback which has a pair of IMFeedbackType and its value

    4.5.5 Example

    The following codes demonstrate how to specify color feedback in IMText. If you specify the IMText filled with color feedbacks to IML methods such as iml_make_status_draw() string can be drawn with color in client side.
    Example
    void
    SetFeedback(
    iml_session_t * s,
    IMText * text
    )
    {
    int i;
    IMFeedbackList *fbl;
    IMFeedback *fb;
    int size;

    size = text->char_length;
    text->feedback = (IMFeedbackList *) s->If->m->iml_new(s,
    sizeof(IMFeedbackList) * size);

    /* set color for each character */
    for (i = 0; i < size; i++) {
    fbl = &text->feedback[i];
    fbl->count_feedbacks = 3; /* IM_DECORATION_FEEDBACK,
    * IM_FOREGROUND_RGB_FEEDBACK,
    * IM_BACKGROUND_RGB_FEEDBACK */

    fbl->feedbacks = (IMFeedback *) s->If->m->iml_new(s,
    sizeof(IMFeedback) * fbl->count_feedbacks);

    /*
    * normal decolation, IM_DECORATION_FEEDBACK is required in
    * the first element
    */
    fb = &fbl->feedbacks[0];
    IM_FEEDBACK_TYPE(fb) = IM_DECORATION_FEEDBACK;
    IM_FEEDBACK_VALUE(fb) = IMNormal;

    /* foreground is blue */
    fb = &fbl->feedbacks[1];
    IM_FEEDBACK_TYPE(fb) = IM_FOREGROUND_RGB_FEEDBACK;
    IM_FEEDBACK_VALUE(fb) = IM_RGB_COLOR(0, 0, 255);

    /* background is blue */
    fb = &fbl->feedbacks[2];
    IM_FEEDBACK_TYPE(fb) = IM_BACKGROUND_RGB_FEEDBACK;
    IM_FEEDBACK_VALUE(fb) = IM_RGB_COLOR(255, 255, 255);
    }
    }



    4.6 IMAnnotation

    Annotation is used to provide some information for the input string.

    4.6.1 IMAnnotationType

    IMAnnotationType is used for specifying the type of annotation.
    Annotation Type
    Symbol
    Value
    Description
    IM_ANNOTATION_INPUT_STRING 1
    The input string annotation attribute gives the input string which leaded to the associated text as conversion result.
    IM_ANNOTATION_READING 2
    The reading annotation attribute gives the reading of some text in the associated text. The reading annotation is often used in those languages where the written form of the text and the pronunciation of a word are only loosely related.
    IM_ANNOTATION_SPEECH 3
    The part of speech annotation attribute gives the information how the associated text should be broken up into parts of speech, which usually correspond to words.
    IM_ANNOTATION_CLAUSE 4
    The clause annotation attribute gives the information how the associated text should be broken up into parts of clause, which usually correspond to phrases.

    4.6.2 IMAnnotationValue

    IMAnnotationValue structure is used to represent actual value of the annotation.

    IMAnnotationValue

    typedef struct _IMAnnotationValue {
        int start_pos;
        int end_pos;
        int len;
        void *value;
    } IMAnnotationValue;


    start_pos
    Specifies the start position of this annotation.
    end_pos
    Specifies the end position of this annotation.
    len
    Specifies the length of this annotation.
    value
    Specifies the actual value of this annotation.

    4.6.3 IMAnnotation

    IMAnnotation structure is used to represent actual Annotation information.

    IMAnnotation
    typedef struct _IMAnnotation {
        int type; /* IMAnnotationType */
        int num_values;
        IMAnnotationValue *values;
    } IMAnnotation;
    type
    Specifies the annotation type.
    num_values
    Specifies the number of AnnotationValue
    values
    Specifies the IMAnnotationValue

    4.6.4 Handling Advanced Input Sources such as HandWriting and Voice Input

    Details how to handle advanced input sources are pending.

    4.7 IMText

    IMText structure is provided for exchange input string between Language Engine and IM client.
    IMText structure holds a lot of information such as feedbacks of the string, annotations of the string.
    Each IML methods require IMText representation in the argument.

    IMText
    typedef struct _IMText {
      IMEncoding      encoding;
      unsigned int    char_length;
      union {
        UTFCHAR       *utf_chars;
        char          *native_chars;
      } text;
      IMFeedbackList  *feedback;
      unsigned int    count_annotations;
      IMAnnotation    *annotations;
    } IMText;

    encoding
    Always should be 0, which means UTF16_CODESET.
    char_length
    Specifies the length of the text.
    text.utf_chars
    Specifies the UTF-16 coded string.
    feedback
    Specifies IMFeedbackList structure which represents the feedbacks of the text.utf_chars. feedback should have the same length of text.utf_chars. For example, if you specify 10 length of characters in text.utf_chars, feedback should have 10 length of IMFeedbackList. Each IMFeedbackList corresponds each character. A IMFeedbackList feedback[3] represents a feedback of the character text.utf_chars[3].
    count_annotations
    Specifies the number of annotation.
    annotation
    Specifies the annotation.

    5. Language Engine Module

    The Language Engine Module is main part of a Language Engine, which will be loaded dynamically and can be executed by calling IF methods by iiimd.

    5.1 Defining if_GetIfInfo() in your engine module

    main() is not needed in Language Engine Module. The module should define IF Method instead of if_methods_t main(), which will be called by iiimd when an action, such as IC creation, IC destruction, new user entered, changing input focus, key event that happens on clients.

    The detail of IF Method is described in the next section, IF Method.

    if_methods_t is defined as below:

    if_methods_t
    typedef struct _if_methods {
    Bool if_OpenIF(iml_if_t * If);
    Bool if_CloseIF(iml_if_t * If);
    Bool if_GetIFValues(iml_if_t *, IMArgList, int);
    Bool if_SetIFValues(iml_if_t *, IMArgList, int);
    Bool if_OpenDesktop(iml_desktop_t *, IMArgList, int);
    Bool if_CloseDesktop(iml_desktop_t *);
    Bool if_CreateSC(iml_session_t *, IMArgList, int);
    Bool if_GetSCValues(iml_session_t *, IMArgList, int);
    Bool if_SetSCValues(iml_session_t *, IMArgList, int);
    IMText *if_ResetSC(iml_session_t *);
    void if_SetSCFocus(iml_session_t *);
    void if_UnsetSCFocus(iml_session_t *);
    void if_SendEvent(iml_session_t *, IMInputEvent *);
    } if_methods_t ;

    if_GetIfInfo() is the special method for IM Engine library to retrieve the information of the Language Engines, such as the name of engine, the supported locales and objects and method table.

    The if_methods_t should be returned in as IF_METHOD_TABLE in if_GetIfInfo(). Also IF_VERSION, IF_LE_NAME, IF_SUPPORTED_LOCALES are required to define in if_GetIfInfo. IF_SUPPORTED_OBJECTS should be defined when the Language Engine use object downloading.

    IF_NEED_THREAD_LOCK is not required but when the Language Engine wants to lock and unlock the thread while executing the IF methods, the Language Engine should define the attribute True. The default value is False, which means the IF methods of the Language Engine should be MT-Safe.

    For more detail, please refer IF Attribute section of Appendix B. Also, the next section Auxiliary Object describes how to specify object as IMObjectDescriptorStruct.

    Language Engine module should be shared library .so format in UNIX platform, and dynamic library .DLL format in Windows  platform.

    5.1.1 Example

    Example
    /*
    * define If method prototype
    */
    static Bool if_template_OpenIF(iml_if_t *);
    static Bool if_template_CloseIF(iml_if_t *);
    static Bool if_template_GetIFValues(iml_if_t *, IMArgList, int);
    static Bool if_template_SetIFValues(iml_if_t *, IMArgList, int);
    static Bool if_template_OpenDesktop(iml_desktop_t *, IMArgList, int);
    static Bool if_template_CloseDesktop(iml_desktop_t *);
    static Bool if_template_CreateSC(iml_session_t *, IMArgList, int);
    static Bool if_template_DestroySC(iml_session_t *);
    static Bool if_template_GetSCValues(iml_session_t *, IMArgList, int);
    static Bool if_template_SetSCValues(iml_session_t *, IMArgList, int);
    static IMText *if_template_ResetSC(iml_session_t *);
    static void if_template_SetSCFocus(iml_session_t *);
    static void if_template_UnsetSCFocus(iml_session_t *);
    static void if_template_SendEvent(iml_session_t *, IMInputEvent * ev);

    /*
    * define if_methods_t
    */
    static if_methods_t if_methods = {
    if_template_OpenIF,
    if_template_CloseIF,
    if_template_GetIFValues,
    if_template_SetIFValues,
    if_template_OpenDesktop,
    if_template_CloseDesktop,
    if_template_CreateSC,
    if_template_DestroySC,
    if_template_GetSCValues,
    if_template_SetSCValues,
    if_template_ResetSC,
    if_template_SetSCFocus,
    if_template_UnsetSCFocus,
    if_template_SendEvent
    };

    UTFCHAR lename_string[] = {0x30b5, 0x30f3, 0x30d7, 0x30eb, 0x65e5,
    0x672c, 0x8a9e, 0x30a8, 0x30f3, 0x30b8,
    0x30f3, 0x0};

    UTFCHAR jahrn_string[] = {0x65e5, 0x672c, 0x8a9e, 0x0};

    static IMLEName lename = {
    "template", lename_string /* LE id, HRN */
    };

    static IMLocale locales[] = {
    {"ja", jahrn_string}, /* locale id, HRN */
    NULL
    };

    IMObjectDescriptorStruct *objects = NULL;

    void init_objects();

    void
    if_GetIfInfo(
    IMArgList args,
    int num_args
    )
    {
    int i;

    init_objects();

    for (i = 0; i < num_args; i++, args++) {
    switch (args->id) {
    case IF_VERSION:
    args->value = (IMArgVal) "1.2";
    break;
    case IF_METHOD_TABLE:
    args->value = (IMArgVal) & if_methods;
    break;
    case IF_LE_NAME:
    args->value = (IMArgVal) & lename;
    break;
    case IF_SUPPORTED_LOCALES:
    args->value = (IMArgVal) & locales;
    break;
    case IF_SUPPORTED_OBJECTS:
    args->value = (IMArgVal) objects;
    break;
    case IF_NEED_THREAD_LOCK:
    args->value = (IMArgVal) False;
    break;
    default:
    break;
    }
    }
    }

    5.1.1.1 Export if_GetIfInfo() in C++ code

    When you use C++ for the Language Engine Module, the method should be define as ``export "C"'' for IM Engine library

    Example
    extern "C" {
    void
    if_GetIfInfo(
    IMArgList args,
    int num_args
    )
    {
    ...
    }
    }

    5.1.1.2 Export if_GetIfInfo() on Windows platform

    For Windows platform, the if_GetIFInfo() should be defined as extern __declspec(dllexport) for DLL.

    Example
    #define EXPORT extern __declspec(dllexport)

    EXPORT void
    if_GetIfInfo()
    {
    /* ... */
    }

    And .def file is required for exporting the function.

    Example
    ; template.def

    LIBRARY template

    EXPORTS
    if_GetIfInfo

    5.1.2 One Language Engine module which supports Multiple Languages.

    When your Language Engine supports Multiple Languages,Language Engine can regist IMLocale structure for IF_SUPPORTED_LOCALES in if_GetIfInfo().The array of IMLocale structure should be a NULL terminated array so that Language Engine can support Multiple Languages.

    5.1.3 One Language Engine module which supports Multiple IM Logics.

    As of SDK 1.2 Draft 1.3, one Language Engine can provide multiple IM logics. When Language Engine wants to provide multiple IM logics, Language Engine should regist IMEInfo structure for IF_SUPPORTED_IMEINFO in if_GetIfInfo(). When IMEInfo structure is registerd at if_GetIfInfo() call, iiimd will use IMEInfo instead of IF_LE_NAME and IF_SUPPORTED_LOCALES. Note that older iiimd doesn't support this feature, so Language Engine should provide a value of IF_LE_NAME and IF_SUPPORTED_LOCALES for compatibility.

    5.1.3.1 IMEInfo

    IMEInfo strucure is used for identifying IM logics that Language Engine supports.
    IMEInfo
    typedef struct IMEINFO_ {
         Bool enable;
         char *ime_id;
         UTFCHAR *imename;
         UTFCHAR *version;
         UTFCHAR *description;   
         UTFCHAR *author;         
         UTFCHAR *copyright;
         IMLocale *locales;    
    }   IMEInfo;

    enable
    Specifies whether this Language Engine works.
    ime_id
    Specifies Language Engine id. Should be ASCII coded.
    imename
    Specifies Language Engine's name. Should be UTF-16 coded.
    version
    Specifies Language Engine's version. Should be UTF-16 coded.
    This argument is optional. You can pass NULL.
    description
    Specifies the description of Language Engine. Should be UTF-16 coded.
    This argument is optional. You can pass NULL.
    author
    Specifies the author of Language Engine. Should be UTF-16 coded.
    This argument is optional. You can pass NULL.
    copyright
    Specifies the copyright of Language Engine. Should be UTF-16 coded.
    This argument is optional. You can pass NULL.
    locales
    Specifies the locales this Language Engine supports. Should be NULL terminated array of IMLocale.

    You can pass a null-terminated array of IMEInfo structure in if_GetIfInfo() calls.

    5.1.3.2 Detecting which IM logic is selected.

    If you registered IMEInfo structure, SC_CLIENT_IME_INFO notifies which IM logic is selected for inputing string in if_CreateSC() and if_SetSCValues() IF methods.

    5.2 Using Pre-defined IF Method except you want to implement.

    In order to reduce a work for developing your Language Engine, IM Engine library prepares default IML methods.
    When you pass NULL as a IF method's pointer, the default IF method implemented within IM Engine library is invoked. Which means that you can implement only what you want to modifiy default behaivior.


    5.3 Destination of Language Engine Module

    The destination of Language Engine modules depends on implementation. The default locations for Solaris platform and Windows NT platform are defined as the following. The location can be specified -ifpath_name iiimd option, like

    iiimd -ifpath_name /tmp/iiimf_test

    for Solaris platform. or

    iiimd -ifpath_name c:\\temp\\iiimf_test

    for Windows NT platform.

    5.3.1 on Unix Platform

    /usr/lib/iiim is now base directory for IIIMF. The Language Engine Module should be located under

    /usr/lib/iiim/le

    for Unix platforms.

    5.3.2 on Windows platform

    For Windows NT platform, language engine module should be provided as DLL library. The Language Engine Module should be located under

    D:\\WINNT\\System32\\iiimf

    6. Auxiliary Object

    While IIIMF provides some default widgets to input string, Language Engines sometimes want to use their own widgets, such as lookup choice window, preedit window, palette window.

    IM Engine library provides some functions to register LE own Auxiliary Objects to the IM client so that Language Engine module can send objects to IM client which works as Auxiliary programs such as palette on the IM client side.

    6.1 Defining ObjectDescriptor

    In order to regist your Auxiliary Objects, Language engine module should define IMObjectDescriptorStruct.

    IMObjectDescriptorStruct should be terminated by NULL and specified for IF_SUPPORTED_OBJECTS in if_GetIfInfo() method.

    6.1.1 IMObjectType

    Each IMObjectDescriptorStruct should have the type of Auxiliary Object.

    IMObjectType
    Symbol
    Value
    Description
    IM_DOWNLOADINGOBJECT_JARGUI_TYPE 0x1031
    Declares the object is GUI object and Java jar file format.
    IM_DOWNLOADINGOBJECT_JARLWE_TYPE 0x1032 Declares the object is LWE object and Java jar file format.
    Note:This feature isn't supported in this version.
    IM_DOWNLOADINGOBJECT_CCDEF_TYPE 0x1030 Declares the object is CCDEF syntax rule file. It requires basepath and encoding fields.
    Note:This feature isn't supported in this version.
    IM_DOWNLOADINGOBJECT_BINGUI_TYPE 0x1033 Declares the object is GUI object and binary file format. Only UNIX platform is supported and it's .so shared library format.
    IM_DOWNLOADINGOBJECT_BINLWE_TYPE 0x1034 Declares the object is LWE object and binary file format. Only UNIX platform is supported and it's .so shared library format.
    Note:This feature isn't supported in this version.
    IM_DOWNLOADINGOBJECT_SGUI_TYPE 0x1035 Declares the object is GUI object and script file format.
    Note:This feature isn't supported in this version.
    IM_DOWNLOADINGOBJECT_SLWE_TYPE 0x1036 Declares the object is LWE object and script file format.
    Note:This feature isn't supported in this version.

    6.1.2 IMObjectDescriptorStruct

    IMObjectDescriptorStruct is used to notify the IM client that which Auxiliary Object Language Engine supports.
    Language engine module should define IMObjectDescriptorStruct if the language engine needs to use Auxiliary object. The following fields are required for the definition.

    IMObjectDescriptorStruct
    typedef struct _IMObjectDescriptorStruct {
      char *leid;                 /* id for LE, `sampleja' */
      IMObjectType type;
      unsigned int id;              /* assigined dynamically by LELookup */
      unsigned int size;            /* object size */

      char **class_names;           /* only for JARFILE_OBJECT */
      unsigned int count_names;     /* count of class names */
                                    /* only for CCDEF */
      UTFCHAR *name;                /* HRN */
      int name_length;              /* HRN len in UTF16-char unit */
      char *domain;               /* reversed domain */
      char *path;                   /* path for object */
      char *scope;          /* usability id or `generic' */

      /* only for CCDEF */
      char *signature;              /* Object signature */
      char *basepath;               /* base path for include tag */
      char *encoding;               /* encoding of CCDEF */
    } IMObjectDescriptorStruct;


    leid
    This field specifies the identifier for the language engine module, which should be same with the id of IMLEName.
    type Specifies a type of the object.
    class_names Specifies a list of class name that are included in the object. A jar file can contain multiple classes for the Aux. For example, "foo.bar.sample.SamplePanel" and "foo.bar.sample.SampleAux" can be specified.

    The name specified in this field will be used in aux_name field of IMAuxStartCallbackStruct , IMAuxDrawCallbackStruct and IMAuxDoneCallbackStruct at iml_make_aux_start_inst() , iml_make_aux_draw_inst() and iml_make_aux_done_inst() .

    count_names Specifies the number of class_names. For the example above, this field should be 2.
    name Specifies HRN(Human Readable Name) of the object
    name_length Specifies the length of name
    domain Specifies reversed domain of vendor who developed the object.
    path Speficies the location of the object.
    scope Speficies whether of not the object can be used by the other language engine module. If the object is designed only for the language engine module, this field should be same with leid field. Otherwise, this field is generic, which means this object can be used by the others.
    Note:generic keyword will not work properly in this version. Use leif only.
    basepath Required if type is IM_DOWNLOADINGOBJECT_CCDEF_TYPES. Speficies the location of CCDEF syntax rule files.
    Note: IM_DOWNLOADINGOBJECT_CCDEF_TYPES isn't supported in this release.
    encoding Required if type is IM_DOWNLOADINGOBJECT_CCDEF_TYPES. Speficies the encoding of CCDEF syntax rule.
    Note: IM_DOWNLOADINGOBJECT_CCDEF_TYPES isn't supported in this release.
    IMObjectDescriptorStruct should be terminated by NULL and specified for IF_SUPPORTED_OBJECTS in if_GetIfInfo() method.

    7. HotKey

    Hotkey is a special keyevent that can be registered by the iiimd and Language Engines to the client. When an input event matches one of the registered Hotkeys, the IM client determines what to do depending on the particular Hotkey's settings.

    7.1 Defining if_GetHotKeyInfo() in your engine module

    Each Language Engine can register their own HotKey Profiles using the special method for the IM Engine Library called if_GetHotKeyInfo(). The Hotkey definitions could be in an external configuration file that can be loaded dynamically by IIIM Server or it can hardcoded in the Language Engine.

    7.1.1 Data Structure used for Hotkey

    7.1.1.1 IMHotkeyStruct

    IMHotkeyStruct structure is used to represent actual Hotkey information. Each IMHotkeyStruct is connected to one action and holds keys infomation which assinged to the action.

    IMHotkeyStruct

    typedef struct _IMHotkeyStruct {
      char *label;
      int state_flag;
      int action_flag;
      int nkeys;
      IMKeyEventStruct *keys;
    } IMHotkeyStruct;

    label
    Specifies the label of this Hotkey. Should be ASCII coded.
    state_flag
    Specifies the state of this Hotkey. 1 means that this Hotkey is acvitated, 0 means deactivated.
    action_flag
    Specifies the action of this Hotkey.Action flag can be configurable by Language Engine, but details are pending.
    nkeys
    Specifies the number of IMKeyEventStruct.
    keys
    Specifies the IMKeyEventStruct.

    7.1.1.2 IMHotkeyProfileStruct

    IMHotkeyProfileStruct structure holds profile id and a list of IMHotkeyStruct. Profile id is provided for allowing Language Engine can register several sets of actions.
    IMHotKeyProfileStruct

    typedef struct _IMHotkeyProfileStruct {
      IMLEName *name;
      int profile_id;
      int scope;
      int num_hotkeys;
      IMHotkeyStruct *hks;
    } IMHotkeyProfileStruct;


    name
    Specifies the name of  Language Engine or IM logic
    profile_id
    Specifies the number of this Profile.
    scope
    Specifies the scope on which this profile effects.
    num_hotkeys
    Specifies the number of IMHotkeyStruct
    hks
    Specifies the IMHotkeyStruct

    7.1.1.3 IMHotkeyManagerStruct

    IMHotkeyManagerStruct structure is used to manage Hotkey Profile. IMHotkeyManagerStruct holds the number of Hotkey Profile and the array of Hotkey Profile.

    IMHotkeyManagerStruct

    typedef struct _IMHotkeyManagerStruct {
      int num_hotkey_profiles;
      IMHotkeyProfileStruct *hkps;
    } IMHotkeyManagerStruct;


    num_hotkey_profiles
    Specifies the number of IMHotkeyProfileStruct
    hkps
    Specifies the IMHotkeyProfileStruct

    7.1.2 Example

    Example
    static IMHotkeyManagerStruct *g_hkms = NULL;
    static IMKeyEventStruct *sampleja_hotkey;
    IMHotkeyManagerStruct*
    if_GetHotKeyInfo (IMLEName *a_le_name)
    {
    if (g_hkms)
    return (IMHotkeyManagerStruct *)g_hkms;
    g_hkms = calloc(1, sizeof(IMHotkeyManagerStruct));
    /* Creating two profiles */
    g_hkms->num_hotkey_profiles = 2;
    g_hkms->hkps = calloc(g_hkms->num_hotkey_profiles,
    sizeof(IMHotkeyProfileStruct));
    /* 1st Hotkey Profile */
    g_hkms->hkps[0].profile_id = 777; /* Any random number */
    g_hkms->hkps[0].scope = SESSION_SPECIFIC_HOTKEY;
    g_hkms->hkps[0].num_hotkeys = 1;
    g_hkms->hkps[0].name = a_le_name;
    g_hkms->hkps[0].hks = calloc(g_hkms->hkps[0].num_hotkeys,
    sizeof(IMHotkeyStruct));
    if (sampleja_hotkey == NULL) return (IMHotkeyManagerStruct *)NULL;
    /* Hotkey 1 */
    sampleja_hotkey[0].keyCode = IM_VK_F8;
    sampleja_hotkey[0].keyChar = 0;
    sampleja_hotkey[0].modifier = 0;
    sampleja_hotkey[0].time_stamp = 0;
    g_hkms->hkps[0].hks[0].label = "SAMPLEJA_HOTKEY_F8";
    g_hkms->hkps[0].hks[0].state_flag = 0;
    g_hkms->hkps[0].hks[0].action_flag = 1;
    g_hkms->hkps[0].hks[0].nkeys = 1;
    g_hkms->hkps[0].hks[0].keys = &sampleja_hotkey[0];
    return g_hkms;
    }

    In the case of defining Hotkeys in an external configuration file, you can add/delete/modify hotkey definitions dynamically.

    Example
    static IMHotkeyManagerStruct *g_hkms = NULL;

    IMHotkeyManagerStruct*
    if_GetHotKeyInfo (
    IMLEName *a_le_name
    )
    {
    if (g_hkms)
    return (IMHotkeyManagerStruct *)g_hkms;
    /* Load the hotkey configuration file dynamically and fill the */
    /* IMHotkeyManagerStruct structure */
    g_hkms = load_hotkey_config_file(filename);
    return g_hkms;
    }

    Bool
    if_CloseIF(
    iml_if_t *if
    )
    {
    /* free HotkeyManager */
    if (g_hkms) {
    ...
    }
    return True;
    }

    7.2 LEs switching between Hotkey Profiles

    IM Engine library provides a special interface for HOTKEY related functionalities. Here is the sample code for LE to switch to a particular Hotkey Profile:
    a
       iml_hkc       *hkc; /* iml_hkc defined in ~/trunk/include/iml/SunIMMthd.h */

    hkc = desktop->desktopGetValue(IML_HOTKEY_CONTEXT, "iiim.le.sampleja");
    hkc->switchLEProfile(IME_HOTKEY_PROFILE_TWO, &leName);
    hkc->hotkey_context_free(hkc);

    7.3 IIIMServer registering Hotkey Profiles

    Here is how IIIMServer registers HOTKEYS PROFILES:
    1. While loading all LEs, IIIMServer collects the Hotkey Profiles registered by all Language Engines and assigns a unique PROFILE_ID.
    2. IIIMServer also creates a DEFAULT HOTKEY PROFILE (also called SUPER HOTKEY PROFILE). This contains the following SUPER HOTKEYS:
      1. IM on/off keys ( <Ctrl>space / <Shift>space / Kanji-key )
      2. Language Selection Window (for LE switching) ( <Ctrl+Shift>space / <Ctrl+Alt>space )
    3. For enabling the profile switching from LE, IIIMServer creates a list of the following mapping
                    <Unique Profile ID, IMHotkeyProtocolStruct *>
      Note: IMHotkeyProtocolStruct contains both the profile_id assigned by each LE (which need not be unique) and the LE name.
    4. IIIMServer merges the SUPER HOTKEYS with the HOTKEYS defined by each LE. So, all the Hotkey Profiles from LE, will include the SUPER HOTKEYS.
    5. After merging, IIIMServer sends all the Hotkey Profiles from LE and the DEFAULT HOTKEY PROFILE in IM_REGISTER_HOTKEYS request. Since there is no separate protocol for registering the list of Hotkey Profiles, IIIMServer registers all the Hotkey Profiles one by one.
    6. After registering, IIIMServer selects the DEFAULT HOTKEY PROFILE as the Client's current profile by sending IM_SELECT_HOTKEY_PROFILE request with the default PROFILE_ID.
    7. If a particular LE registers HOTKEY PROFILE and it is chosed as the default LE for the client application, then the LE can switch the profile by using the interface explained in question 4.

    8. IF Method

    IF methods will be invoked by iiimd when iiimd receives protocol associated with the Language Engine from IM client.

    8.1 Opening and Closing an IF

    When iiimd receives a request of IM connection for the Language Engine, if_OpenIF() IF method is invoked to initialize the Language Engine. The Language Engine is able to do something for initialization in this method. This IF method is only for Language Engine initialization, should not depend on any locale and any user information. The locale and user information of IM client will be usable after if_OpenDesktop() IF method is called. If Language Engine does not accept any connections or internal error happens so gives up to continue operation, if_OpenIF() should return False. Otherwise, it should return True.

    When iiimd no longer needs the Language Engine Interface (IF) opened by if_OpenIF() IF method any more, that is there is no user to use the Language Engine any more, if_CloseIF() IF method will be called.

    iml_if_t
    typedef struct _iml_if_t {
        char *if_name;
        char *if_version;
        char *locale;
        iml_methods_t *m;
        iml_desktop_list desktop_list;
        int desktop_count;
    } iml_if_t;
    if_name
    Specifies the IF name.
    if_version
    Specifies the IF version.
    locale
    Specifies the id of the locale this LE works.
    m
    Specifies the iml_methods.
    desktop_list
    Specifies the list of desktop connected to this Language Engine.
    desktop_count
    Specifies the number of desktop connected to this Language Engine.

    8.1.1 if_OpenIF()

    Bool (*if_OpenIF)(iml_if_t *If)

    8.1.2 if_CloseIF()

    Bool (*if_CloseIF)(iml_if_t *If)

    8.1.3 Example

    Example
    Bool
    if_template_OpenIF(
    iml_if_t * If
    )
    {
    /* initialization for the Language Engine */
    initialize_template();
    }

    Bool
    if_template_CloseIF(
    iml_if_t * If
    )
    {
    /* destruction for the Language Engine */
    close_template();
    }

    8.2 Setting and Querying IF values

    Following IF methods are provided to query and set, modify IF attributes. However, there is no usable IF attributes in this release.

    8.2.1 if_GetIFValues()

    Bool (*if_GetIFValues)(iml_if_t *If,IMArgList args,int n_args)

    8.2.2 if_SetIFValues()

    Bool (*if_SetIFValues)(iml_if_t *If, IMArgList args, int n_args)

    8.3 Opening and Closing User Desktop

    8.3.1 Desktop

    Language Engine should support multi-user connection. A new concept, called a Desktop for that purpose, is provided to identify the user environment. Desktop is identified by user name, host name and display id, which are represented in iml_desktop_t structure.

    8.3.1.1 iml_desktop_t

    iml_desktop_t structure holds the Desktop related data, such as username, hostname and display_id.

    iml_desktop_t
    typedef struct _iml_desktop_t {
    char *user_name;
    char *host_name;
    char *display_id;
    iml_if If; /* parent If */
    iml_inst_slot_t *free_slot_q1; /* MM general */
    iml_inst_slot_t *free_slot_q2; /* MM lookup */
    iml_session_list session_list; /* list of child session */
    struct _iml_desktop_t *next;
    void *specific_data; /* user defined */
    } iml_desktop_t;
    user_name
    Specifies the user name of the IM client.
    host_name
    Specifies the host name of the IM client.
    display_id
    Specifies the display name of the IM client.
    If
    Specifies the IF methods.
    free_slot_q1
    Specifies the memory_pool. Should not use.
    free_slot_q2
    Specifies the memory_pool. Should not use.
    session_list
    Specifies the session list this desktop has
    next
    Specifies the next desktop. may be NULL.
    specific_data
    Specifies the private data for this desktop.

    Language Engine may want to know whether the connection is a first time or second, and may want to know user name of IM client to distinguish the behavior of the Language Engine and license management and etc. Following two IF methods are provided for the purpose.

    8.3.2 if_OpenDesktop()

    When the user starst to use the Language Engine, if_OpenDesktop() IF method is invoked. Language Engine can retrieve the client information such as user name, host name and display id from iml_desktop_t structure.

    Bool (*if_OpenDesktop)(iml_desktop_t *desktop, IMArgList args, int n_args)

    8.3.3 if_CloseDesktop()

    When the user no longer uses the Language Engine, if_CloseDesktop() IF method is invoked.

    Bool (*if_CloseDesktop)(iml_desktop_t *desktop)

    8.3.4 Implementing Language Engine Specific License Scheme.

    Language Engine can check the license for the user and the host and if not acceptable, if_OpenDesktop() should return False, otherwise should return True.

     Also, the additional information of IM client can be checked by IMArgList arg and int n_args. The protocol type, client type, OS name, OS vendor and OS version of IM client are usable. The language engine module can use them if the information other than user name, host name and display id are needed for license management. The attributes are predefined. Please refer UI Attribute section of Appendix.

    8.3.5 Store/Get Desktop Specific Infomation

     If Language Engine wants to prepare allocated data per desktop, Language Engine can allocate and store its pointer to desktop->specific_data.

    When iiimd does not need the desktop any more, which indicates the user quits from the desktop, if_CloseDesktop()desktop->specific_data will be called. When Language Engine allocates and stores a data to , it should be freed in if_CloseDesktop() IF method.

    8.3.6 Example

    Example
    Bool
    if_template_OpenDesktop(
    iml_desktop_t * desktop,
    IMArgList args,
    int n_args
    )
    {
    Bool ret;
    int i;

    /*
    * Additional information of IM client
    */
    char *user_name, *host_name, *display_id, *protocol_type,
    *client_type, *os_name, *os_arch, *os_version;

    for (i = 0; i < n_args; i++, args++) {
    switch (args->id) {
    case UI_USER_NAME: user_name=args->value; break;
    case UI_HOST_NAME: host_name=args->value; break;
    case UI_DISPLAY_ID: display_id=args->value; break;
    case UI_PROTOCOL_TYPE: protocol_type=args->value; break;
    case UI_CLIENT_TYPE: client_type=args->value; break;
    case UI_OS_NAME: os_name=args->value; break;
    case UI_OS_ARCH: os_arch=args->value; break;
    case UI_OS_VERSION: os_version=args->value; break;
    }
    }

    /*
    * Language Engine can check a license for the user
    */
    ret = check_license(desktop->user_name, desktop->host_name);
    if(ret == True){
    MyDataPerDesktop *my_data_per_desktop = (MyDataPerDesktop *)
    malloc(sizeof(MyDataPerDesktop));
    desktop->specific_data=(void*)my_data_per_desktop;
    }
    return ret;
    }

    Bool
    if_template_CloseDesktop(
    iml_desktop_t * desktop
    )
    {
    /*
    * desktop->specific_data can be used in any IF methods
    */
    MyDataPerDesktop *my_data_per_desktop = (MyDataPerDesktop *)
    desktop->specific_data;
    /*
    * Language Engine can free the license for the user
    */
    free_license(desktop->user_name, desktop->host_name);
    return True;
    }


    8.4 Creating and Destroying a Session Context

    8.4.1 Session

    After if_CreateSC() is invoked, the communications between iiimd and a Language Engine will start. For example, there are two applications in the same desktop, A and B. A has three textfields, which means that A creates three ICs. B has two textedits, which means that B creates two ICs. Then, iiimd will manage five different communications(i.e. ICs) in total. And also, it does not matter which IC belongs to either A or B from iiimd's point of view.

    Here, a communication between iiimd and a IC is called a Session. The Session that is generated in the client and then a Language Engine has been connected will be the default one in the IC.

    It is important to understand the concept of Session for both IML and IF. Once the connection with a Language Engine is established, both IML and IF is identified by the Session iml_session_t and the content is exchanged between iiimd and the Language Engines.

    8.4.1.1 iml_session_t

    iml_session_t structure has the information used for identifying the Session and exchanging the context specific data between iiimd and the Language Engines.

    iml_session_t
    typedef struct _iml_session {
      /* public */
        iml_if_t *If;                       /* parent IF */
        iml_desktop_t *desktop;             /* parent desktop */
        void *specific_data;                /* specific data per session */
        int current_active_region;          /* check active region */
        int public_status;                  /* check conversion on/off */
      /* private */
        IMPreeditDrawCallbackStruct PreEditTextInfo; /* preedit cache */
        int PreEditTextBufferSize;
        int PreEditAttrBufferSize;
        status_cache_t status_cache;                /* cache for status string */
        iml_inst_mem_block_list_t *mem_block_short_term_small;
        iml_inst_mem_elem_list_t *mem_elem_short_term;
        iml_inst_mem_elem_list_t *mem_elem_long_term;
        void *SessionContext;                       /* reference for iml_execute() */
        struct _iml_session *next;                  /* link */
    } iml_session_t;

    If
    Specifies the IF methods.
    desktop
    Specifies the desktop this session belongs
    specific_data
    Specifies the private data for this session
    current_active_region
    Specifies the attbiute of this context. You can check the attributes of this context such as pre-edit, lookup choice. Details are pending for current version.
    public_status
    Specifies the conversion status for this context.
    PreEditTextInfo
    Specifies the cache of the pre-edit text. Should not use.
    PreEditTextBufferSize
    Specifies the cache size of pre-edit text. Should not use.
    PreEditAttrBufferSize
    Specifies the cache size of pre-edit attribute. Should not use.
    status_cache
    Specifies the cache of status text. Should not use.
    next
    Specifies the next session.

    8.4.2 if_CreateSC()

    An input context is created on the client, if_CreateSC() is invoked. It's not required to create iml_session_timl_session_t structure here, is created by IM Engine library side, which means Language Engine does not need to call SDK1.0 based iml_construct_session() and iml_destruct_session(). The return value of this IF method should be Bool.

    When the session is acceptable, return True. Otherwise, return False.

    Bool (*if_CreateSC)(iml_session_t *s,IMArgList args, int n_args)

    8.4.3 if_DestroySC()

    An IC is destroyed with a call to if_DestroySC(). When Language Engine allocates and returns data pointer at if_CreateSC() IF method, s->specific_data should be freed in if_DestroySC().

    Bool (*if_DestroySC)(iml_session_t *s)

    8.4.4 Store/Get Session Specific Infomation

    If Language Engine wants to assign session specific data to the session, s->specific_data can be used.

    For example, Language Engine may want to adapt MyDataPerSession structure for each session. In this case, MyDataPerSession can be assgined to s->specific_data, and which can be referred in any IF methods.

    8.4.5 Example

    Example
    static Bool
    if_template_CreateSC(
    iml_session_t * s,
    IMArgList args,
    in t n_args
    )
    {
    /* will be stored as s->specific_data */
    MyDataPerSession *my_data_per_session = (MyDataPerSession *)
    malloc(sizeof(MyDataPerSession));

    s->specific_data = (void*) my_data_per_session;

    return True;
    }

    static Bool
    if_template_GetSCValues(
    iml_session_t * s,
    IMArgList args,
    int n_args
    )
    {
    /* can be referred by s->specific_data in any IF methods */
    MyDataPerSession *my_data_per_session =
    (MyDataPerSession *) s->specific_data;
    }

    static Bool
    if_template_DestroySC(
    iml_session_t * s
    )
    {
    /* should free in if_DestroySC */
    MyDataPerSession *my_data_per_session =
    (MyDataPerSession *) s->specific_data;

    free(my_data_per_session);
    }


    8.5 Setting and Querying Session values

    These IF methods are provided to query and set, modify SC attributes. Language Engine can use SC attribute and these IF methods for negotiation, such as Object Downloading, with IM client. For more detail, please refer SC Attribute section of Appendix B.

    8.5.1 if_GetSCValues()

    if_GetSCValues() IF method is used to set and modify SC attributes.

    Bool (*if_GetSCValues)(iml_session_t *s, IMArgList args, int n_args)

    8.5.2 if_SetSCValues()

    if_SetSCValues() IF method is used to receive values of the SC attributes.

    Bool (*if_SetSCValues)(iml_session_t *s, IMArgList args, int n_args)

    8.5.3 Example

    Example
    Bool
    if_template_SetSCValues(
    iml_session_t * s,
    IMArgList args,
    int num_args
    )
    {
    int i;
    IMArg *p = args;

    for (i = 0; i < num_args; i++, p++) {
    switch (p->id) {
    case SC_TRIGGER_ON_NOTIFY:
    // conversion on
    break;
    case SC_TRIGGER_OFF_NOTIFY:
    // conversion off
    break;
    case SC_REALIZE:
    if(s->desktop->session_count == 1){
    // can start IM pallet here
    }
    break;
    default:
    break;
    }
    }
    return True;
    }

    8.6 Handling Focus

    When the input context on the client side gets and loses an input focus, these IF method is invoked.

    8.6.1 if_SetSCFocus()

    if_SetSCFocus() IF method is used to notify IC client gets input focus.

    void (*if_SetSCFocus)(iml_session_t *s)

    8.6.2 if_UnsetSCFocus()

    if_GetSCFocus() IF method is used to notify IC client loses input focus.

    void (*if_UnsetSCFocus)(iml_session_t *s)

    8.7 Resetting a Session

    If a client needs to reset the input context, this IF method is invoked with the associated session information. This IF method should return the current pre-edit string if necessary. IMText returned by this function will be commited to the client.

    8.7.1 if_ResetSC()

    if_ResetSC() IF method is used to notify that client's IC needs to be resetted.

    IMText *(*if_ResetSC)(iml_session_t *s)

    8.8 Handling Input Events

    8.8.1 if_SendEvent()

    When any event occurs on the client IC, this IF method is invoked with IMInputEvent, which contains any of key event, string event, text event and aux event. Language Engine can find event type by checking IMInputEvent->type .

    void (*if_SendEvent)(iml_session_t *s,IMInputEvent *ev)

    8.8.2 Event Type

    Event type specifies which type of event, the IC client emitted.

    Input Event Type
    typedef enum {
      IM_EventKeyList = 1,
    IM_EventString = 2,
    IM_EventText = 3,
    IM_EventAux = 4,
    IM_EventAuxSet = 4,
    IM_EventAuxGet = 5,

    IM_HotkeyEvent = 6,
    IM_EventKeyReleaseList = 7,

    IM_EventX = 100

    } IM_Event_Type;
    Symbol
    Value
    Description
    IM_EventKeyList 1
    Event that holds KeyPress infomation.
    IM_EventString 2
    Event that holds Unicode String.
    IM_EventText 3
    Event that holds IMText.
    IM_EventAux 4
    Deprecated. Only left for backward compatibility. use IM_EventAuxSet instead.
    IM_EventAuxSet 4
    Event that holds Aux Event.
    IM_EventAuxGet 5
    Event that holds AuxGet Event.
    IM_HotkeyEvent 6
    Event that holds Hotkey Event
    IM_EventKeyReleaseList 7
    Event that holds KeyRelease infomation.
    IM_EventX 100
    Deprecated. Only left for backward compatibility. should not use.

    8.8.3 Event Data Structure

    For each event type, a corresponding Event structure will be prepared.
    In addition to the individual structure, IMInpueEvent structure is a union of the individual structure.
    You should access corresponding event by using IMInputEvent.

    8.8.3.1 IMInputEvent

    An IMInputEvent structure's first entry is always the type member, which indicates the InputEvent's type described at 8.8.2, so that Language Engine can distinguish what type of the IM client wants to handle.


    IMInputEvent
    typedef union IMInputEvent_ {
    int type;
    IMKeyListEvent keylist;
    IMTextEvent text;
    IMStringEvent string;
    IMAuxEvent aux;
    IMAuxGetEvent auxget;
    IMKeyReleaseListEvent keyreleaselist;
    IMHotkeyEvent hotkey;
    IMXEvent xevent;
    } IMInputEvent;
    type
    Event Type

    keylist
    IMKeyListEvent

    text
    IMTextEvent

    string
    IMStringEvent

    aux
    IMAuxEvent

    auxget
    IMAuxGetEvent

    keyreleaselist
    IMKeyReleaseListEvent

    hotkey
    IMHotkeyEvent

    xevent
    Deprecated, should not use.



    8.8.3.2 Key Event

    8.8.3.2.1 IMKeyEventStruct
    IMKeyEventStruct is used to represent a key value.

    IMKeyEventStruct

    typedef struct _IMKeyEventStruct {
    int keyCode;
    int keyChar;
    int modifier;
    int time_stamp;
    } IMKeyEventStruct, *IMKeyList;

    keyCode
    Specifies keycode
    keyChar
    Specifies UTF-16 coded character
    modifier
    Specifies key modifier
    time_stamp
    Specifies the time when key was pressed/released.

    8.8.3.2.2 IMKeyListEvent
    IMKeyListEvent structure is used for communicating KeyPress Event between IM Client and IM Server.

    IMKeyListEvent Structure
    typedef struct _IMKeyListEvent {
    int type;
    int n_operation;
    IMOperationList operation_list;

    int n_key;
    IMKeyList keylist;
    } IMKeyListEvent;
    type Specify the type of InputEvent . Should be IM_EventKeyList
    n_operation Specifies the number of IMOperationList
    IMOperationList is not supported in this version. should be 0.
    operation_list Specifies the IMOperationList
    IMOperationList is not supported in this version . should be NULL.
    n_key
    Specify the number of IMKeyEventStruct
    keylist
    Specify the pointer of IMKeyEventStruct

    8.8.3.2.3 IMKeyReleaseListEvent
    IMKeyReleaseListEvent structure is used for communicating KeyRelease Event between IM Client and IM Server.

    IMKeyReleaseListEvent Structure
    typedef struct _IMKeyReleaseListEvent {
    int type;
    int n_operation;
    IMOperationList operation_list;

    int n_key;
    IMKeyList keylist;
    } IMKeyReleaseListEvent;
    type Specify the type of InputEvent . Should be IM_EventKeyReleaseList
    n_operation Specifies the number of IMOperationList
    IMOperationList is not supported in this version. should be 0.
    operation_list Specifies the IMOperationList
    IMOperationList is not supported in this version . should be NULL.
    n_key
    Specify the number of IMKeyEventStruct
    keylist
    Specify the pointer of IMKeyEventStruct

    8.8.3.3 String Event

    IMStringEvent structure is used for communicating Unicode String between IM Client and IM Server.
    Typically, IMStringEvent notifies Text Conversion request from the IM Client.
    IMStringEvent
    typedef struct _IMStringEvent {
    int type;
    int n_operation;
    IMOperationList operation_list;
    UTFCHAR *string;
    } IMStringEvent;
    type
    Specifies the type of InputEvent . Should be IM_EventString
    n_operation
    Specifies the number of IMOperationList
    IMOperationList is not supported in this version. should be 0.
    operation_list
    Specifies the IMOperationList
    IMOperationList is not supported in this version . should be NULL.
    string
    Specifies UTF-16 coded string.

    8.8.3.4 Text Event

    IMTextEvent structure is used for communicating IMText between IM Client and IM Server.
    IMTextEvent
    typedef struct _IMTextEvent {
    int type;
    int n_operation;
    IMOperationList operation_list;
    IMText *text;
    } IMTextEvent;
    type
    should be IM_EventText
    n_operation
    Specifies the number of IMOperationList
    IMOperationList is not supported in this version. should be 0.
    operation_list
    Specifies the IMOperationList
    IMOperationList is not supported in this version . should be NULL.
    text IMText structure

    8.8.3.5 HotKey Event

    IMHotkeyEvent structure is used for notifying Hotkey is pressed.

    IMHotkeyEvent

    type
    n_operation
    operation_list
    n_key
    keylist
    state

    id

    8.8.3.6 Auxiliary Event

    8.8.3.6.1 IMAuxEvent
    IMAuxEvent structure is an event that indicates Aux send some information to Language Engine.

    IMAuxEvent
    typedef struct _IMAuxEvent {
    int type;
    IMAuxDrawCallbackStruct *aux;
    } IMAuxEvent;
    type
    Specifies the type of InputEvent. should be IM_AuxEventSet
    aux
    Specifies the IMAuxDrawCallbackStruct that holds the notify message from Aux Object.

    8.8.3.6.2 IMAuxGetEvent
    IMAuxGetEvent structure is an event that indicates Aux wants to know some information from Language Engine.
    While IMAuxEvent can only send notify messages to the Language Engine from Aux,
    IMAuxGetEvent can notify the message and receive the response from the Language Engine.

    IMAuxGetEvent
    typedef struct _IMAuxGetEvent {
    int type;
    IMAuxDrawCallbackStruct *fromaux; /* AUX -> LE */
    IMAuxDrawCallbackStruct *toaux; /* LE -> AUX */
    } IMAuxGetEvent;
    type
    Specifies the type of InputEvent. Should be IM_AuxGetEvent
    fromaux
    Specifies the IMAuxDrawCallbackStruct that holds the request notify from Aux Object.
    toaux
    Specifies the IMAuxDrawCallbackStruct that holds the reply  to Aux Object.

    8.8.4 Receiving Key Event

    Every Key Event is passed in if_SendEvent() as IMKeyListEvent and IMKeyReleaseListEvent, which have a list of IMKeyEventStruct structure. The Language Engine may know which key was pressed or released on the client by checking IMKeyEventStruct structure.

    int keyCode;		/* keycode, defined in IM Engine.h */
    int keyChar; /* keychar is defined */
    int modifier; /* modifier */

    8.8.4.1 Example

    Example
    if(ev->type == IM_EventKeyList){
    IMKeyListEvent *keylistevent=(IMKeyListEvent*)ev;
    int i;
    for (i = 0; i < keylistevent->n_keys; ++i) {
    IMKeyEventStruct key = keylistevent->keylist[i];
    }
    }

    For example, when 'a' is pressed on the client, the following values will be passed to if_SendEvent() If method. IM_VK_A is a keycode which is defined in SunIM.h.

    keyCode  : IM_VK_A
    keyChar : 'a'
    modifier : 0

    When Control+w is pressed, the following values will be passed. IM_CTRL_MASK is defined in SunIM.h as well.

    keyCode  : IM_VK_W;
    keyChar : 'w';
    modifier : IM_CTRL_MASK

    Please refer to Appendix C. for key modifier and keycode in detail.

    8.8.5 Returning a Key Event

    When a key event is not necessary for LE, which means the key event is not needed for the conversion, the Language Engine may want to notify that to the client. For example, the Language Engine will commit pre-edit string by enter key when the pre-edit string exists, however, when there is no pre-edit string, the Language Engine may ignore that event and return the key event of an enter key to the client.

    For this purpose, iml_make_keypress_inst() and iml_make_keyrelease_inst() IML methods are provided. The methods return a key event to the client. Please refer iml_make_keypress_inst() and iml_make_keyrelease_inst() section of IML method .

    8.8.6 Receiving Auxiliary Event

    Auxiliary events are also passed in if_SendEvent() as IMAuxEvent and IMAuxGetEvent. IMAuxDrawCallbackStruct can be retrieved from aux field of IMAuxEvent

    8.8.6.1 Example

    Example
    if(ev->type == IM_EventAux){
    IMAuxEvent *auxevent=(IMAuxEvent*)ev;
    IMAuxDrawCallbackStruct *draw=auxevent->aux;
    }

    Note that SDK1.0 based if_SetAuxValues If Method had been obsoleted.

    8.9 Managing Desktop and Session

    Language Engine may wants to know how many users are using the engine, how many sessions are opened. desktop_list and session_list are provided in iml_if_t and iml_desktop_t strucure for such purposes.

    iml_desktop_list If->desktop_list;

    iml_session_list desktop->session_list;

    Language Engine can retrieve the entry and look into the each desktop and session.

    8.9.1 Example

    Example
    Bool
    if_template_OpenDesktop(
    iml_desktop_t *desktop,
    IMArgList args,
    int n_args
    )
    {
    /*
    list users who already used
    */
    iml_desktop_t *p = desktop->If->desktop_list;
    while(p) {
    printf("user name=%s host=%s\n",
    p->user_name,
    p->host_name);
    if(p->next) p = p->next;
    else break;
    }
    ...
    }

    session_list of desktop can be used as well.
     
    Example
        iml_session_t *p = s->desktop->session_list;
    while(p) {
    if(p->next) p = p->next;
    else break;
    }

    9. IML Method

    IML Method is a set of functions predefined in IM Engine library to create iml_inst instance, which controls pre-edit drawing, status drawing, handling lookup choice and etc.
    Creating iml_inst instance does not mean to execute, send the command to the client. Each iml_make_ IML methods only create iml_inst instance. iml_execute() is a IML method to execute, in other word, to send IML commands to the client. Thus, network connection does not occur until iml_execute() is called.

    There are some convention for each IML methods. Basically, iml_make_*_start_inst() IML methods are provided to tell start operation to the client. For example, when Language Engine wants to draw pre-edit string, Language Engine should create iml_inst instance by calling iml_make_preedit_start_inst() then should call iml_execute().

    After iml_execute() is called, Language Engine can draw pre-edit with the iml_inst instance created by iml_make_draw_preedit_inst() IML methods. And iml_make_*_done_inst() IML methods are for stop the operations. When Language Engine does not need any drawing of the pre-edit string, LE should create iml_inst instance by iml_make_preedit_done_inst() and should call iml_execute().

    The arguments of IML methods that represent string should be UTF-16 for multilocale support. UTFCHAR is for string. IMText is for string, its feedback and annotation. The feedback is now supported with Color representation in IM Engine interface. Strings on pre-edit, status and lookup choice can be drawn with specified Color.


    9.1 Retrive IML Methods from iml_session_t

    In order to use IML Methods, we need to get iml_methods_t from iml_session_t structure. we can get iml_methods_t from If member of iml_session_t. For example, if you want to start pre-edit, you can call iml_make_preedit_start() through iml_session_t->If->m->iml_make_preedit_start()

    9.2 Drawing Pre-edit

    The following IML methods are provided for control pre-edit string. First, Language Engine should call iml_make_preedit_start_inst() to create an iml_inst instance to start the pre-edit drawing. The instance should be executed by iml_execute() before iml_make_preedit_draw_inst() is called. To draw pre-edit string, iml_make_preedit_draw_inst() can be used. To replace the existing pre-edit string, iml_make_preedit_draw_with_chgpos_inst() can be used.

    When Language Engine wants to stop the pre-edit drawing, iml_make_preedit_done_inst() should be called to create an iml_inst and should be sent by iml_execute().

    9.2.1 iml_make_preedit_start_inst()

    This method creates an iml_inst instance to start pre-edit drawing. Language Engine should create this instance and send the instance by iml_instiml_execute() before iml_make_preedit_draw_inst() is called.

    iml_inst *(*iml_make_preedit_start_inst)(iml_session_t *s)

    9.2.2 iml_make_preedit_draw_inst()

    This method creates an iml_inst instance to draw the preedit. It's the simplest way to create iml_inst instance for pre-edit drawing. At default, the caret position is moved to the end of entered pre-edit string.

    iml_inst *(*iml_make_preedit_draw_inst)(iml_session_t *s, IMText *preedit)

    9.2.3 iml_make_preedit_draw_with_chgpos_inst()

    This method creates an iml_inst instance to replace, delete, insert the pre-edit string to the existing pre-edit string.

    Text Deletion When the preedit field contains 0 length of text data, it indicates the delete operation. The text to be deleted is then the current text in the buffer from position chg_first (starting at zero) on a character length of chg_length.

    When the preedit field contains possible length of text data, it indicates either insertion or replacement of text in the buffer.

    Text Insertion A chg_length value of zero indicates that text must be inserted right at the position specified by chg_first. A value of zero for chg_first specifies the first character in the buffer.


    Text Replacement A positive chg_length indicates that chg_length number of characters, starting at chg_first must be replaced by text, whose length is specified in the text field of the preedit data.

    Moving Caret The caret field identifies the character position before which the cursor should be placed - after modification to the preedit buffer by insertion/replacement/deletion has been completed. For example, if caret is zero, the cursor is at the beginning of the buffer. If the caret is one, the cursor is between the first and second character.

    iml_inst *(*iml_make_preedit_draw_with_chgpos_inst)(iml_session *s, IMText *preedit, int chg_first, int chg_length, int caret)

    9.2.4 iml_make_preedit_erase_inst()

    This method creates an iml_inst instance to erase the existing pre-edit string entirely.

    iml_inst *(*iml_make_preedit_erase_inst)(iml_session_t *s)


    9.2.5 iml_make_preedit_caret_inst()

    This method creates an iml_inst instance to set position of caret. The pre-edit text will not be changed.

    iml_inst *(*iml_make_preedit_caret_inst)(iml_session_t *s, int caret)

    9.2.6 iml_make_preedit_done_inst()

    This method creates an iml_inst instance to stop pre-edit drawing. Language Engine should create this iml_inst instance and send the instance by iml_execute() when pre-edit drawing is not needed anymore.

    iml_inst *(*iml_make_preedit_done_inst)(iml_session_t *s)

    9.3 Drawing Status

    To draw status field, the following IML method can be used. First, Language Engine should call iml_make_status_start_inst() to create an iml_inst instance to start the status drawing. The instance should be executed by iml_execute() before iml_make_status_draw_inst() is called. When Language Engine does not need any status drawing, an iml_inst instance created by iml_make_status_down_inst() should be executed by iml_execute().

    9.3.1 iml_make_status_start_inst()

    This method creates an iml_inst instance to start status drawing. Language Engine should create this instance and send the instance by iml_instiml_execute() before iml_make_status_draw_inst() is called.

    iml_inst *(*iml_make_status_start_inst)(iml_session_t *s)

    9.3.2 iml_make_status_draw_inst()

    This method creates an iml_inst instance to draw status string.

    iml_inst *(*iml_make_status_draw_inst)(iml_session_t *s, IMText *status)

    9.3.3 iml_make_status_done_inst()

    This method creates an iml_inst instance to stop status drawing. Language Engine should create this iml_inst instance and send the instance by iml_execute() when status drawing is not needed anymore.

    iml_inst *(*iml_make_status_done_inst)(iml_session_t *s)


    9.4 Start and Stop Forwarding Event

    After conversion is turned on, input events on the client associated with the session is being forwarded to the Language Engine through if_SendEvent() IF method. When Language Engine have not set SC_TRIGGER_OFF_KEY SC attribute in if_SetSCValues() IF method, Language Engine oughts to check the input event to find the off key, then if the input event is assigned for off key, Language Engine should send an iml_inst instance created by this method.

    9.4.1 iml_make_start_conversion_inst()


    iml_inst *(*iml_make_start_conversion_inst)(iml_session_t *s)

    9.4.2 iml_make_end_conversion_inst()

    iml_inst *(*iml_make_end_conversion_inst)(iml_session_t *s)

    9.5 Handling Lookup Choice

    To control lookup choice on the client side, the following IML methods are provided. First, Language Engine should create iml_inst instance to start lookup operation by iml_make_lookup_start_inst(), which takes IMLookupStartCallbackStruct structure.
    To display lookup with candidate, the iml_inst instance can be created by iml_make_lookup_draw_inst(), which takes IMLookupDrawCallbackStruct structure. by iml_make_lookup_process_inst() . After a candidate is selected on the lookup choice, Language Engine needs to create iml_inst instance to stop the lookup by iml_make_lookup_done_inst() IML method, then needs to send committed string by iml_make_commit_inst() IML method.

    9.5.1 Data Structure used for handling Lookup Choice

    9.5.1.1 IMChoiceObject

    IMChoiceObject has a pair of IMText. label is used to provide some information, such as short cut key to select the candidate, and value indicates the actual candidate for the input text.
    IMChoiceObject
    typedef struct _IMChoiceObject {
      IMText *label;
      IMText *value;
    } IMChoiceObject;

    label
    Specifies the label
    value
    Specifies the value
       

    9.5.1.2 IMLookupStartCallbackStruct

    IMLookupStartCallbackStruct is used to notify Language Engine want to start Lookup Choice operation.

    IMLookupStartCallbackStruct
    whoIsMaster This field indicates the IMClient how the IMServer will handle the lookup choice operation. Only IMIsMaster is supported, which means the IM Language Engine needs to send a request to lookup draw every time the lookup candidates change.
    IMPreference.choice_per_window This field specifies the number of lookup candidates to display in a lookup window at one time.
    IMPreference.ncolumns This field specifies the number of columns of lookup candidates to display in a lookup window.
    IMPreference.nrows This field specifies the number of rows of lookup candidates to display in a lookup window.
    IMPreference.drawUpDirection This field specifies the drawing direction of lookup candidates. DrawUpHorizontally(0) and DrawUpVertically(1) are supported.
    IMPreference.whoOwnsLabel This field indicates whether the lookup candidates will be labeled, the IM Language Engine or Client. Only IMOwnsLabel is supported, which means the Languane Engine is responsible for labeling the candidates in IMLookupDrawCallbackStruct.

    9.5.1.3 IMLookupDrawCallbackStruct

    IMLookupDrawCallbackStruct is used to update the candidates for lookup choice.
    IMLookupDrawCallbackStruct
    typedef struct _IMLookupDrawCallbackStruct {
      IMChoiceObject *choices;
      int n_choices;
      int max_len;
      int index_of_first_candidate;
      int index_of_last_candidate;
      int index_of_current_candidate;
      IMText *title;
    } IMLookupDrawCallbackStruct;


    index_of_first_candidate This field specifies index of the first candidate.
    index_of_last_candidate This field specifies index of the last candidate.
    n_choices This field specifies the number of choices of the lookup choice.
    title This field specifies title of the lookup choice as IMText structure.
    choices This field specifies each candidate (value) and its label(label) as IMChoiceObject structure.
    max_len This field specifies the maximum length of the candidates.
    index_of_current_candidate This field specifies the index of current candidate, which is displayed as reversed on the lookup choice.

    9.5.2 iml_make_lookup_start_inst()

    This method creates an iml_inst instance to start lookup operation. This method needs IMLookupStartCallbackStruct structure as the argument. Language Engine specifies detail attributes, such as the number of row and column in IMLookupStartCallbackStruct.

    iml_inst *(*iml_make_lookup_start_inst)(iml_session_t *s, IMLookupStartCallbackStruct *start)

    9.5.2.1 Example

    The following code shows how to start lookup choice operation.
    Example
        IMLookupStartCallbackStruct *start;

    start = (IMLookupStartCallbackStruct *) s->If->m->iml_new(s,
    sizeof(IMLookupStartCallbackStruct));
    start->whoIsMaster = IMIsMaster;

    start->IMPreference = (LayoutInfo *) s->If->m->iml_new(s,
    sizeof(LayoutInfo));

    start->IMPreference->choice_per_window = 6;
    start->IMPreference->ncolumns = 1;
    start->IMPreference->nrows = 6;
    start->IMPreference->drawUpDirection = DrawUpHorizontally;
    start->IMPreference->whoOwnsLabel = IMOwnsLabel;

    lp = s->If->m->iml_make_lookup_start_inst(s, start);
    s->If->m->iml_execute(s, &lp);

    9.5.3 iml_make_lookup_draw_inst()

    This method creates an iml_inst instance to display the lookup. This method can take IMLookupDrawCallbackStruct so that the Language Engine specifies detail attributes, such as label for each candidate, number of row and column and etc.

    iml_inst *(*iml_make_lookup_draw_inst)(iml_session_t *s, IMLookupDrawCallbackStruct *draw)

    9.5.3.1 Example

    The following code shows how to update lookup choice.
    Example
        IMLookupStartCallbackStruct *draw;
    IMText *candidates;
    IMText *label;
    int current_index;
    int max_len;

    draw = (IMLookupDrawCallbackStruct *) s->If->m->iml_new(s,
    sizeof(IMLookupDrawCallbackStruct));
    draw->index_of_first_candidate = 0;
    draw->index_of_last_candidate = 5;
    draw->n_choices = 6;

    draw->title = (IMText *) make_luc_title();

    draw->choices = (IMChoiceObject *) s->If->m->iml_new(s,
    draw->n_choices * sizeof(IMChoiceObject));

    for (i = 0; i < draw->n_choices; i++) {
    IMText *vt; /* for value */
    IMText *lt; /* for label */
    vt = draw->choices[i].value = candidates[i];
    lt = draw->choices[i].label = labels[i];
    if (max_len < vt->utf_char_length)
    max_len = vt->utf_char_length;
    }

    draw->max_len = max_len;
    draw->index_of_current_candidate = current_index;

    lp = s->If->m->iml_make_lookup_draw_inst(s, draw);
    s->If->m->iml_execute(s, &lp);

    9.5.4 iml_make_lookup_done_inst()

    This method creates an iml_inst instance to stop the lookup. Language Engine should create this iml_inst   instance and sends the command by iml_execute() when Language Engine want to stop the lookup operation.

    iml_inst *(*iml_make_lookup_done_inst)(iml_session_t *s)

    9.6 Committing Pre-edit

    This method creates an iml_inst instance to enter strings to the client associated with the session. After pre-edit string is committed, Language Engine needs to create this iml_inst instance and send the command by iml_execute(). IMText *text is committed. Note that before committing the text, you need to erase the pre-edited strings.

    9.6.1 iml_make_commit_inst()

    iml_inst *(*iml_make_commit_inst)(iml_session_t *s, IMText *text)

    9.7 Returning Key Event

    These methods create an iml_inst instance to return a keyevent to the client associated with the session. When the language engine does not process the keyevent received at if_SendEvent() If Method, the language engine can return the keyevent to the client. For example, the language engine does not need arrow keys for the conversion but the client needs for the caret movement, the language engine needs to return the keyevent to the client by this IML methods.

    9.7.1 iml_make_keypress_inst()

    iml_inst *(*iml_make_keypress_inst)(iml_session_t *s, IMKeyEventStruct *key)

    9.7.2 iml_make_keyrelease_inst()

    iml_inst *(*iml_make_keyrelease_inst)(iml_session_t *s, IMKeyEventStruct *key)

    9.8 Handling Auxiliary Object

    Language Engine can send own AUX modules to the client through iiimd. After sending AUX modules, Language Engine can controls the AUX by these methods. Each methods take IMAuxStartCallbackStruct,IMAuxDrawCallbackStruct, and IMAuxDoneCallbackStruct  as the argument.

    9.8.1 Data Structure used for handling Auxiliary Object

    9.8.1.1 IMAuxBaseCallbackStruct

    IMAuxBaseCallbackStruct
    aux_name
    Specifies class name for Auxiliary Object. For Java AUX, this field should be a class name which is defined in IMObjectDescriptorStruct.
    aux_index Deprecated. Should not use.

    9.8.1.2 IMAuxStartCallbackStruct

    IMAuxStartCallbackStruct structure is used to notify that Language Engine wants to start Auxiliary Object.
    IMAuxStartCallbackStruct
    typedef IMAuxStartCallbackStruct IMAuxBaseCallbackStruct

    9.8.1.3 IMAuxDoneCallbackStruct

    IMAuxDoneCallbackStruct structure is used to notify that Language Engine wants to stop Auxiliary Object.
    IMAuxDoneCallbackStruct
    typedef IMAuxDoneCallbackStruct IMAuxBaseCallbackStruct

    9.8.1.4 IMAuxDrawCallbackStruct

    IMAuxDrawCallbackStruct structure is used to communicate between Language Engine and Auxiliary Object.
    IMAuxDrawCallbackStruct
    aux_name
    Specifies class name for Aux. For Java AUX, this field should be a class name which is defined in IMObjectDescriptorStruct.
    aux_index
    Deprecated. Should not use.
    count_integer_values
    Specifies the number of integer for count_integer_values. 
    integer_values Specifies integer array. 
    count_string_values Specifies number of string for string_values. 
    string_values Specifies string array as IMText format. 

    9.8.2 iml_make_aux_start_inst()

    This method creates an iml_inst instance to start AUX module. Language Engine needs to specify AUX id in IMAuxStartCallbackStruct structure.

    iml_inst *(*iml_make_aux_start_inst)(iml_session_t *s, IMAuxStartCallbackStruct *start)

    9.8.3 iml_make_aux_done_inst()

    This method creates an iml_inst instance to stop AUX. Language Engine needs to specify AUX id in IMAuxDoneCallbackStruct  structure. Language Engine should create this iml_inst instance and send the instance by iml_execute() when AUX is not needed anymore.

    iml_inst *(*iml_make_aux_done_inst)(iml_session_t *s, IMAuxDoneCallbackStruct *done)

    9.8.4 iml_make_aux_draw_inst()

    This method creates an iml_inst instance to control Auxiliary module. Language Engine can send Language Engine Specific Message to Auxiliary Object. In order to send a message correctly, Language Engine needs to specify Auxiliary id and integer and string array in IMAuxDrawCallbackStruct structure.

    iml_inst *(*iml_make_aux_draw_inst)(iml_session_t *s, IMAuxDrawCallbackStruct *draw)

    The events of actions on the Auxiliary Object can be received by if_SendEvent() IF method. IMInputEvent *ev of its argument is set for IMAuxEvent structure.

    9.9 Linking IML Instance at Tail of List

    After creating of each iml_inst, Language Engine can execute the command by calling iml_execute(). However, multiple iml_inst can be stacked by this method, then can be executed by iml_execute(). This means that Language Engines does not have to call iml_execute() after each iml_inst creation.

    9.9.1 iml_link_inst_tail()

    iml_inst *(*iml_link_inst_tail)(iml_inst **rrv,iml_inst *lp)

    9.9.2 Example

    The following code shows how to use iml_link_inst_tail.

    Example
        iml_inst *rrv = NULL;
    iml_inst *lp;

    lp = s->If->m->iml_make_preedit_draw_inst(s, preedit_string);
    s->If->m->iml_link_inst_tail(&rrv, lp);

    lp = s->If->m->iml_make_status_draw_inst(s, status_string);
    s->If->m->iml_link_inst_tail(&rrv, lp);

    ...

    /*
    execute commands created by
    iml_make_preedit_draw_inst() and
    iml_make_status_draw_inst()
    */
    s->If->m->iml_execute(s, &rrv);

    9.10 Execute the commands

    This method executes IML commands, which means sends actual protocol to the client associated with the session. The chain of iml_inst stacked by iml_link_inst_tail() method can be specified.

    9.10.1 iml_execute()

    iml_inst *(*iml_execute)(iml_session_t *s, iml_inst **lp);

    10. MM Methods

    The following four methods are provided for management of allocation and deallocation of memory, which are convenient for Language Engine interface. Note that these MM methods are part of IML methods.

    10.1 Allocate Area

    iml_new() allocates area for short-life-cycle, which means the area allocated by iml_new() are freed before the next IF methods is called. For example, when you allocates an area by iml_new() in If_SetSCValues(), you don't need to free the area at the end of the method because the area will be freed before next call of IF methods, such as if_SendEvent(). The argument takes a iml_session_t* session and the area to be allocated are associated with the session. So it's possible for Language Engine to manage the allocated area per session. Conversely, iml_new2() allocates area for long-life-cycle area, which is alive while the session is alive, will not be freed until the session is destroyed so that Language Engine can use the area through until the session is destroyed.

    10.1.1 iml_new()

    void *iml_new(iml_session_t *s, int size)

    10.1.2 iml_new2()

    void *iml_new2(iml_session_t *s,int size)

    10.1.3 Example


    The following code explains how to allocate memory through MM methods.

    Example
    	/*
    this area is alive until the session is
    destroyed or until iml_delete2() is called.
    */
    char *long_life_area=(char*)s->If->m->iml_new2(s,1000);

    /*
    this area is only alive in this method or
    until iml_delete() is called.
    */
    char *short_life_area=(char*)s->If->m->iml_new(s,1000);

    10.2 Free Area

    To free the area allocated by iml_new() and iml_new2(), these methods can be used. iml_delete() MM method frees the area allocated by iml_new(). iml_delete2() MM method frees the area allocated by iml_new2(). However, normally LE does not need to call these method manually. the area alloced by iml_new() is freed by iml_delete() automatically in IM Engine library before calling the next IF methods. the area alloced by iml_new2() is freed by iml_delete2() automatically at the session is destroyed.

    iml_delete()


    void iml_delete(iml_session_t *s)


    iml_delete2()


    void iml_delete2(iml_session_t *s)

    11. Namespace

    In general, Language Engines use this set of APIs int the following order.

    1. in if_OpenIF(), retrieve namespace related functions.
    2. in if_OpenIF(), create a namespace context for the LE.
    3. in if_OpenDesktop() or if_CreateSC(), create a namespace context for a user.
    4. while the context is valid, any namespace based file I/O functions can be used.
    5. in if_CloseDesktop() or if_DestroySC(), free the namespace context for the user.
    6. in if_CloseIF(), free the namespace context for the LE. When appropriate, namespace contexts, which will not be used anymore, can be freed.

    11.1 Create/Destroy a Namespace Context for Language Engine

    If an LE access files which is not related to a specific user, the LE can create a namespace context and use it to access the files. Example:
        iml_nsc_t * nsc;
    iml_if_t * If;
    int fd;
    int rval;
    char buf[1024];

    nsc = le_nsc_create("sampleLE", IML_NSC_TYPE_LE, If);
    fd = le_open(nsc, "/etc/iiim/le/sampleLE/sampleLE.cfg", O_RDONLY);
    rval = le_read(nsc, fd, buf, sizeof(buf));
    /* do something */
    le_close(nsc, fd);

    Note:

    1. IIIMServer reads the Namespace mapping rules created by the User and then redirects the I/O operations.

    Sample namespace mapping rules are defined in the last section.

    2. The namespace based file I/O calls such as le_open(), le_creat(), le_opendir() ..etc, returns a namespace identifier which is the file descriptor (or) the directory stream pointer equivalent. This namespace identifier should be passed to other I/O calls such as le_read(), le_write(), le_close(), le_stat(), le_readdir(), le_closedir(), le_fcntl() ..etc.

    11.2 Free the namespace context for the user

    If an LE does not need a namespace context for a specific user anymore, the LE can free the namespace context. Example:
        iml_nsc_t * nsc;

    le_nsc_free(nsc);

    11.3 Create/Destroy a Namespace Context for an User

    If LE needs access to files related to a specific user, then LE can create a namespace context for the user, and use it to access the files. Example:
        iml_nsc_t *     nsc;
    iml_desktop_t * desktop;
    int fd;
    int rval;
    char buf[1024];

    nsc = le_nsc_create("sampleLE", IML_NSC_TYPE_DESKTOP, desktop);
    fd = le_open(nsc, "/var/lib/iiim/le/sampleLE/userA/config", O_RDONLY);
    rval = le_read(nsc, fd, buf, sizeof (buf));
    /* do something */
    le_close(nsc, fd);
    Note:

    IIIMServer reads the Namespace mapping rules created by the User and then redirects the I/O operations.

    Sample namespace mapping rules are defined in the last section.


    11.4 Free the namespace context for the LE

    If an LE does not need a namespace context which is not related to specific user anymore, the LE can free the namespace context. Example:
        iml_nsc_t * nsc;

    le_nsc_free(nsc);

    12. Example Code

    IIIMP SDK contains two example language engines.

    Template for Language Engine

    template.c is provided for the template. All If method are pre-defined so the IM developer can copy and modify it to create own Language Engine Module easily.

    src/server/programs/language_engines/template.c

    Sample for Japanese Language Engine

    sampleja.c is also provided for IM developer. It's more complex but it's very useful. The pre-edit, status drawing, lookup choice operation are defined. For the keybind of sampleja sample Language Engine Module, please refer the README file on the directory.

    src/server/programs/language_engines/sampleja

    And sampleja2.cpp is an example for C++ programming interface.

    src/server/programs/language_engines/sampleja2

    Appendix A. Method Summary

    IF Method Summary

    IF Method
    Opening and Closing an IF
    Bool if_OpenIF(iml_if_t *If)
    Bool if_CloseIF(iml_if_t *If)
    Setting and Querying IF Values
    Bool if_GetIFValues(iml_if_t *If, IMArgList args, int n_args)
    Bool if_SetIFValues(iml_if_t *If, IMArgList args, int n_args)
    Opening and Closing User Desktop
    Bool if_OpenDesktop(iml_desktop_t *desktop, IMArgList args, int n_args)
    Bool if_CloseDesktop(iml_desktop_t *desktop)
    Creating and Destroying a Session Context
    Bool if_CreateSC(iml_session_t *s, IMArgList args, int n_args)
    Bool if_DestroySC(iml_session_t *s)
    Setting and Querying SC Values
    Bool if_GetSCValues(iml_session_t *s, IMArgList args, int n_args)
    Bool if_SetSCValues(iml_session_t *s, IMArgList args, int n_args)
    Resetting a Session
    IMText* if_ResetSC(iml_session_t *s)
    Handling Focus
    void if_SetSCFocus(iml_session_t *s)
    void if_UnsetSCFocus(iml_session_t *s)
    Handling Input Event
    void if_SendEvent(iml_session_t *s, IMInputEvent *ev)

    IML Method Summary

    IML Method
    Drawing Preedit
    iml_inst* iml_make_preedit_start_inst(iml_session_t *s)
    iml_inst* iml_make_preedit_draw_inst(iml_session_t *s, IMText *preedit)
    iml_inst* iml_make_preedit_caret_inst(iml_session_t *s, int caret)
    iml_inst* iml_make_preedit_draw_with_chgpos_inst(iml_session_t *s, IMText *preedit, int chg_first, int chg_length, int caret)
    iml_inst* iml_make_preedit_erase_inst(iml_session_t *s)
    iml_inst* iml_make_preedit_done_inst(iml_session_t *s)
    Drawing Status String
    iml_inst* iml_make_status_start_inst(iml_session_t *s)
    iml_inst* iml_make_status_draw_inst(iml_session_t *s, IMText *status)
    iml_inst* iml_make_status_done_inst(iml_session_t *s)
    Handling Lookup Choice
    iml_inst* iml_make_lookup_start_inst(iml_session_t *s, IMLookupStartCallbackStruct *ls)
    iml_inst* iml_make_lookup_draw_inst(iml_session_t *s, IMLookupDrawCallbackStruct *ld);
    iml_inst* iml_make_lookup_done_inst(iml_session_t *s)
    Committing Text
    iml_inst* iml_make_commit_inst(iml_session_t *s, IMText *text)
    Returning KeyEvent
    iml_inst* iml_make_keypress_inst(iml_session_t *s, IMKeyEventStruct *key)
    iml_inst* iml_make_keyrelease_inst(iml_session_t *s, IMKeyEventStruct *key)
    Handling Aux
    iml_inst* iml_make_aux_start_inst(iml_session_t *s, IMAuxStartCallbackStruct *start)
    iml_inst* iml_make_aux_draw_inst(iml_session_t *s, IMAuxDrawCallbackStruct *draw)
    iml_inst* iml_make_aux_done_inst(iml_session_t *s, IMAuxDoneCallbackStruct *done)
    Start and Stop forwarding event
    iml_inst* iml_make_start_conversion_inst(iml_session_t *s)
    iml_inst* iml_make_end_conversion_inst(iml_session_t *s)
    Linking and Execute Commands
    iml_inst* iml_link_inst_tail(iml_inst **rrv, iml_inst *lp)
    iml_inst* iml_execute(iml_session_t *s, iml_inst** lp)

    MM Method Summary

    MM Method
    Allocates Area
    void* iml_new(iml_session_t *s, int size)
    void* iml_new2(iml_session_t *s, int size)
    Free Area
    void iml_delete(iml_session_t *s)
    void iml_delete2(iml_session_t *s)

    Appendix B. IF Attribute and SC Attribute

    IF, SC and UI attributes are defined as int by enum

    IF Attribute

    IF Attributes
    IF_VERSION required in if_GetIfInfo() Specifies the version of IM Engine library. It takes char* and _IF_VERSION_ is predefined in SunIM.h header.
    IF_METHOD_TABLE required in if_GetIfInfo() Specifies the address of the method table. It takes if_methods_t*.
    IF_LE_NAME required in if_GetIfInfo() Specifies the name of Language Engine Module. It takes IMLEName structure, which can represent id and human readable name of the Language Engine.
    IF_SUPPORTED_LOCALES required in if_GetIfInfo() Specifies supported locales by the Language Engine. It takes null terminated array of IMLocale structure. The id and human readable name of the locale can be represented.
    IF_SUPPORTED_OBJECTS optional in if_GetIfInfo() Specifies supported object descripters by the Language Engine. It takes null terminated array of IMObjectDescriptorStruct structure.
    IF_NEED_THREAD_LOCK optional in if_GetIfInfo() Specifies True or False whether the LE is MT-safe or not. False is the default. When the attribute is set as True, IM Engine locks the thread while each IF method is processing and unlocks after IF method is returned.
    IF_SUPPORTED_IMEINFO
    optional in if_GetIfInfo()
    Specifies supported IM Logics. It takes null terminated array of IMEInfo structure.
    IF_HAVE_LOCALE_DEPENDENCY optional in if_GetIfInfo() Specifies True or False whether the LE has the locale dependency. For example, the LE uses wchar_t representation and uses mbtowcs() and wcstombs(). False is the default.
    G = used in if_GetIFValues()
    S = used in if_SetIFValues()
    G/S = used in both if_GetIFValues()/if_SetIFValues()

    SC Attribute

    SC Attributes
    Symbol

    Description
    SC_SUPPORTED_CHARACTER_SUBSETS G Specifies supported character subsets for the Language Engine. It takes null terminated array of int. The values of each character subsets are described in IM Attribute ID and Appendix B. Values for Character Subsets .

    Note:This attribute isn't implemented.

    SC_REALIZE S Notifies just after the session is created. For example, Language Engine wants to start Aux utility like pallet, LE can use this notification to create iml_inst of iml_make_aux_start_inst() and call iml_execute().

    Note that After the notification, LE can make iml_inst and call iml_execute(). In other words, LE can not create any iml_inst until this notification is received.

    SC_TRIGGER_ON_NOTIFY S Notifies starting of forward event from the client. For example, Language Engine can know the conversion is turned ON on the client by this notification. It's only for notification so the value is always NULL in if_SetSCValues() IF method.
    SC_CLIENT_LOCALE
    S
    Notifies IM client's locale name.
    SC_CLIENT_CHARACTER_SUBSETS
    S
    Notifies IM client's input method name.
    SC_CLIENT_INPUT_METHOD_ENGINE
    S
    Notifies IM client's input method information.
    SC_CLIENT_APPLICATION_NAME
    S
    Notifies IM client's application name.
    SC_REQUIRE_KEYRELEASE G
    Specifies whether your Language Engine is sensitive for KeyRelease Event.

    G = used in if_GetSCValues()
    S = used in if_SetSCValues()
    G/S = used in both if_GetSCValues()/if_SetSCValues()

    UI Attribute

    UI Attributes
    UI_USER_NAME   user name who is using the IM client. When Java client, System.getProperty("user.name") will be returned. When Solaris platform, getpwuid(getuid())->pw_name will be returned.
    UI_HOST_NAME   host name of IM client
    UI_DISPLAY_ID   If the client is X, the value of DisplayName(display) will be returned. If the client is Java, ":0.0" will always be returned.
    UI_PROTOCOL_TYPE   protocol type of IM client. "IIIMP" is for IIIM protocol, "XIMP" is XIM protocol or "XIMCP" if X11R6 XIMP protocol.
    UI_CLIENT_TYPE   client type of IM client. "JAVA" is for Java client, or "X" is for X client.
    UI_XSERVER_VENDOR   Only available if UI_PROTOCOL_TYPE is XIMP and XIMCP. The vendor name of X server on where IM client is running can be checked. The value of ServerVendor(display) will be returned.
    UI_OS_NAME   The name of operation system. For example, the IM client is running on Solaris platform, "SunOS" is returned. The value of System.getProperty("os.name") will be returned when UI_CLIENT_TYPE is JAVA. The value of sysinfo() with SI_SYSNAME will be returned when UI_CLIENT_TYPE is X.
    UI_OS_ARCH   The architecture of the operation system. For example, the IM client is running on Solaris SPARC platform, "sparc" is returned. On Solaris Intel platform, "x86" is returned. The value of System.getProperty("os.arch") will be returned when UI_CLIENT_TYPE is JAVA. The value of sysinfo() with SI_RELEASE will be returned when UI_CLIENT_TYPE is X. However, "i86pc" will be changed to "x86" for the compatibility for Java client.
    UI_OS_VERSION   The version of the operation system. For example, the IM client is running on Solaris 7, "5.7" is returned. The value of System.getProperty("os.version") will be returned when UI_CLIENT_TYPE is JAVA. The value of sysinfo() with SI_RELEASE will be returned when UI_CLIENT_TYPE is X.

    Appendix C. KeyCode and KeyMask


    Key Modifier Mask
    Symbol
    Value
    IM_SHIFT_MASK
    (1 <<  0)
    IM_CTRL_MASK
    (1 <<  1)
    IM_META_MASK
    (1 <<  2)
    IM_ALT_MASK
    (1 <<  3)
    IM_BUTTON1_MASK
    (1 <<  4)
    IM_ALT_GRAPH_MASK
    (1 <<  5)
    IM_BUTTON2_MASK
    IM_ALT_MASK
    IM_BUTTON3_MASK
    IM_META_MASK

    KeyCode
    Symbol
    Value
    IM_VK_ENTER '\n'
    IM_VK_BACK_SPACE '\b'
    IM_VK_TAB '\t'
    IM_VK_CANCEL 0x03
    IM_VK_CLEAR 0x0C
    IM_VK_SHIFT 0x10
    IM_VK_CONTROL 0x11
    IM_VK_ALT 0x12
    IM_VK_PAUSE 0x13
    IM_VK_CAPS_LOCK 0x14
    IM_VK_ESCAPE 0x1B
    IM_VK_SPACE 0x20
    IM_VK_PAGE_UP 0x21
    IM_VK_PAGE_DOWN 0x22
    IM_VK_END 0x23
    IM_VK_HOME 0x24
    IM_VK_LEFT 0x25
    IM_VK_UP 0x26
    IM_VK_RIGHT 0x27
    IM_VK_DOWN 0x28
    IM_VK_COMMA 0x2C
    IM_VK_MINUS 0x2D
    IM_VK_PERIOD 0x2E
    IM_VK_SLASH 0x2F
    IM_VK_0 0x30
    IM_VK_1 0x31
    IM_VK_2 0x32
    IM_VK_3 0x33
    IM_VK_4 0x34
    IM_VK_5 0x35
    IM_VK_6 0x36
    IM_VK_7 0x37
    IM_VK_8 0x38
    IM_VK_9 0x39
    IM_VK_SEMICOLON 0x3B
    IM_VK_EQUALS 0x3D
    IM_VK_A 0x41
    IM_VK_B 0x42
    IM_VK_C 0x43
    IM_VK_D 0x44
    IM_VK_E 0x45
    IM_VK_F 0x46
    IM_VK_G 0x47
    IM_VK_H 0x48
    IM_VK_I 0x49
    IM_VK_J 0x4A
    IM_VK_K 0x4B
    IM_VK_L 0x4C
    IM_VK_M 0x4D
    IM_VK_N 0x4E
    IM_VK_O 0x4F
    IM_VK_P 0x50
    IM_VK_Q 0x51
    IM_VK_R 0x52
    IM_VK_S 0x53
    IM_VK_T 0x54
    IM_VK_U 0x55
    IM_VK_V 0x56
    IM_VK_W 0x57
    IM_VK_X 0x58
    IM_VK_Y 0x59
    IM_VK_Z 0x5A
    IM_VK_OPEN_BRACKET 0x5B
    IM_VK_BACK_SLASH 0x5C
    IM_VK_CLOSE_BRACKET 0x5D
    IM_VK_NUMPAD0 0x60
    IM_VK_NUMPAD1 0x61
    IM_VK_NUMPAD2 0x62
    IM_VK_NUMPAD3 0x63
    IM_VK_NUMPAD4 0x64
    IM_VK_NUMPAD5 0x65
    IM_VK_NUMPAD6 0x66
    IM_VK_NUMPAD7 0x67
    IM_VK_NUMPAD8 0x68
    IM_VK_NUMPAD9 0x69
    IM_VK_MULTIPLY 0x6A
    IM_VK_ADD 0x6B
    IM_VK_SEPARATER 0x6C
    IM_VK_SUBTRACT 0x6D
    IM_VK_DECIMAL 0x6E
    IM_VK_DIVIDE 0x6F
    IM_VK_DELETE 0x7F
    IM_VK_NUM_LOCK 0x90
    IM_VK_SCROLL_LOCK 0x91
    IM_VK_F1 0x70
    IM_VK_F2 0x71
    IM_VK_F3 0x72
    IM_VK_F4 0x73
    IM_VK_F5 0x74
    IM_VK_F6 0x75
    IM_VK_F7 0x76
    IM_VK_F8 0x77
    IM_VK_F9 0x78
    IM_VK_F10 0x79
    IM_VK_F11 0x7A
    IM_VK_F12 0x7B
    IM_VK_F13 0xF000
    IM_VK_F14 0xF001
    IM_VK_F15 0xF002
    IM_VK_F16 0xF003
    IM_VK_F17 0xF004
    IM_VK_F18 0xF005
    IM_VK_F19 0xF006
    IM_VK_F20 0xF007
    IM_VK_F21 0xF008
    IM_VK_F22 0xF009
    IM_VK_F23 0xF00A
    IM_VK_F24 0xF00B
    IM_VK_PRINTSCREEN 0x9A
    IM_VK_INSERT 0x9B
    IM_VK_HELP 0x9C
    IM_VK_META 0x9D
    IM_VK_BACK_QUOTE 0xC0
    IM_VK_QUOTE 0xDE
    IM_VK_KP_UP 0xE0
    IM_VK_KP_DOWN 0xE1
    IM_VK_KP_LEFT 0xE2
    IM_VK_KP_RIGHT 0xE3
    IM_VK_DEAD_GRAVE 0x80
    IM_VK_DEAD_ACUTE 0x81
    IM_VK_DEAD_CIRCUMFLEX 0x82
    IM_VK_DEAD_TILDE 0x83
    IM_VK_DEAD_MACRON 0x84
    IM_VK_DEAD_BREVE 0x85
    IM_VK_DEAD_ABOVEDOT 0x86
    IM_VK_DEAD_DIAERESIS 0x87
    IM_VK_DEAD_ABOVERING 0x88
    IM_VK_DEAD_DOUBLEACUTE 0x89
    IM_VK_DEAD_CARON 0x8a
    IM_VK_DEAD_CEDILLA 0x8b
    IM_VK_DEAD_OGONEK 0x8c
    IM_VK_DEAD_IOTA 0x8d
    IM_VK_DEAD_VOICED_SOUND 0x8e
    IM_VK_DEAD_SEMIVOICED_SOUND 0x8f
    IM_VK_AMPERSAND 0x96
    IM_VK_ASTERISK 0x97
    IM_VK_QUOTEDBL 0x98
    IM_VK_LESS 0x99
    IM_VK_GREATER 0xa0
    IM_VK_BRACELEFT 0xa1
    IM_VK_BRACERIGHT 0xa2
    IM_VK_AT 0x0200
    IM_VK_COLON 0x0201
    IM_VK_CIRCUMFLEX 0x0202
    IM_VK_DOLLAR 0x0203
    IM_VK_EURO_SIGN 0x0204
    IM_VK_EXCLAMATION_MARK 0x0205
    IM_VK_INVERTED_EXCLAMATION_MARK 0x0206
    IM_VK_LEFT_PARENTHESIS 0x0207
    IM_VK_NUMBER_SIGN 0x0208
    IM_VK_PLUS 0x0209
    IM_VK_RIGHT_PARENTHESIS 0x020A
    IM_VK_UNDERSCORE 0x020B
    IM_VK_FINAL 0x0018
    IM_VK_CONVERT 0x001C
    IM_VK_NONCONVERT 0x001D
    IM_VK_ACCEPT 0x001E
    IM_VK_MODECHANGE 0x001F
    IM_VK_KANA 0x0015
    IM_VK_HANGUL 0x0015
    IM_VK_JUNJA 0x0017
    IM_VK_FINAL 0x0018
    IM_VK_KANJI 0x0019
    IM_VK_HANJA 0x0019
    IM_VK_ALPHANUMERIC 0x00F0
    IM_VK_KATAKANA 0x00F1
    IM_VK_HIRAGANA 0x00F2
    IM_VK_FULL_WIDTH 0x00F3
    IM_VK_HALF_WIDTH 0x00F4
    IM_VK_ROMAN_CHARACTERS 0x00F5
    IM_VK_ALL_CANDIDATES 0x0100
    IM_VK_PREVIOUS_CANDIDATE 0x0101
    IM_VK_CODE_INPUT 0x0102
    IM_VK_JAPANESE_KATAKANA 0x0103
    IM_VK_JAPANESE_HIRAGANA 0x0104
    IM_VK_JAPANESE_ROMAN 0x0105
    IM_VK_CUT 0xFFD1
    IM_VK_COPY 0xFFCD
    IM_VK_PASTE 0xFFCF
    IM_VK_UNDO 0xFFCB
    IM_VK_AGAIN 0xFFC9
    IM_VK_FIND 0xFFD0
    IM_VK_PROPS 0xFFCA
    IM_VK_STOP 0xFFC8
    IM_VK_COMPOSE 0xFF20
    IM_VK_ALT_GRAPH 0xFF7E
    IM_VK_UNDEFINED 0x0

    Appendix D. Future Enhancementds

    Appendix E. Change History

    Updates from SDK 1.2 Draft 1.2 Language Engine Interface Module

    TBD

    Updates from SDK 1.0 Language Engine Interface Module




    Copyright(C) 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
    Copyright(C) 2005 CICC. All RIghts Reserved.
    Copyright(C) 2005 OpenI18N.org. All Rights Reserved.