Back to index

im-sdk  12.3.91
UDEngine.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #ifdef WIN32
00043 #include <windows.h>
00044 #endif
00045 
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 #include <sys/types.h>
00050 
00051 #include "SunIM.h"
00052 #include "SunIMMMan.h"
00053 #include "SunIMProt.h"
00054 #include "SunIMMthd.h"
00055 #include "SunIMPriv.h"
00056 #include "SunIMCore.h"
00057 #include "SunIMPub.h"
00058 #include "UDEngine.h"
00059 
00060 Bool if_udengine_OpenIF(iml_if_t *);
00061 Bool if_udengine_CloseIF(iml_if_t *);
00062 Bool if_udengine_GetIFValue(iml_if_t *, IMArgList, int);
00063 Bool if_udengine_SetIFValue(iml_if_t *, IMArgList, int);
00064 Bool if_udengine_OpenDesktop(iml_desktop_t *, IMArgList, int);
00065 Bool if_udengine_CloseDesktop(iml_desktop_t *);
00066 Bool if_udengine_CreateSC(iml_session_t *, IMArgList, int);
00067 Bool if_udengine_DestroySC(iml_session_t *);
00068 Bool if_udengine_GetSCValue(iml_session_t *, IMArgList, int);
00069 Bool if_udengine_SetSCValue(iml_session_t *, IMArgList, int);
00070 IMText *if_udengine_ResetSC(iml_session_t *);
00071 void if_udengine_SetSCFocus(iml_session_t *);
00072 void if_udengine_UnsetSCFocus(iml_session_t *);
00073 void if_udengine_SendEvent(iml_session_t *, IMInputEvent * ev);
00074 
00075 /* IF Method */
00076 if_methods_t udengine_methods2 = {
00077     if_udengine_OpenIF,
00078     if_udengine_CloseIF,
00079     if_udengine_GetIFValue,
00080     if_udengine_SetIFValue,
00081     if_udengine_OpenDesktop,
00082     if_udengine_CloseDesktop,
00083     if_udengine_CreateSC,
00084     if_udengine_DestroySC,
00085     if_udengine_GetSCValue,
00086     if_udengine_SetSCValue,
00087     if_udengine_ResetSC,
00088     if_udengine_SetSCFocus,
00089     if_udengine_UnsetSCFocus,
00090     if_udengine_SendEvent
00091 };
00092 
00093 UTFCHAR lename_string[] = {0x7b80, 0x4f53, 0x4e2d, 0x872d, 0x65b0, 0x62fc, 0x97f3, 0x8f93, 0x8815, 0x6cd5, 0x0}; 
00094 UTFCHAR zhhrn_string[] = {0x7b80, 0x4f53, 0x4e2d, 0x872d, 0x0};
00095 
00096 static IMLEName lename = {
00097     "udengine", lename_string      /* LE id, HRN */
00098 };
00099 
00100 static IMLocale locales[] = {
00101     {"zh", zhhrn_string},   /* locale id, HRN */
00102     NULL
00103 };
00104 
00105 IMObjectDescriptorStruct *objects = NULL;
00106 
00107 int max_codetable_number = 0;
00108 
00109 void init_objects();
00110 void free_objects();
00111 
00112 #ifdef WIN32
00113 #define EXPORT extern __declspec(dllexport)
00114 
00115 EXPORT
00116 
00117 #endif
00118 
00119 void 
00120 if_GetIfInfo(
00121     IMArgList args,
00122     int num_args
00123 )
00124 {
00125     int i;
00126 
00127     init_objects(); 
00128     for (i = 0; i < num_args; i++, args++) {
00129         switch (args->id) {
00130             case IF_VERSION:
00131                 args->value = (IMArgVal) "1.2";
00132                 break;
00133             case IF_METHOD_TABLE:
00134                 args->value = (IMArgVal) & udengine_methods2;
00135                 break;
00136             case IF_LE_NAME:
00137                 args->value = (IMArgVal) & lename;
00138                 break;
00139             case IF_SUPPORTED_LOCALES:
00140                 args->value = (IMArgVal) & locales;
00141                 break;
00142             case IF_SUPPORTED_OBJECTS:
00143                 args->value = (IMArgVal) NULL; 
00144                 break;
00145             case IF_NEED_THREAD_LOCK:
00146                 args->value = (IMArgVal) False;
00147                 break;
00148             default:
00149                 break;
00150             }
00151     }
00152 }
00153 
00154 char *class_names[] = {"com.sun.iiim.sample.udengine.NewPYPanel"};
00155 
00156 void aux_start(iml_session_t *);
00157 void aux_draw(iml_session_t *, int, int, int *, int, UTFCHAR **);
00158 void aux_done(iml_session_t *);
00159 void aux_set(iml_session_t *);
00160 void receive_aux(iml_session_t *, IMAuxDrawCallbackStruct *);
00161 Bool receive_keylist(iml_session_t *, IMKeyListEvent *);
00162 
00163 void my_conversion_on(iml_session_t *);
00164 void my_conversion_off(iml_session_t *);
00165 
00166 void status_draw(iml_session_t *);
00167 void preedit_draw(iml_session_t *);
00168 void lookup_draw(iml_session_t *, UTFCHAR **, int);
00169 void commit(iml_session_t *);
00170 void eval_packet(iml_session_t *, im_data *);
00171 
00172 IMText *make_preedit_imtext(iml_session_t *);
00173 void preedit_buf_print(iml_session_t *);
00174 IMText *make_imtext(iml_session_t *, UTFCHAR *);
00175 
00176 int UTFCHARLen(UTFCHAR *);
00177 int UTFCHARCpy(UTFCHAR *, UTFCHAR *);
00178 
00179 IMFeedbackList *create_feedback(iml_session_t * s, int size);
00180 IMFeedbackList *create_feedback2(iml_session_t * s, int size);
00181 void set_feedback(IMFeedbackList *, int);
00182 int get_feedback(IMFeedbackList *);
00183 
00184 /* data per desktop */
00185 typedef struct {
00186     iml_session_t *auxproxy_session;
00187     int aux_started;
00188     int engine_id;
00189     int punc;
00190     int skb;
00191     int gbk_support;
00192 }   MyDataPerDesktop;
00193 
00194 /* data per session */
00195 typedef struct {
00196     int status_start;
00197     int preedit_start;
00198     int luc_start;
00199     int conv_on;
00200     
00201     IMText **luc_candidates;
00202     IMText **luc_labels;
00203     
00204     UTFCHAR *conversion_string;    /* reversed */
00205     UTFCHAR *preedit_string;       /* underlined */
00206     
00207     int luc_top;
00208     int luc_nchoices;
00209     int luc_current_candidate;     /* index of current candidate */
00210     int luc_type;           /* Clinet or IM Master */
00211     int max_candidates;
00212     
00213     UTFCHAR *preedit_buf;   /* preedit */
00214     IMFeedbackList *preedit_feedback;     /* feedback for preedit */
00215     int caret_pos;
00216     
00217     IMFeedbackList *luc_fbs_reverse;
00218     IMFeedbackList *luc_fbs_normal;
00219 
00220     UTFCHAR *commit_buf; /* commit */
00221 
00222     UTFCHAR *status_buf; /* status */
00223 
00224     int session_id;
00225     char *username;
00226 
00227 }   MyDataPerSession;
00228 
00229 #define MAX_SESSION 512
00230 #define MAX_PHRASE_LEN 20
00231 static int s_id[MAX_SESSION];
00232 
00233 /*
00234 #define       DEBUG
00235 */
00236 
00237 #define       DEBUG1
00238 
00239 
00240 void debugprint(iml_session_t *s) {
00241     printf("  s=[%x]\n", s);
00242     printf("  If=[%x]\n", s->desktop->If);
00243     printf("  desktop=[%x]\n", s->desktop);
00244     printf("  locale=[%s]\n", s->desktop->If->locale);
00245     printf("  if_name=[%s]\n", s->desktop->If->if_name);
00246     printf("  USER:%s\n", s->desktop->user_name);
00247     printf("  HOST:%s\n", s->desktop->host_name);
00248     printf("    DISPLAY:%s\n", s->desktop->display_id);
00249 }
00250 
00251 Bool
00252 if_udengine_OpenIF(
00253     iml_if_t * If
00254 )
00255 {
00256     max_codetable_number = IM_open(If->ifpath_name);
00257     if(max_codetable_number) return True;
00258     else return False;
00259 }
00260 
00261 Bool
00262 if_udengine_CloseIF(
00263     iml_if_t * If
00264 )
00265 {
00266 #ifdef  notdef
00267     free_objects();
00268 #endif
00269 
00270     IM_close(max_codetable_number);
00271 
00272     return True;
00273 }
00274 
00275 UTFCHAR aux_name_panel[] = {0x65b0, 0x62fc, 0x97f3, 0x8f85, 0x52a9, 0x7a97, 0x53e3, 0};
00276 UTFCHAR aux_name_aux[] = {0x65b0, 0x62fc, 0x97f3, 0x8f85, 0x52a9, 0x7a97, 0x53e3, 0};
00277 
00278 void
00279 free_objects()
00280 {
00281     IMObjectDescriptorStruct *l = objects;
00282 
00283     while (l->leid) {
00284         free(l->name);
00285         l++;
00286     };
00287     free(objects);
00288     objects = NULL;
00289 }
00290 
00291 void
00292 init_objects()
00293 {
00294     IMObjectDescriptorStruct *l;
00295     objects = (IMObjectDescriptorStruct *) calloc(2, sizeof(IMObjectDescriptorStruct));
00296     l = objects;
00297 
00298     l->leid = "udengine";       /* engine id */
00299     l->type = IM_DOWNLOADINGOBJECT_JARGUI_TYPE; /* object type */
00300     l->name = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * (UTFCHARLen(aux_name_panel) + 1));
00301     UTFCHARCpy(l->name, aux_name_panel);
00302     l->name_length = UTFCHARLen(aux_name_panel);
00303     l->domain = "com.sun.udengine";
00304     l->scope = "udengine";      
00305     l->path = "/usr/lib/im/locale/zh_CN/udengine/udengine_obj.jar";  /* path */
00306     l->signature = "";
00307     l->basepath = NULL;         /* only for CCDEF */
00308     l->encoding = NULL;         /* only for CCDEF */
00309     l->class_names = class_names;
00310     l->count_names = 1;
00311 }
00312 
00313 Bool
00314 if_udengine_GetIFValue(
00315     iml_if_t * If,
00316     IMArgList args,
00317     int num_args
00318 )
00319 {
00320 
00321 #ifdef DEBUG
00322     printf("if_udengine_GetIFValue()\n");
00323     printf("  If=[%x]\n", If);
00324     printf("  locale=[%s]\n", If->locale);
00325     printf("  if_name=[%s]\n", If->if_name);
00326 #endif
00327 
00328     return True;
00329 }
00330 
00331 Bool
00332 if_udengine_SetIFValue(
00333     iml_if_t * If,
00334     IMArgList args,
00335     int num_args
00336 )
00337 {
00338     int i;
00339 #ifdef DEBUG
00340     printf("if_udengine_SetIFValue()\n");
00341     printf("  If=[%x]\n", If);
00342     printf("  locale=[%s]\n", If->locale);
00343     printf("  if_name=[%s]\n", If->if_name);
00344 #endif
00345     for (i = 0; i < num_args; i++, args++) {
00346         switch (args->id) {
00347         }
00348     }
00349     return True;
00350 }
00351 
00352 Bool
00353 if_udengine_OpenDesktop(
00354     iml_desktop_t * desktop,
00355     IMArgList args,
00356     int num_args
00357 )
00358 {
00359     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) calloc(1, sizeof(MyDataPerDesktop));
00360     int i;
00361 
00362 #ifdef DEBUG
00363     printf("if_udengine_OpenDesktop()\n");
00364     printf("  If=[%x]\n", desktop->If);
00365     printf("  desktop=[%x]\n", desktop);
00366     printf("  locale=[%s]\n", desktop->If->locale);
00367     printf("  if_name=[%s]\n", desktop->If->if_name);
00368     printf("  USER:%s\n", desktop->user_name);
00369     printf("  HOST:%s\n", desktop->host_name);
00370     printf("  DISPLAY:%s\n", desktop->display_id);
00371 #endif
00372 
00373     desktop_data->aux_started = False;
00374     desktop_data->engine_id = 0;
00375     desktop_data->punc = 0;
00376     desktop_data->skb = 0;
00377     desktop_data->gbk_support = 0;
00378     desktop_data->auxproxy_session = NULL;
00379     desktop->specific_data = (void *) desktop_data;
00380     return True;
00381 }
00382 
00383 Bool
00384 if_udengine_CloseDesktop(
00385     iml_desktop_t * desktop
00386 )
00387 {
00388     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) desktop->specific_data;
00389 
00390 #ifdef DEBUG
00391     printf("if_udengine_CloseDesktop()\n");
00392     printf("  If=[%x]\n", desktop->If);
00393     printf("  desktop=[%x]\n", desktop);
00394     printf("  locale=[%s]\n", desktop->If->locale);
00395     printf("  if_name=[%s]\n", desktop->If->if_name);
00396     printf("  USER:%s\n", desktop->user_name);
00397     printf("  HOST:%s\n", desktop->host_name);
00398     printf("  DISPLAY:%s\n", desktop->display_id);
00399 #endif
00400 
00401     free(desktop_data);
00402     return True;
00403 }
00404 
00405 #define       BUFSIZE       256
00406 #define       MAXCANDIDATES 40
00407 
00408 Bool
00409 if_udengine_CreateSC(
00410     iml_session_t *s,
00411     IMArgList args,
00412     int num_args
00413 )
00414 {
00415     iml_desktop_t *desktop = s->desktop;
00416     static int first_create = 1;
00417     int i;
00418 
00419     MyDataPerSession *p = (MyDataPerSession *) calloc(1, sizeof(MyDataPerSession));
00420     p->status_start = False;
00421     p->luc_start = False;
00422     p->preedit_start = False;
00423     p->preedit_buf = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * BUFSIZE);
00424     p->status_buf = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * BUFSIZE);
00425     p->commit_buf = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * BUFSIZE);
00426     
00427     p->conversion_string = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * BUFSIZE);
00428     p->preedit_string = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * BUFSIZE);
00429     p->luc_candidates = NULL;
00430     p->luc_labels = NULL;
00431     p->luc_nchoices = 36;
00432     p->caret_pos = -1;
00433     p->max_candidates = MAXCANDIDATES - 1;
00434     p->luc_current_candidate = 0;
00435     p->luc_fbs_reverse = create_feedback(0, BUFSIZE);
00436     p->luc_fbs_normal = create_feedback(0, BUFSIZE);
00437     p->preedit_feedback = create_feedback(0, BUFSIZE);
00438     for(i=0;i<BUFSIZE;i++) {
00439        set_feedback(&p->luc_fbs_reverse[i], IMUnderline);
00440        set_feedback(&p->luc_fbs_reverse[i], IMReverse);
00441        set_feedback(&p->luc_fbs_reverse[i], IMNormal);
00442     }
00443 
00444     if(first_create) {
00445         for (i = 0; i < MAX_SESSION; i ++) s_id[i] = 0;
00446         first_create = 0;
00447     }
00448 
00449     for (i = 0; i < MAX_SESSION; i ++)
00450         if (s_id[i] == 0) { p->session_id = i ; break; }
00451 
00452     if ( i == MAX_SESSION ) {
00453          perror(" Can't open so many subwindows");
00454          return False;
00455     }
00456     s_id[i] = 1;
00457     p->username = (char *)strdup(desktop->user_name);
00458     
00459 #ifdef DEBUG
00460     printf("if_udengine_CreateSC()\n");
00461     printf("    If=[%x]\n", desktop->If);
00462     printf("    desktop=[%x]\n", desktop);
00463     printf("    locale=[%s]\n", desktop->If->locale);
00464     printf("    if_name=[%s]\n", desktop->If->if_name);
00465     printf("    USER:%s\n", desktop->user_name);
00466     printf("    HOST:%s\n", desktop->host_name);
00467     printf("    DISPLAY:%s\n", desktop->display_id);
00468 
00469     for (i = 0; i < num_args; i++, args++) {
00470         switch (args->id) {
00471             case UI_USER_NAME:
00472                 if (args->value) {
00473                     printf("    UI_USER_NAME=%s\n", args->value);
00474                 }
00475                 break;
00476             case UI_HOST_NAME:
00477                 if (args->value) {
00478                     printf("    UI_HOST_NAME=%s\n", args->value);
00479                 }
00480                 break;
00481             case UI_DISPLAY_ID:
00482                 if (args->value) {
00483                     printf("    UI_DISPLAY_ID=%s\n", args->value);
00484                 }
00485                 break;
00486             case UI_PROTOCOL_TYPE:
00487                 if (args->value) {
00488                     printf("    UI_PROTOCOL_TYPE=%s\n", args->value);
00489                 }
00490                 break;
00491             case UI_XSERVER_VENDOR:
00492                 if (args->value) {
00493                     printf("    UI_XSERVER_VENDOR=%s\n", args->value);
00494                 }
00495                 break;
00496             case UI_CLIENT_TYPE:
00497                 if (args->value) {
00498                     printf("    UI_CLIENT_TYPE=%s\n", args->value);
00499                 }
00500                 break;
00501             case UI_OS_NAME:
00502                 if (args->value) {
00503                     printf("    UI_OS_NAME=%s\n", args->value);
00504                 }
00505                 break;
00506             case UI_OS_ARCH:
00507                 if (args->value) {
00508                     printf("    UI_OS_ARCH=%s\n", args->value);
00509                 }
00510                 break;
00511             case UI_OS_VERSION:
00512                 if (args->value) {
00513                     printf("    UI_OS_VERSION=%s\n", args->value);
00514                 }
00515                 break;
00516             }
00517     }
00518 #endif
00519     s->specific_data = (void*) p;
00520     
00521     return True;
00522 }
00523 
00524 Bool
00525 if_udengine_DestroySC(
00526     iml_session_t * s
00527 )
00528 {
00529     MyDataPerSession *p = (MyDataPerSession *) s->specific_data;
00530     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
00531 
00532     IM_destroySession(p->session_id);
00533     s_id[p->session_id] = 0;
00534 
00535     if ( s == desktop_data->auxproxy_session) {
00536        aux_done(s);
00537        desktop_data->auxproxy_session = NULL;
00538        desktop_data->punc = 0;
00539        desktop_data->skb = 0;
00540        desktop_data->gbk_support = 0;
00541     }
00542 
00543     if (p->preedit_buf)
00544         free((char *) p->preedit_buf);
00545     if (p->status_buf)
00546         free((char *) p->status_buf);
00547     if (p->commit_buf)
00548         free((char *) p->commit_buf);
00549     if (p->conversion_string)
00550         free((char *) p->conversion_string);
00551     if (p->preedit_string)
00552         free((char *) p->preedit_string);
00553     if (p->preedit_feedback)
00554         free((char *) p->preedit_feedback);
00555     if (p->luc_fbs_reverse)
00556         free((char *) p->luc_fbs_reverse);
00557     if (p->luc_fbs_normal)
00558         free((char *) p->luc_fbs_normal);
00559     free((char *) p);
00560 #ifdef DEBUG
00561     printf("if_udengine_DestroySC(s=%x)\n", s);
00562     debugprint(s);
00563 #endif
00564     return True;
00565 }
00566 
00567 Bool
00568 if_udengine_GetSCValue(
00569     iml_session_t * s,
00570     IMArgList args,
00571     int num_args
00572 )
00573 {
00574     int i;
00575     IMArg *p = args;
00576     
00577     static int charsubset[] = {
00578         67,                 /* LATIN */
00579         47,                 /* HIRAGANA */
00580         48,                 /* KATAKANA */
00581         71,                 /* KANJI */
00582         0
00583     };
00584     
00585 #ifdef DEBUG
00586     printf("if_udengine_GetSCValue(s=%x)\n", s);
00587     debugprint(s);
00588 #endif
00589     for (i = 0; i < num_args; i++, p++) {
00590         switch (p->id) {
00591             case SC_SUPPORTED_CHARACTER_SUBSETS:
00592                 /* specify CHARACTER_SUBSETS */
00593                 p->value = (IMArgVal) charsubset;
00594                 break;
00595             default:
00596                 break;
00597             }
00598     }
00599     return True;
00600 }
00601 
00602 UTFCHAR off_string[] = {0x897f, 0x6587, 0};
00603 UTFCHAR title_string[] = {0x67e5, 0x627e, 0x8868, 0};
00604 
00605 void
00606 my_conversion_on(
00607     iml_session_t * s
00608 )
00609 {
00610     iml_inst *lp;
00611     iml_inst *rrv = NULL;
00612     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00613     session_data->conv_on = True;
00614     
00615     lp = s->If->m->iml_make_start_conversion_inst(s);
00616     s->If->m->iml_link_inst_tail(&rrv, lp);
00617     
00618     if (session_data->preedit_start == False) {
00619         lp = s->If->m->iml_make_preedit_start_inst(s);
00620         s->If->m->iml_link_inst_tail(&rrv, lp);
00621         session_data->preedit_start = True;
00622     }
00623     lp = s->If->m->iml_execute(s, &rrv);
00624     status_draw(s);
00625 }
00626 
00627 void
00628 my_conversion_off(
00629     iml_session_t * s
00630 )
00631 {
00632     iml_inst *lp;
00633     iml_inst *rrv = NULL;
00634     
00635     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00636     session_data->conv_on = False;
00637 
00638     IM_resetSession(session_data->session_id);
00639     
00640     /* if preedit exists, commit the string */
00641     commit(s);
00642     
00643     if (session_data->luc_start == True) {
00644         lp = s->If->m->iml_make_lookup_done_inst(s);
00645         s->If->m->iml_link_inst_tail(&rrv, lp);
00646         session_data->luc_start = False;
00647     }
00648     if (session_data->preedit_start == True) {
00649         lp = s->If->m->iml_make_preedit_erase_inst(s);
00650         s->If->m->iml_link_inst_tail(&rrv, lp);
00651         lp = s->If->m->iml_make_preedit_done_inst(s);
00652         s->If->m->iml_link_inst_tail(&rrv, lp);
00653         session_data->preedit_start = False;
00654         session_data->caret_pos = -1;
00655     }
00656     lp = s->If->m->iml_make_end_conversion_inst(s);
00657     s->If->m->iml_link_inst_tail(&rrv, lp);
00658     
00659     s->If->m->iml_execute(s, &rrv);
00660     
00661     status_draw(s);
00662 }
00663 
00664 Bool
00665 if_udengine_SetSCValue(
00666     iml_session_t * s,
00667     IMArgList args,
00668     int num_args
00669 )
00670 {
00671     int i;
00672     IMArg *p = args;
00673 
00674 #ifdef DEBUG
00675     printf("if_udengine_SetSCValue()\n");
00676     debugprint(s);
00677 #endif
00678 
00679     for (i = 0; i < num_args; i++, p++) {
00680         switch (p->id) {
00681             case SC_TRIGGER_ON_NOTIFY:
00682                 my_conversion_on(s);
00683                 break;
00684                 
00685             case SC_TRIGGER_OFF_NOTIFY:
00686                 my_conversion_off(s);
00687                 break;
00688                 
00689             case SC_REALIZE:
00690               {
00691                   MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
00692                   MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00693                   IM_createSession(session_data->session_id);
00694                     if(desktop_data->auxproxy_session == NULL) 
00695                       desktop_data->auxproxy_session = s;
00696                     /* aux_start(s); */
00697                   
00698               }
00699                 break;
00700 
00701            case SC_LOOKUP_LABELTYPE:
00702                 break;
00703 
00704             default:
00705                 break;
00706             }
00707     }
00708     return True;
00709 }
00710 
00711 IMText *
00712 if_udengine_ResetSC(
00713     iml_session_t * s
00714 )
00715 {
00716     int i;
00717     iml_inst *lp;
00718     IMText *p = make_preedit_imtext(s);
00719     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00720     
00721 #ifdef DEBUG
00722     printf("if_udengine_ResetSC(s=%x)\n", s);
00723     debugprint(s);
00724 #endif
00725     
00726     /*
00727     * when you return IMText for commit string, you need to call
00728     * iml_make_preedit_erase_inst() here.
00729     */
00730     lp = s->If->m->iml_make_preedit_erase_inst(s);
00731     s->If->m->iml_execute(s, &lp);
00732     
00733     /*
00734     * reset buffer
00735     */
00736     for(i=0;i<BUFSIZE;i++){
00737        set_feedback(&session_data->preedit_feedback[i], IMUnderline);
00738     }
00739     memset(session_data->preedit_buf, 0, sizeof(UTFCHAR) * BUFSIZE);
00740     memset(session_data->status_buf, 0, sizeof(UTFCHAR) * BUFSIZE);
00741     memset(session_data->commit_buf, 0, sizeof(UTFCHAR) * BUFSIZE);
00742     memset(session_data->preedit_string, 0, sizeof(UTFCHAR) * BUFSIZE);
00743     memset(session_data->conversion_string, 0, sizeof(UTFCHAR) * BUFSIZE);
00744     session_data->caret_pos = -1;
00745     
00746     /*
00747     * return committed string
00748     */
00749     if (p->char_length) {
00750         return p;
00751     }
00752     return (IMText *) NULL;
00753 }
00754 
00755 void
00756 if_udengine_SetSCFocus(
00757     iml_session_t * s
00758 )
00759 {
00760     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00761     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
00762 #ifdef DEBUG
00763     printf("if_udengine_SetSCFocus()\n");
00764 #endif
00765     aux_start(s);
00766     aux_set(s);
00767 }
00768 
00769 void
00770 if_udengine_UnsetSCFocus(
00771     iml_session_t * s
00772 )
00773 {
00774 #ifdef DEBUG
00775     printf("if_udengine_UnsetSCFocus()\n");
00776     debugprint(s);
00777 #endif
00778 }
00779 
00780 void
00781 if_udengine_SendEvent(
00782     iml_session_t * s,
00783     IMInputEvent * ev
00784 )
00785 {
00786 #ifdef DEBUG
00787     printf("if_udengine_SendEvent s=%x ev=%x\n", s, ev);
00788 #endif
00789     if (ev) {
00790         if (ev->type == IM_EventKeyList) {
00791             if (receive_keylist(s, (IMKeyListEvent *) ev) == False) {
00792                 IMKeyListEvent *keylist = (IMKeyListEvent *) ev;
00793                 iml_inst *lp = s->If->m->iml_make_keypress_inst(s, (IMKeyEventStruct *) keylist->keylist);
00794                 s->If->m->iml_execute(s, &lp);
00795             }
00796         } else if (ev->type == IM_EventAux) {
00797             IMAuxEvent *aux = (IMAuxEvent *) ev;
00798             IMAuxDrawCallbackStruct *data = aux->aux;
00799             receive_aux(s, data);
00800         } else if (ev->type == IM_EventString) {
00801             /* String Event */
00802         } else if (ev->type == IM_EventText) {
00803             /* Text Event */
00804         }
00805     }
00806 }
00807 
00808 void im_send_aux_event(s,key,index)
00809 iml_session_t *s;
00810 int key;
00811 int index;
00812 {
00813     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00814     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
00815 
00816 /*        XIMAuxDrawCallbackStruct *dcb;*/
00817 
00818     switch(key) {
00819         case '1':
00820             desktop_data->punc = (desktop_data->punc == 0) ? 1 : 0 ;
00821             break;
00822 
00823         case '2':
00824            if(index != -1) desktop_data->skb = index;
00825            else {
00826                      desktop_data->skb ++; 
00827               desktop_data->skb = desktop_data->skb % max_codetable_number;
00828            }
00829         default:
00830             break;
00831     }
00832     aux_set(s);
00833 
00834 /*
00835         dcb = (XIMAuxDrawCallbackStruct *)create_aux_struct(s);
00836         im_draw_aux(s,dcb);
00837 */
00838         return;
00839 }
00840 
00841 void eval_packet(s, imdata)
00842 iml_session_t *s ;
00843 im_data *imdata;
00844 {
00845     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00846     iml_inst *lp;
00847     UTFCHAR **luc_tmp;
00848     int k;
00849     int caret;
00850 
00851     if(imdata->operation == CIM_STATUS) status_draw(s); 
00852        
00853     session_data->caret_pos = imdata->caret_pos;
00854     zh_str_to_utf16(imdata->pre_str, session_data->preedit_buf, &session_data->caret_pos);
00855     preedit_draw(s);
00856        
00857     if( (imdata->operation == CIM_COMMIT) || (imdata->operation == CIM_COMMITSYMBOL) ) {
00858        zh_str_to_utf16(imdata->commit_str, session_data->commit_buf, &caret);
00859        commit(s);
00860     }
00861 
00862     if (imdata->luc_num > 0) {
00863        session_data->luc_nchoices = imdata->luc_num;
00864        luc_tmp = (UTFCHAR**) s->If->m->iml_new(s, session_data->luc_nchoices * sizeof(UTFCHAR*));
00865        for(k = 0; k < session_data->luc_nchoices; k ++) {
00866            luc_tmp[k] = (UTFCHAR*) s->If->m->iml_new(s, MAX_PHRASE_LEN * sizeof(UTFCHAR));
00867            luc_tmp[k][0] = 0;
00868            zh_str_to_utf16(imdata->luc_str[k], luc_tmp[k], &caret);
00869        }
00870        lookup_draw(s, luc_tmp, imdata->luc_num);
00871     }
00872     else if(session_data->luc_start == True){
00873         lp = (iml_inst*)s->If->m->iml_make_lookup_done_inst(s);
00874         s->If->m->iml_execute(s, &lp);
00875        session_data->luc_start = False;
00876     }
00877 }
00878 
00879 Bool
00880 receive_keylist(
00881     iml_session_t * s,
00882     IMKeyListEvent * keylist
00883 )
00884 {
00885     int i;
00886     im_data *imdata;
00887     IMKeyEventStruct *k = (IMKeyEventStruct *) keylist->keylist;
00888     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00889     long kcode, modifier;
00890     unsigned short kchar;
00891     i = UTFCHARLen(session_data->preedit_buf);
00892 
00893     #ifdef DEBUG
00894        printf("keycode %x, keychar %x state %x\n",k->keyCode, k->keyChar, k->modifier);
00895     #endif
00896 
00897     kcode = k->keyCode;
00898     kchar = k->keyChar;
00899     modifier = k->modifier; 
00900 
00901     modifyEvent(&kcode, &kchar, &modifier);
00902     if((modifier & 0x0008 ) == 0x0008) {  /*aux operation*/ 
00903        im_send_aux_event(s, kcode, -1);
00904        return True;
00905     }
00906 
00907     if((modifier == 4) && (kchar == 0x20)) { /* conversion off */
00908        my_conversion_off(s);
00909        return True;
00910     }
00911     imdata = (im_data *)IM_sendEvent(session_data->session_id, kcode, kchar, modifier);
00912     if(imdata == NULL) return False;
00913 
00914     #ifdef DEBUG
00915     if(imdata != NULL) {
00916         printf("imdata->operation=%d\n",imdata->operation);
00917         printf("imdata->pre_str=%s\n",imdata->pre_str);
00918         printf("imdata->caret_pos=%d\n",imdata->caret_pos);
00919         printf("imdata->luc_str=%s\n",imdata->luc_str[0]);
00920         printf("imdata->luc_num=%d\n",imdata->luc_num);
00921         printf("imdata->commit_str=%s\n",imdata->commit_str);
00922         printf("imdata->status_str=%s\n",imdata->status_str);
00923         printf("imdata->error_num=%d\n",imdata->error_num);
00924     }
00925     #endif
00926 
00927     if(imdata->operation == CIM_BOUNCEKEY) return False;
00928     else {
00929         eval_packet(s, imdata);
00930        return True;
00931     }
00932 }
00933 
00934 UTFCHARCat(
00935     UTFCHAR * dest,
00936     UTFCHAR * str1,
00937     UTFCHAR * str2
00938 )
00939 {
00940     int i;
00941     for (i = 0; *str1; i++) {
00942         *dest++ = *str1++;
00943     }
00944     for (i = 0; *str2; i++) {
00945         *dest++ = *str2++;
00946     }
00947     *dest = 0;
00948     return i;
00949 }
00950 
00951 int
00952 UTFCHARCpy(
00953     UTFCHAR * dest,
00954     UTFCHAR * original
00955 )
00956 {
00957     int i;
00958     for (i = 0; *original; i++) {
00959         *dest++ = *original++;
00960     }
00961     *dest = 0;
00962     return i;
00963 }
00964 
00965 int
00966 UTFCHARLen(
00967     UTFCHAR * p
00968 )
00969 {
00970     int i;
00971     for (i = 0; *p; i++)
00972     p++;
00973     return i;
00974 }
00975 
00976 void
00977 commit(
00978     iml_session_t * s
00979 )
00980 {
00981     int len, i;
00982     iml_inst *lp;
00983     iml_inst *rrv = NULL;
00984     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
00985     IMText *p = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00986     memset(p, 0, sizeof(IMText));
00987     p->encoding = UTF16_CODESET;
00988     
00989     len = UTFCHARLen(session_data->commit_buf);
00990     if (len != 0) {
00991        p->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * (len + 1));
00992        UTFCHARCpy(p->text.utf_chars, session_data->commit_buf);
00993        p->char_length = len;
00994        p->feedback = create_feedback(s, p->char_length);
00995        lp = s->If->m->iml_make_commit_inst(s, p);
00996        s->If->m->iml_link_inst_tail(&rrv, lp);
00997        s->If->m->iml_execute(s, &rrv);
00998     }
00999     for(i=0;i<BUFSIZE;i++){
01000        set_feedback(&session_data->preedit_feedback[i], IMUnderline);
01001     }
01002     memset(session_data->preedit_buf, 0, sizeof(UTFCHAR) * BUFSIZE);
01003     memset(session_data->commit_buf, 0, sizeof(UTFCHAR) * BUFSIZE);
01004     memset(session_data->preedit_string, 0, sizeof(UTFCHAR) * BUFSIZE);
01005     memset(session_data->conversion_string, 0, sizeof(UTFCHAR) * BUFSIZE);
01006     
01007     session_data->caret_pos = -1;
01008 }
01009 
01010 void 
01011 aux_set(
01012     iml_session_t *s
01013 )
01014 {
01015     int caret;
01016     char mode[40];
01017     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01018     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01019     im_data* imdata;
01020     extern im_data *IM_setAuxValue();
01021 
01022     IM_setAuxValue(session_data->session_id, PUNCTUATION_STATUS, desktop_data->punc);
01023 
01024     imdata = (im_data *)IM_setAuxValue(session_data->session_id, SOFTKEYBOARD_LAYOUT, desktop_data->skb);
01025     if(imdata) {
01026         zh_str_to_utf16(imdata->status_str, session_data->status_buf, &caret);
01027         eval_packet(s,imdata);
01028     }
01029     else {
01030        IM_getValue(session_data->session_id, IM_STATUS, mode);
01031        zh_str_to_utf16(mode, session_data->status_buf, &caret);
01032        status_draw(s);
01033     }
01034 }
01035 
01036 
01037 void
01038 status_draw(
01039     iml_session_t * s
01040 )
01041 {
01042     int len;
01043     iml_inst *lp;
01044     iml_inst *rrv = NULL;
01045     UTFCHAR status_str[20];
01046     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01047     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01048 
01049     IMText *p = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
01050     memset(p, 0, sizeof(IMText));
01051 
01052     p->encoding = UTF16_CODESET;
01053     
01054     if (session_data->conv_on) {
01055        UTFCHARCpy(status_str, session_data->status_buf);
01056     } else {
01057          UTFCHARCpy(status_str,off_string);
01058     }
01059     
01060     len = UTFCHARLen(status_str);
01061     p->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * (len + 1));
01062     
01063     UTFCHARCpy(p->text.utf_chars, status_str);
01064     
01065     p->char_length = len;
01066     p->feedback = create_feedback(s, p->char_length);
01067 
01068     if (session_data->status_start == False) {
01069         lp = s->If->m->iml_make_status_start_inst(s);
01070         s->If->m->iml_link_inst_tail(&rrv, lp);
01071         session_data->status_start = True;
01072     }
01073     lp = s->If->m->iml_make_status_draw_inst(s, p);
01074     s->If->m->iml_link_inst_tail(&rrv, lp);
01075     
01076     s->If->m->iml_execute(s, &rrv);
01077 }
01078 
01079 void
01080 preedit_buf_print(iml_session_t * s)
01081 {
01082     int i;
01083     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01084     int len = UTFCHARLen(session_data->preedit_buf);
01085     for (i = 0; i <= len; i++) {
01086         printf("Preedit[%d]=%x     %x\n",
01087             i,
01088             session_data->preedit_buf[i],
01089            get_feedback(&session_data->preedit_feedback[i]));
01090     }
01091 }
01092 
01093 IMText *
01094 make_imtext(iml_session_t * s, UTFCHAR * u)
01095 {
01096     int len;
01097     IMText *p = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
01098     memset(p, 0, sizeof(IMText));
01099     p->encoding = UTF16_CODESET;
01100     len = UTFCHARLen(u);
01101     p->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * (len + 1));
01102     UTFCHARCpy(p->text.utf_chars, u);
01103     p->char_length = len;
01104     p->feedback = create_feedback(s, p->char_length);
01105     return p;
01106 }
01107 
01108 IMText *
01109 make_preedit_imtext(iml_session_t * s)
01110 {
01111     int len, i;
01112     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01113     IMText *p = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
01114     memset(p, 0, sizeof(IMText));
01115 
01116     p->encoding = UTF16_CODESET;
01117     len = UTFCHARLen(session_data->preedit_buf);
01118     p->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * (len + 1));
01119     UTFCHARCpy(p->text.utf_chars, session_data->preedit_buf);
01120     p->char_length = len;
01121     p->feedback = create_feedback(s, p->char_length);
01122     for(i = 0; i < session_data->caret_pos; i ++) {
01123        set_feedback(&session_data->preedit_feedback[i], IMReverse);
01124     }
01125     for(i = session_data->caret_pos; i < p->char_length; i ++) {
01126        set_feedback(&session_data->preedit_feedback[i], IMUnderline);
01127     }
01128     for (i = 0; i < p->char_length; i++) {
01129         set_feedback(&p->feedback[i], get_feedback(&session_data->preedit_feedback[i]));
01130     }
01131     return p;
01132 }
01133 
01134 void
01135 preedit_draw(
01136     iml_session_t * s
01137 )
01138 {
01139     iml_inst *lp;
01140     iml_inst *rrv = NULL;
01141     
01142     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01143     IMText *p = make_preedit_imtext(s);
01144     
01145     if (session_data->preedit_start == False) {
01146         lp = s->If->m->iml_make_preedit_start_inst(s);
01147         s->If->m->iml_link_inst_tail(&rrv, lp);
01148         session_data->preedit_start = True;
01149     }
01150     if(p->char_length == 0) {
01151        lp = s->If->m->iml_make_preedit_erase_inst(s);
01152        s->If->m->iml_link_inst_tail(&rrv, lp);
01153        s->If->m->iml_execute(s, &rrv);
01154        return;
01155     }
01156     lp = s->If->m->iml_make_preedit_draw_inst(s, p);
01157     s->If->m->iml_link_inst_tail(&rrv, lp);
01158     
01159     if(session_data->caret_pos != -1) {
01160        lp = s->If->m->iml_make_preedit_caret_inst(s, session_data->caret_pos); 
01161        s->If->m->iml_link_inst_tail(&rrv, lp);
01162     }
01163     s->If->m->iml_execute(s, &rrv);
01164 }
01165 
01166 void
01167 lookup_draw(iml_session_t * s, UTFCHAR ** luc_tmp, int luc_num)
01168 {
01169     int i;
01170     int j = 0;
01171     iml_inst *lp;
01172     MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
01173     IMLookupDrawCallbackStruct *draw;
01174     IMLookupStartCallbackStruct *start;
01175     int max_len = 0;
01176     IMText **candidates;
01177     IMText **labels;
01178     int len;
01179     UTFCHAR buf[BUFSIZE];
01180     
01181     if (session_data->luc_candidates == NULL) {
01182         session_data->luc_candidates = (IMText **) calloc(MAXCANDIDATES, sizeof(IMText *));
01183     }
01184     candidates = session_data->luc_candidates;
01185     
01186     for (i = 0; i < luc_num; i++) {
01187         if (candidates[i]) {
01188             free(candidates[i]->text.utf_chars);
01189             free(candidates[i]->feedback);
01190             free(candidates[i]);
01191         }
01192         candidates[i] = (IMText *) calloc(1, sizeof(IMText));
01193         candidates[i]->encoding = UTF16_CODESET;
01194         candidates[i]->char_length = UTFCHARLen(luc_tmp[i]);
01195         candidates[i]->text.utf_chars = (UTFCHAR *) calloc(1,
01196             sizeof(IMText) * (candidates[i]->char_length + 1));
01197         UTFCHARCpy(candidates[i]->text.utf_chars, luc_tmp[i]);
01198 
01199         candidates[i]->feedback = create_feedback(0, candidates[i]->char_length);
01200     }
01201     
01202     if (session_data->luc_labels == NULL) {
01203         session_data->luc_labels = (IMText **) calloc(MAXCANDIDATES, sizeof(IMText));
01204         labels = session_data->luc_labels;
01205         for (i = '1'; i <= '9'; i++, j++) {
01206             labels[j] = (IMText *) calloc(1, sizeof(IMText));
01207            labels[j]->encoding = UTF16_CODESET;
01208             labels[j]->char_length = 1;
01209             labels[j]->text.utf_chars = (UTFCHAR *) calloc(1,
01210                 sizeof(IMText) * (labels[j]->char_length + 1));
01211             labels[j]->text.utf_chars[0] = (UTFCHAR) i;
01212             labels[j]->feedback = create_feedback(0, labels[j]->char_length);
01213         }
01214 /*
01215         for (i = 'A'; i <= 'Z'; i++, j++) {
01216             labels[j] = (IMText *) calloc(1, sizeof(IMText));
01217            labels[j]->encoding = UTF16_CODESET;
01218             labels[j]->char_length = 1;
01219             labels[j]->text.utf_chars = (UTFCHAR *) calloc(1,
01220                 sizeof(IMText) * (labels[j]->char_length + 1));
01221             labels[j]->text.utf_chars[0] = (UTFCHAR) i;
01222             labels[j]->feedback = (IMFeedback *) calloc(1,
01223                 sizeof(IMText) * (labels[j]->char_length + 1));
01224             memset(labels[j]->feedback, 0, sizeof(IMFeedback) * (labels[j]->char_length + 1));
01225         }
01226         for (i = 'a'; i <= 'z'; i++, j++) {
01227             labels[j] = (IMText *) calloc(1, sizeof(IMText));
01228            labels[j]->encoding = UTF16_CODESET;
01229             labels[j]->char_length = 1;
01230             labels[j]->text.utf_chars = (UTFCHAR *) calloc(1,
01231                 sizeof(IMText) * (labels[j]->char_length + 1));
01232             labels[j]->text.utf_chars[0] = (UTFCHAR) i;
01233             labels[j]->feedback = (IMFeedback *) calloc(1,
01234                 sizeof(IMText) * (labels[j]->char_length + 1));
01235             memset(labels[j]->feedback, 0, sizeof(IMFeedback) * (labels[j]->char_length + 1));
01236         }
01237 */
01238     }
01239     labels = session_data->luc_labels;
01240     
01241     if (session_data->luc_start == False) {
01242         session_data->luc_top = 0;
01243         start = (IMLookupStartCallbackStruct *) s->If->m->iml_new(s, sizeof(IMLookupStartCallbackStruct));
01244         memset(start, 0, sizeof(IMLookupStartCallbackStruct));
01245         start->whoIsMaster = IMIsMaster;
01246         session_data->luc_type = IMIsMaster;
01247         start->IMPreference = (LayoutInfo *) s->If->m->iml_new(s, sizeof(LayoutInfo));
01248         memset(start->IMPreference, 0, sizeof(LayoutInfo));
01249         start->IMPreference->choice_per_window = 7;
01250         start->IMPreference->ncolumns = 7;
01251         start->IMPreference->nrows = 1;
01252         start->IMPreference->drawUpDirection = DrawUpHorizontally;
01253         start->IMPreference->whoOwnsLabel = IMOwnsLabel;
01254         start->CBPreference = NULL;
01255         lp = s->If->m->iml_make_lookup_start_inst(s, start);
01256         s->If->m->iml_execute(s, &lp);
01257         session_data->luc_start = True;
01258     }
01259     draw = (IMLookupDrawCallbackStruct *) s->If->m->iml_new(s, sizeof(IMLookupDrawCallbackStruct));
01260     memset(draw, 0, sizeof(IMLookupDrawCallbackStruct));
01261     draw->index_of_first_candidate = 0;
01262     draw->index_of_last_candidate = luc_num - 1;
01263     draw->n_choices = draw->index_of_last_candidate - draw->index_of_first_candidate + 1;
01264     
01265     draw->title = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
01266     memset(draw->title, 0, sizeof(IMText));
01267     draw->title->encoding = UTF16_CODESET;
01268     draw->title->char_length = UTFCHARLen(title_string);
01269     draw->title->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s,
01270         sizeof(IMText) * (draw->title->char_length + 1));
01271     UTFCHARCpy(draw->title->text.utf_chars, title_string);
01272     draw->title->feedback = create_feedback(s, draw->title->char_length);
01273     
01274     draw->choices = (IMChoiceObject *) s->If->m->iml_new(s, draw->n_choices * sizeof(IMChoiceObject));
01275     memset(draw->choices, 0, draw->n_choices * sizeof(IMChoiceObject));
01276     
01277     for (i = 0; i < draw->n_choices; i++) {
01278         IMText *vt;         /* for value */
01279         IMText *lt;         /* for label */
01280         vt = draw->choices[i].value = candidates[i + session_data->luc_top];
01281         lt = draw->choices[i].label = labels[i];
01282 #ifdef DEBUG        
01283         printf("candidates[%d]=%x\n", i + session_data->luc_top,
01284             candidates[i + session_data->luc_top]);
01285 #endif
01286         
01287         if (max_len < vt->char_length)
01288             max_len = vt->char_length;
01289         
01290         if (i + session_data->luc_top == session_data->max_candidates) {
01291             draw->index_of_first_candidate = 0;
01292             draw->index_of_last_candidate = i;
01293             draw->n_choices = i + 1;
01294             break;
01295         }
01296     }
01297     draw->max_len = max_len;
01298     draw->max_len = 20;
01299     draw->index_of_current_candidate = session_data->luc_current_candidate;
01300     
01301 #ifdef DEBUG        
01302     printf("session_data->luc_top=%x\n", session_data->luc_top);
01303     
01304     printf("draw->index_of_first_candidate=%x\n", draw->index_of_first_candidate);
01305     printf("draw->index_of_last_candidate=%x\n", draw->index_of_last_candidate);
01306     printf("draw->n_choices=%x\n", draw->n_choices);
01307     printf("draw->max_len=%x\n", max_len);
01308     printf("draw->index_of_current_candidate=%x\n", session_data->luc_current_candidate);
01309 #endif    
01310 
01311     lp = s->If->m->iml_make_lookup_draw_inst(s, draw);
01312     s->If->m->iml_execute(s, &lp);
01313 }
01314 
01315 void
01316 receive_aux(
01317     iml_session_t * s,
01318     IMAuxDrawCallbackStruct * aux
01319 )
01320 {
01321     IMText *lts, *lt;
01322     int i, j, index;
01323     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01324 
01325 #ifdef DEBUG
01326     printf("AUX\n");
01327     
01328     printf("\taux_name=[%s]\n", aux->aux_name);
01329     printf("\tcount_integer_values=[%d]\n", aux->count_integer_values);
01330     printf("\tcount_string_values=[%d]\n", aux->count_string_values);
01331     
01332     printf("\t** INT[] **\n");
01333 #endif
01334 
01335     if(aux->count_integer_values == 3) {
01336        desktop_data->punc = aux->integer_values[0];
01337        desktop_data->skb = aux->integer_values[1];
01338        desktop_data->gbk_support = aux->integer_values[2];     
01339     }
01340 }
01341 
01342 void
01343 aux_start(
01344     iml_session_t * s
01345 )
01346 {
01347     int i;
01348     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01349     iml_session_t *s_ = desktop_data->auxproxy_session;
01350 
01351     if(s_ == NULL) {
01352        s_ = desktop_data->auxproxy_session = s;
01353        printf("aux_start: auxproxy_session is NULL, take the responsibility for auxproxy\n");
01354     }
01355 
01356     if (desktop_data->aux_started == False) {
01357         iml_inst *lp;
01358         IMAuxStartCallbackStruct *aux = (IMAuxStartCallbackStruct *) s_->If->m->iml_new(s_, sizeof(IMAuxStartCallbackStruct));
01359         memset(aux, 0, sizeof(IMAuxStartCallbackStruct));
01360         aux->aux_name = class_names[0];
01361         lp = s_->If->m->iml_make_aux_start_inst(s_, aux);
01362         s_->If->m->iml_execute(s_, &lp);
01363 #ifdef DEBUG
01364         printf("Starting AUX [%s]\n", class_names[0]);
01365 #endif
01366         desktop_data->aux_started = True;
01367     } else {
01368 #ifdef DEBUG
01369         printf("AUX[%s] is already started.\n", class_names[0]);
01370 #endif
01371     }
01372 }
01373 
01374 void
01375 aux_done(
01376     iml_session_t * s
01377 )
01378 {
01379     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01380     iml_session_t *s_ = desktop_data->auxproxy_session;
01381 
01382     if (desktop_data->aux_started == True) {
01383         iml_inst *lp;
01384         IMAuxDoneCallbackStruct *aux = (IMAuxDoneCallbackStruct *) 
01385               s_->If->m->iml_new(s_, sizeof(IMAuxDoneCallbackStruct));
01386         memset(aux, 0, sizeof(IMAuxDoneCallbackStruct));
01387         aux->aux_name = class_names[0];
01388         lp = s_->If->m->iml_make_aux_done_inst(s_, aux);
01389         s_->If->m->iml_execute(s_, &lp);
01390 #ifdef DEBUG
01391         printf("Closing AUX\n");
01392 #endif
01393         desktop_data->aux_started = False;
01394     } else {
01395 #ifdef DEBUG
01396         printf("AUX is already done.\n");
01397 #endif
01398     }
01399 }
01400 
01401 void
01402 aux_draw(
01403     iml_session_t * s,
01404     int class_name_id,
01405     int count_integers,
01406     int *integers,
01407     int count_strings,
01408     UTFCHAR ** strings
01409 )
01410 {
01411     iml_inst *lp;
01412     int i, j;
01413     int len = 7;
01414     IMText *lts, *lt;
01415     IMAuxDrawCallbackStruct *aux;
01416     MyDataPerDesktop *desktop_data = (MyDataPerDesktop *) s->desktop->specific_data;
01417     iml_session_t *s_ = desktop_data->auxproxy_session;
01418 
01419     if(s_ == NULL) {
01420        s_ = desktop_data->auxproxy_session = s;
01421 #ifdef DEBUG
01422        printf("aux_draw: auxproxy_session is NULL, take the responsibility for auxproxy\n");
01423 #endif
01424     }
01425 
01426     if (desktop_data->aux_started == False) {
01427 #ifdef DEBUG
01428         printf("AUX is not started.\n");
01429 #endif
01430         return;
01431     }
01432     aux = (IMAuxDrawCallbackStruct *) s_->If->m->iml_new(s_, sizeof(IMAuxDrawCallbackStruct));
01433     memset(aux, 0, sizeof(IMAuxDrawCallbackStruct));
01434 
01435     aux->aux_name = class_names[0];
01436 
01437     aux->count_integer_values = count_integers;
01438     if (aux->count_integer_values) {
01439         aux->integer_values = (int *) s_->If->m->iml_new(s_, sizeof(int) * aux->count_integer_values);
01440         memset(aux->integer_values, 0, sizeof(int) * aux->count_integer_values);
01441 
01442         for (i = 0; i < aux->count_integer_values; i++) {
01443             aux->integer_values[i] = integers[i];
01444         }
01445     }
01446     aux->count_string_values = count_strings;
01447     if (aux->count_string_values) {
01448         aux->string_values = lts = (IMText *)
01449         s_->If->m->iml_new(s_, sizeof(IMText) * aux->count_string_values);
01450         memset(aux->string_values, 0, sizeof(IMText) * aux->count_string_values);
01451         aux->string_values->encoding = UTF16_CODESET;
01452 
01453         for (i = 0, lt = lts; i < aux->count_string_values; i++, lt++) {
01454             len = UTFCHARLen(strings[i]);
01455             lt->text.utf_chars = (UTFCHAR *) s_->If->m->iml_new(s_, sizeof(UTFCHAR) * (len + 1));
01456             lt->char_length = len + 1;
01457             UTFCHARCpy(lt->text.utf_chars, strings[i]);
01458         }
01459     }
01460     lp = s_->If->m->iml_make_aux_draw_inst(s_, aux);
01461     s_->If->m->iml_execute(s_, &lp);
01462 }
01463 
01464 IMFeedbackList *
01465 create_feedback2(
01466     iml_session_t * s,
01467     int size
01468 )
01469 {
01470     int i;
01471     IMFeedbackList *feedback, *fbl;
01472     IMFeedback *fb;
01473     feedback = (IMFeedbackList *) s->If->m->iml_new2(s, sizeof(IMFeedbackList) * size);
01474     memset(feedback, 0, sizeof(IMFeedbackList) * size);
01475     for (i = 0; i < size; i++) {
01476         IMFeedbackList *fbl = &feedback[i];
01477         fbl->count_feedbacks = 1;
01478         fb = fbl->feedbacks = (IMFeedback *) s->If->m->iml_new2(s, sizeof(IMFeedback));
01479         memset(fbl->feedbacks, 0, sizeof(IMFeedback));
01480     }
01481     return feedback;
01482 }
01483 
01484 IMFeedbackList *
01485 create_feedback(
01486     iml_session_t * s,
01487     int size
01488 )
01489 {
01490     int i;
01491     IMFeedbackList *feedback, *fbl;
01492     IMFeedback *fb;
01493     
01494     if (s) {
01495         feedback = (IMFeedbackList *) s->If->m->iml_new(s, sizeof(IMFeedbackList) * size);
01496         memset(feedback, 0, sizeof(IMFeedbackList) * size);
01497     } else {
01498         feedback = (IMFeedbackList *) calloc(1, sizeof(IMFeedbackList) * size);
01499     }
01500     for (i = 0; i < size; i++) {
01501         IMFeedbackList *fbl = &feedback[i];
01502         fbl->count_feedbacks = 1;
01503         if (s) {
01504             fb = fbl->feedbacks = (IMFeedback *) s->If->m->iml_new(s, sizeof(IMFeedback));
01505             memset(fbl->feedbacks, 0, sizeof(IMFeedback));
01506         } else {
01507             fb = fbl->feedbacks = (IMFeedback *) calloc(1, sizeof(IMFeedback));
01508         }
01509     }
01510     return feedback;
01511 }
01512 
01513 int
01514 get_feedback(
01515     IMFeedbackList * fbl
01516 )
01517 {
01518     IMFeedback *fb = &fbl->feedbacks[0];
01519     return IM_FEEDBACK_VALUE(fb);
01520 }
01521 
01522 void
01523 set_feedback(
01524     IMFeedbackList * fbl,
01525     int value
01526 )
01527 {
01528     IMFeedback *fb = &fbl->feedbacks[0];
01529     IM_FEEDBACK_TYPE(fb)=IM_DECORATION_FEEDBACK;
01530     IM_FEEDBACK_VALUE(fb)=value;
01531 }