Language Engine Interface Specification 1.2

Draft

Draft Version 1.2
Oct 20 1999
Masaki Katakai

Updates from SDK 1.0 Language Engine Interface Module


Contents

ABSTRACT
SunIM Library Overview
IF Method
IML Method
MM Method
Programming Interface Overview
C/C++ programming interface
MT-Safe
Locale Independent
Language Engine Module
Defining if_GetIfInfo() in your engine module
Destination of Language Engine Module
Object Downloading
Defining ObjectDescriptor
IF Method
Opening and Closing an IF
Setting and Querying IF values
Opening and Closing User Desktop
Creating and Destroying a Session Context
Setting and Querying Session values
Handling Focus
Resetting a Session
Handling Input Events
Managing Desktop and Session
IML Method
IMText and IMFeedback
Drawing Pre-edit
Drawing Status
Start and Stop Forwarding Event
Handling Lookup Choice
Committing Pre-edit
Returning Key Event
Reset-return Pre-edit
Handling Aux
Object Downloading
Linking IML Instance at Tail of List
Execute the commands
MM Methods
Allocate Area
Free Area
Example Code
Template for Language Engine
Sample for Japanese Language Engine
Appendix A. Method Summary
IF Method Summary
IML Method Summary
MM Method Summary
Appendix B. IF Attribute and SC Attribute
IF Attribute
SC Attribute
UI Attribute

ABSTRACT

This document describes how to develop Language Engine Modules to be connected to htt_server by using SunIM library. When you have written Language Engine Module once with SunIM library, the module will connect any client that supports Internet-Intranet Input Method(IIIM) protocol through htt_server. It would not be possible to create a program that can talk with IM client directly using IIIM protocol, however, SunIM 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.

SunIM Library Overview

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

SunIM library is independent from both htt_server and Language Engines, and constructed by three objects, Input Method Logic(IML), Interface(IF), Memory Manager(MM).

IF Method

Language Engine Module needs to define a set of functions, called IF Method, in it. These IF methods will be loaded by htt_server dynamically and will be invoked by htt_server when htt_server 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 htt_server. This IF method is resposible 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.

IML Method

IML Methods is a set of functions and is provided for Language Engines in order to control input method through htt_server. 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 feeback for each character.

MM Method

MM Methods is a set of functions for memory allocation and deallocation. These methods are contained in IML Methods.

Programming Interface

C/C++ programming interface

SunIM library supports both C and C++ programming interfaces.

MT-Safe

IF methods defined in Language Engine Module should be MT-Safe. htt_server 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.

Locale Independent

SunIM 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 example, setlocale().

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 htt_server.

Defining if_GetIfInfo() in your engine module

main() is not needed in Language Engine Module. The module should define IF Method if_methods_t instead of main(), which will be called by htt_server 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:

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 SunIM library to retrieve the information of the Language Engines, such as the name of engine, the supported locales and objects and methodtable.

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 selction Object Downloading 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 NT platform.

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;
            }
    }
}

When you use C++ for the Language Engine Module, the method should be define as ``export "C"'' for SunIM library
Example
extern "C" {
   void
   if_GetIfInfo(
       IMArgList args,
       int num_args
   )
   {
	...
   }
}

For Windows NT 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

For more detail, especially how to build on Windows NT platform, please refer the example codes in the following directries. sampleja2 is for example codes for C++ programming interface.
	src/server/programs/language_engines/template
	src/server/programs/language_engines/sampleja
	src/server/programs/language_engines/sampleja2

Destination of Language Engine Module

The destination of Language Engine modules depends on imlplementation. The default locations for Solaris platform and Windows NT platform are defined as the following. The location can be specified -ifpath_name htt_server option, like
	htt_server -ifpath_name /tmp/iiimf_test
for Solaris platform. or
	htt_server -ifpath_name c:\\temp\\iiimf_test
for Windows NT platform.

Solaris Platform
/usr/lib64/im is now base directory for IIIMF. The Language Engine Module should be located under
	/usr/lib64/im/leif
for Solaris platform.

IIIMF SDK 1.2 provides two sample Language Engine Modules under the directory, sampleja.so and tempalte.so.

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
for Windows NT platform. sampleja.dll is provided for example.

Object Downloading

Language engine module can send objects to IM client which works as Aux programs on the client side.

Defining ObjectDescriptor

Language engine module should define IMObjectDescriptorStruct if the language engine needs to use Aux object. The following fields are required for the definition.

char *leid
This field specifies the identifier for the language engine module, which should be same with the id of IMLEName.
IMObjectType type
Specifies a type of the object.

IM_DOWNLOADINGOBJECT_JARGUI_TYPE
Declares the object is GUI object and Java jar file format.
IM_DOWNLOADINGOBJECT_JARLWE_TYPE
Declares the object is LWE object and Java jar file format.
Note:This feature isn't supported in this version.
IM_DOWNLOADINGOBJECT_CCDEF_TYPE
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
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
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.

char **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() .

unsigned int count_names
Specifies the number of class_names. For the example above, this field should be 2.

UTFCHAR *name
Specifies HRN(Human Readable Name) of the object
int name_length
Specifies the length of name

char *domain
Specifies reversed domain of vender who developed the object.
char *path
Speficies the location of the object.
char *scope
Speficies if 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, the object can be used by the others, this field is generic.
Note:generic keyword will not work properly in this version. Use leif only.

char *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.
char *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.

IF Method

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

Opening and Closing an IF

When htt_server 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. These IF methods are only for Language Engine initialization, should not depends 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 htt_server does not need the Language Engine Interface (IF) opened by if_OpenIF() IF method any more, which indicates there is no user to use the Language Engine, if_CloseIF() IF method will be called.

if_OpenIF()
Bool (*if_OpenIF)(If)
	iml_if_t *If;

if_CloseIF()
Bool (*if_CloseIF)(If)
	iml_if_t *If;

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();
}

Setting and Querying IF values

These IF methods are provided to query and set, modify IF attributes. However, there is no usable IF attributes in this release.
if_GetIFValues()
Bool (*if_GetIFValues)(If, args, n_args)
        iml_if_t   *If;
	IMArgList  args;
	int        n_args;

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

Opening and Closing User Desktop

As described above, Language Engine should support multi-user connection. A new concept, called a Desktop, 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.

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 deinfed */
}   iml_desktop_t;

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. These two IF methods are provided for the purpose.

When the user start 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.

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.

When Language Engine may want to prepare allocated data per desktop, Language Engine can allocate and store its pointer to desktop->specific_data.

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

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

if_CloseDesktop()
Bool (*if_CloseDesktop)(desktop)
	iml_desktop_t *desktop;

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;
}

Creating and Destroying a Session Context

Session
After if_CreateSC() is invoked, the communications between htt_server 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, htt_server 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 htt_server's point of view.

Here, a communication between htt_server 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_tand the content is exchanged between htt_server and the Language Engines.

An input context is created on the client, if_CreateSC() is invoked. It's not required to create iml_session_t structure here, iml_session_t is created by SunIM 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. If Language Engine wants to assigne specific data to the session, s->specific_data can be used.

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

if_DestroySC()
Bool (*if_DestroySC)(s)
	iml_session_t *s;

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

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

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().

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);
}

Setting and Querying Session values

These IF methods are provided to query and set, modify SC attributes.

if_GetSCValues() IF method is used to set and modify SC attributes. if_SetSCValues() IF method is used to receive values of the 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.

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

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

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;
}

Handling Focus

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

if_SetSCFocus()
void (*if_SetSCFocus)(s)
	iml_session_t *s;

if_UnsetSCFocus()
void (*if_UnsetSCFocus)(s)
	iml_session_t *s;

Resetting a Session

If a client needs to reset the input context, this IF method is invoked with the associated session. This IF method should return the current pre-edit string if needed.

if_ResetSC()
IMText *(*if_ResetSC)(s)
	iml_session_t *s;

Handling Input Events

When any event occurs on the client IC, this IF method is invoked with IMInputEvent, which contains any event of key event, string event, text event and aux event. Language Engine can find event type by checking ev->type.
if_SendEvent()
void (*if_SendEvent)(s, ev)
	iml_session_t  *s;
	IMInputEvent *ev;

Receiving Key Event
Every Key Event is passed in if_SendEvent() as IMKeyListEvent, which has a list of IMKeyEventStruct structure. The Language Engine can know which key was pressed on the client to check IMKeyEventStruct structure.
int keyCode;		/* keycode, defined in SunIM.h */
int keyChar;		/* keychar is defined */
int modifier;		/* modifier */

Example
if(ev->type == IM_EventKeyList){
	IMKeyListEvent *keylistevent=(IMKeyListEvent*)ev;
	IMKeyEventStruct *key=(IMKeyEventStruct*)keylistevent->keylist;
				/* a key event is used in this release */
}

For example, when 'a' is pressed on the client, the following values are 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 are passed. IM_CTRL_MASK is defined in SunIM.h as well.
keyCode  : IM_VK_W;
keyChar  : 'w';
modifier : IM_CTRL_MASK

Returning a Key Event
When a key event is not processed, which means the key event is not needed for the conversion, the Language Engine wants to back the event 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 needs to return the key event of an enter key to the client.

For this purpose, iml_make_keypress_inst() IML method is provided. The method returns a key event to the client. Please refer iml_make_keypress_inst() section of IML method .

Receiving Aux Event
Aux event are also passed in if_SendEvent() as IMAuxEvent. IMAuxDrawCallbackStruct can be retrieved from aux field of IMAuxEvent
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.

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.
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;
    }

IML Method

IML Method is a set of functions predefined in SunIM 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 preedit, Language Engine should create iml_inst instance by iml_make_preedit_start_inst() then should call iml_execute() first. 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 SunIM interface. Strings on pre-edit, status and lookup choice can be drawn with specified Color.

IMText and IMFeedback

IMText structure has the following fields. Each IML methods require IMText representation in the argument.

IMEncoding encoding
Always should be 0, which means UTF16_CODESET.
unsigned int char_length
Specifies the length of the text.
UTFCHAR *text.utf_chars
Specifies the string which is UTF16.
IMFeedbackList *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 coresponds each character. A IMFeedbackList feedback[3] represents a feedback of the character text.utf_chars[3].
unsigned int count_annotations
Specifies the number of annotation
Note:annotation isn't supported in this version.
IMAnnotation *annotation
Specifies the annotation.
Note:annotation isn't supported in this version.

IMFeedbackList and IMFeedback can represend Color feedback for each character. IMFeedbackList structure is here,

unsigned int count_feedbacks
Specify the number of IMFeedback
IMFeedback *feedbacks
Specify the list of IMFeedback which has a pair of IMFeedbackType and its value.

IMFeedback structure is the following, which has a pair of feeback type and value.

IMFeedbackType type
Specify the type of IMFeedback,
IM_DECORATION_FEEDBACK
Specify a decoration of a character into value field. The value should be any of IMNormal, IMReverse, IMUnderline. This type is required, and the other types are optional.
IM_FOREGROUND_RGB_FEEDBACK
Specify 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
Specify 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
Specify 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.
int value
Specify a value corresponding with IMFeedbackType

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);
    }
}

More examples are shown in sampleja

        src/server/programs/language_engines/sampleja

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().

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

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)(s, preedit)
	iml_session_t *s;
	IMText       *preedit;

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)(s, preedit, chg_first, chg_length, caret)
        iml_session_t *s;		/* session */
	IMText        *preedit;		/* pre-edit string to be replaced */
	int           chg_first;	/* start point to be changed */
	int           chg_length;	/* length to be changed */
	int           caret;		/* caret position */

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)(s)
	iml_session_t *s;	/* session */

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)(s, caret)
	iml_session_t *s;	/* session */
	int caret;		/* caret position */

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)(s)
	iml_session_t *s;	/* session */

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().

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

iml_inst *(*iml_make_status_start_inst)(s)
	iml_session_t *s;	/* session */

iml_make_status_draw_inst()
This method creates an iml_inst instance to draw status string.
iml_inst *(*iml_make_status_draw_inst)(s, status)
	iml_session_t *s;	/* session */
	IMText        *status;	/* status string */

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)(s)
	iml_session_t *s;	/* session */

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.

iml_make_start_conversion_inst()
iml_inst *(*iml_make_start_conversion_inst)(s)
	iml_session_t *s;

iml_make_end_conversion_inst()
iml_inst *(*iml_make_end_conversion_inst)(s)
	iml_session_t *s;

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.

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)(s, start)
	iml_session_t               *s;		/* session */
	IMLookupStartCallbackStruct *start;	/* start data */

Here are the fields of IMLookupStartCallbackStruct,

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

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);

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)(s, draw)
	iml_session_t              *s;	  	/* session */
	IMLookupDrawCallbackStruct *draw;	/* draw data */

Here are the fields of IMLookupDrawCallbackStruct,

int index_of_first_candidate
This field specifies index of the first candidate.
int index_of_last_candidate
This field specifies index of the last candidate.
int n_choices
This field specifies the number of choices of the lookup choice.
IMText *title
This field specifies title of the lookup choice as IMText structure.
IMChoiceObject *choices
This field specifies each candidate (value) and its label(label) as IMChoiceObject structure.
int max_len
This field specifies the maximum length of the candidates.
int index_of_current_candidate
This field specifies the index of current candidate, which is displayed as reversed on the 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);

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)(s)
	iml_session_t *s;

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.

iml_make_commit_inst()
iml_inst *(*iml_make_commit_inst)(s, text)
	iml_session_t *s; /* session */
	IMText *text;     /* string to be committed */

Returning Key Event

This method creates 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.

iml_make_keypress_inst()
iml_inst *(*iml_make_keypress_inst)(s, IMKeyEventStruct *key)
	iml_session_t     *s;   /* session */
	IMKeyEventStruct  *key; /* key event to be returned */

Handling Aux

Language Engine can send own AUX modules to the client through htt_server. <-- by iml_make_objectdownloading_inst(). --> After sending AUX modules, Language Engine can controls the AUX by these methods. Each methods take IMAuxStartCallbackStruct,IMAuxDrawCallbackStruct and IMAuxDoneCallbackStruct as argument.

char *aux_name
Specifies class name for AUX. For Java AUX, this field should be class name which are defined in IMObjectDescriptorStruct.
int count_integer_values
specifies number of integer for count_integer_values. only IMAuxDrawCallbackStruct.
int *count_integer_values
specifies integer array. only IMAuxDrawCallbackStruct.
int count_string_values
specifies number of string for string_values. only IMAuxDrawCallbackStruct.
IMText *string_values
specifies string array as IMText format. only IMAuxDrawCallbackStruct.

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)(s, start)
	iml_session_t            *s;      /* session */
	IMAuxStartCallbackStruct *start;

iml_make_aux_draw_inst()
This method creates an iml_inst instance to control AUX module. Language Engine needs to specify AUX id and integer and string array in IMAuxDrawCallbackStruct structure.
iml_inst *(*iml_make_aux_draw_inst)(s, draw)
	iml_session_t           *s;      /* session */
	IMAuxDrawCallbackStruct *draw;

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)(s, done)
	iml_session_t           *s; /* session */
	IMAuxDoneCallbackStruct *done;

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

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.

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

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);

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.

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

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.

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.

iml_new()
void *iml_new(s, size)
	iml_session_t *s;
	int size;

iml_new2()
void *iml_new2(s, size)
	iml_session_t *s;
	int size;

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);

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 SunIM 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(s)
	iml_session_t *s;

iml_delete2()
void iml_delete2(s)
	iml_session_t *s;

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)
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 SunIM library. It takes char* and _IF_VERSION_ is predefined in SunIM 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, SunIM locks the thread while each IF method is processing and unlocks after IF method is returned.
G = used in if_GetIFValues()
S = used in if_SetIFValues()
G/S = used in both if_GetIFValues()/if_SetIFValues()

SC Attribute

SC Attributes
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.
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.


Sun Microsystems, Inc. All Rights Reserved.