Back to index

im-sdk  12.3.91
SunIMSubr.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 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <sys/param.h>
00046 
00047 #include "SunIM.h"
00048 #include "SunIMLock.h"
00049 #ifdef  sun
00050 #include <unistd.h>
00051 #endif
00052 
00053 Private iml_inst *iml_make_preedit_start_inst(iml_session);
00054 Private iml_inst *iml_make_preedit_draw_inst(iml_session, IMText *);
00055 Private iml_inst *iml_make_preedit_draw_with_caret_inst(iml_session, IMText *, int);
00056 Private iml_inst *iml_make_preedit_draw_with_chgpos_inst(iml_session_t *, IMText *, int, int, int);
00057 Private iml_inst *iml_make_preedit_erase_inst(iml_session_t *);
00058 Private iml_inst *iml_make_preedit_caret_inst(iml_session_t *, int);
00059 Private iml_inst *iml_make_preedit_done_inst(iml_session_t *);
00060 
00061 Private iml_inst *iml_make_status_start_inst(iml_session_t *);
00062 Private iml_inst *iml_make_status_draw_inst(iml_session_t *, IMText *);
00063 Private iml_inst *iml_make_status_done_inst(iml_session_t *);
00064 
00065 Private iml_inst *iml_make_lookup_start_inst(iml_session_t *, IMLookupStartCallbackStruct *);
00066 Private iml_inst *iml_make_lookup_draw_inst(iml_session_t *, IMLookupDrawCallbackStruct *);
00067 Private iml_inst *iml_make_lookup_done_inst(iml_session_t *);
00068 
00069 Private iml_inst *iml_make_aux_start_inst(iml_session_t *, IMAuxStartCallbackStruct *);
00070 Private iml_inst *iml_make_aux_draw_inst(iml_session_t *, IMAuxDrawCallbackStruct *);
00071 Private iml_inst *iml_make_aux_done_inst(iml_session_t *, IMAuxDoneCallbackStruct *);
00072 
00073 Private iml_inst *iml_make_start_conversion_inst(iml_session_t *);
00074 Private iml_inst *iml_make_end_conversion_inst(iml_session_t *);
00075 
00076 Private iml_inst *iml_make_commit_inst(iml_session_t *, IMText *);
00077 
00078 Private iml_inst *iml_make_keypress_inst(iml_session_t *, IMKeyEventStruct *);
00079 
00080 Private iml_inst *iml_link_inst_tail(iml_inst **, iml_inst *);
00081 Public iml_inst *iml_execute_iml_wrapper(iml_session_t *, iml_inst **);
00082 
00083 Private void *iml_new(iml_session_t *, int);
00084 Private void *iml_new2(iml_session_t *, int);
00085 Private void *iml_delete(iml_session_t *);
00086 Private void *iml_delete2(iml_session_t *);
00087 
00088 Public int iml_add_listener(iml_session_t *, char *, void *, void *); 
00089 Public int iml_delete_listener(iml_session_t *, int);
00090 
00091 
00092 Private void iml_ns_listener_ahead(iml_session_t *, int, void *);
00093 Private iml_inst *iml_make_nop_inst(iml_session_t *);
00094 Private int lookup_config_for_listener(char *, void *);
00095 
00096 extern char *secure_pathname(char *);
00097 
00098 Public iml_methods_t _iml_methods = {
00099        iml_make_preedit_start_inst,
00100        iml_make_preedit_draw_inst,
00101        iml_make_preedit_draw_with_chgpos_inst,
00102        iml_make_preedit_erase_inst,
00103        iml_make_preedit_caret_inst,
00104        iml_make_preedit_done_inst,
00105     
00106        iml_make_status_start_inst,
00107        iml_make_status_draw_inst,
00108        iml_make_status_done_inst,
00109     
00110        iml_make_lookup_start_inst,
00111        iml_make_lookup_draw_inst,
00112        iml_make_lookup_done_inst,
00113     
00114        iml_make_start_conversion_inst,
00115        iml_make_end_conversion_inst,
00116     
00117        iml_make_commit_inst,
00118        iml_make_keypress_inst,
00119     
00120        iml_make_aux_start_inst,
00121        iml_make_aux_draw_inst,
00122        iml_make_aux_done_inst,
00123     
00124        iml_new,
00125        iml_new2,
00126        iml_delete,
00127        iml_delete2,
00128  
00129        iml_link_inst_tail,
00130        iml_execute_iml_wrapper,
00131 
00132        iml_add_listener,
00133        iml_delete_listener,
00134 
00135 };
00136 
00137 /*-----------------------------------------------------------------
00138  * Making instance for Preedit region drawing method
00139  *----------------------------------------------------------------*/
00140 Private iml_inst *
00141 iml_make_preedit_start_inst(
00142     iml_session_t * s
00143 )
00144 {
00145     iml_inst *lp;
00146     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00147     ACTIVATE_REGION(s, PREEDIT);
00148     lp->opcode = IMM_PREEDIT_START;
00149     lp->next = NULL;
00150     lp->size_of_operand = 0;
00151     return lp;
00152 }
00153 
00154 static Bool compare_feedbacks(IMFeedbackList *, IMFeedbackList *);
00155 
00156 /* compare two feeback list */
00157 
00158 static Bool
00159 compare_feedbacks(
00160     IMFeedbackList * fbla,
00161     IMFeedbackList * fblb
00162 )
00163 {
00164     int la = IM_FEEDBACK_COUNT(fbla);
00165     IMFeedback *fba = fbla->feedbacks;
00166     int lb = IM_FEEDBACK_COUNT(fblb);
00167     IMFeedback *fbb = fblb->feedbacks;
00168     IMFeedback *fa, *fb;
00169     int i, j, type, value;
00170     int exist;
00171     
00172     /* return False if lengths are not same */
00173     if (la != lb) {
00174         return False;
00175     }
00176     /* compare each feedback */
00177     for (i = 0; i < la; i++) {
00178         fa = &fba[i];
00179         type = IM_FEEDBACK_TYPE(fa);
00180         value = IM_FEEDBACK_VALUE(fa);
00181         exist = 0;
00182         for (j = 0; j < lb; j++) {
00183             fb = &fbb[j];
00184             if (type == IM_FEEDBACK_TYPE(fb)) {
00185                 if (value != IM_FEEDBACK_VALUE(fb)) {
00186                     return False;
00187                 }
00188                 exist = 1;
00189             }
00190         }
00191         /* type does not exist in b */
00192         if (exist == 0) {
00193             return False;
00194         }
00195     }
00196     return True;
00197 }
00198 
00199 Private iml_inst *
00200 iml_make_preedit_draw_with_caret_inst(
00201     iml_session_t * s,
00202     IMText * text,   /* current text */
00203     int caret
00204 )
00205 {
00206     iml_inst *lp;
00207     IMPreeditDrawCallbackStruct *p;
00208     
00209     UTFCHAR *cws;           /* current str */
00210     IMFeedbackList *cfb;    /* current feedback */
00211     UTFCHAR *pws;           /* prev str */
00212     int pwl;                /* prev len */
00213     IMFeedbackList *pfb;    /* prev fb */
00214     int cwl;                /* current len */
00215     int si;                 /* str index */
00216     int sri;                /* str reverse index */
00217     int fbi;                /* fb index */
00218     int fbri;               /* fb reverse index */
00219     int i;                  /* index */
00220     int j;
00221     int ri;
00222     
00223     if (text && text->encoding != UTF16_CODESET) {
00224         return (iml_make_nop_inst(s));
00225     }
00226     if (!text || text->char_length <= 0) {
00227         return (iml_make_preedit_erase_inst(s));
00228     }
00229     cws = text->text.utf_chars;
00230     cwl = text->char_length;
00231     cfb = text->feedback;
00232     
00233     if (!cfb) {
00234         return (iml_make_nop_inst(s));
00235     }
00236     pws = s->PreEditTextInfo.text->text.utf_chars;
00237     pwl = s->PreEditTextInfo.text->char_length;
00238     pfb = s->PreEditTextInfo.text->feedback;
00239     
00240 #ifdef DEBUG
00241     printf("## CWS ##\n");
00242     //list_imtext(text);
00243     
00244     printf("## PWS ##\n");
00245     //list_imtext(s->PreEditTextInfo.text);
00246 #endif
00247     
00248     ri = pwl;
00249     
00250     /* Compare by utf_chars */
00251     for (si = 0; si < pwl; si++) {
00252         if (pws[si] != cws[si]) {
00253             break;
00254         }
00255     }
00256     
00257     if (cwl && (pwl == cwl)) {
00258         for (sri = pwl - 1; sri >= 0; sri--) {
00259             if (pws[sri] != cws[sri]) {
00260                 break;
00261             }
00262         }
00263         for (fbri = pwl - 1; fbri >= 0; fbri--) {
00264             if (compare_feedbacks(&pfb[fbri], &cfb[fbri]) == False) {
00265                 break;
00266             }
00267         }
00268         ri = _MAX(sri, fbri);
00269     }
00270 #ifdef DEBUG
00271     printf("## PWS ##\n");
00272     //list_feedback(pwl, pfb);
00273     
00274     printf("## CWS ##\n");
00275     //list_feedback(pwl, cfb);
00276 #endif
00277     
00278     for (fbi = 0; fbi < pwl; fbi++) {
00279         if (compare_feedbacks(&pfb[fbi], &cfb[fbi]) == False) {
00280             break;
00281         }
00282     }
00283     
00284     i = _MIN(si, fbi);
00285     
00286     if (caret == -1 && pwl == cwl && i == cwl) {
00287         /*
00288         * Current preedit is the same as previous
00289         */
00290         return (iml_make_nop_inst(s));
00291     }
00292 
00293     lp = (iml_inst *) s->If->m->iml_new(s,
00294                                    sizeof(iml_inst)
00295                                    + sizeof(IMPreeditDrawCallbackStruct));
00296     lp->opcode = IMM_PREEDIT_DRAW;
00297     lp->next = NULL;
00298     
00299     p = (IMPreeditDrawCallbackStruct *) & (lp->operand);
00300     p->text = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00301     p->text->encoding = UTF16_CODESET;
00302     p->text->feedback = cfb + i;
00303     p->text->count_annotations = 0;
00304     p->text->annotations = 0;
00305     if ((p->text->char_length = cwl - i) <= 0) {
00306         if (cwl < pwl) {
00307             p->text = NULL;
00308         } else {
00309             p->text->text.utf_chars = NULL;
00310         }
00311     } else {
00312         p->text->text.utf_chars = cws + i;
00313     }
00314     p->chg_first = i;
00315     p->chg_length = pwl - i;
00316     
00317     if (caret == -1) {
00318         p->caret = cwl;            /* iml_make_preedit_draw_inst() */
00319     } else {
00320         p->caret = caret;   /* caret is specified */
00321     }
00322     
00323 #ifdef DEBUG
00324     printf("iml_make_preedit_draw_with_caret_inst()\n");
00325     printf("  chg_first=%d\n", p->chg_first);
00326     printf("  chg_length=%d\n", p->chg_length);
00327     printf("  caret=%d\n", p->caret);
00328 #endif
00329     
00330 #ifdef IML_API_TEST
00331     /*
00332      * testing for text deletion and insertion
00333      */
00334     return iml_make_preedit_draw_with_chgpos_inst(
00335         s,
00336         p->text,
00337         p->chg_first,
00338         p->chg_length,
00339         p->caret);
00340 #endif
00341     
00342     /* buffer overflow */
00343     if ((cwl + 1) > s->PreEditTextBufferSize) {
00344         IMFeedbackList *flist;
00345         free(s->PreEditTextInfo.text->text.utf_chars);
00346         free(s->PreEditTextInfo.text->feedback);
00347         for (i = 0; i < s->PreEditTextBufferSize; i++) {
00348             flist = &s->PreEditTextInfo.text->feedback[i];
00349             if (flist) {
00350                 free(flist->feedbacks);
00351             }
00352         }
00353         free(s->PreEditTextInfo.text->feedback);
00354         s->PreEditTextInfo.text->text.utf_chars = (UTFCHAR *) calloc(1, sizeof(UTFCHAR) * (cwl + 1));
00355         
00356         s->PreEditTextInfo.text->feedback = (IMFeedbackList *) calloc(1, sizeof(IMFeedbackList) * (cwl + 1));
00357         for (i = 0; i < cwl + 1; i++) {
00358             flist = &s->PreEditTextInfo.text->feedback[i];
00359             flist->feedbacks = (IMFeedback *) calloc(1, sizeof(IMFeedback) * DEFAULTFeedbackSize);
00360         }
00361         
00362         s->PreEditTextBufferSize = cwl + 1;
00363         s->PreEditAttrBufferSize = cwl + 1;
00364     }
00365     s->PreEditTextInfo.text->char_length = cwl;
00366     memcpy(s->PreEditTextInfo.text->text.utf_chars, cws, cwl * sizeof(UTFCHAR));
00367     
00368     /*
00369      * save current string as previous string
00370      */
00371     for (i = 0; i < cwl; i++) {
00372         IMFeedbackList *fblp = &s->PreEditTextInfo.text->feedback[i];
00373         IMFeedbackList *fblc = &cfb[i];
00374         fblp->count_feedbacks = fblc->count_feedbacks;
00375         for (j = 0; j < fblc->count_feedbacks; j++) {
00376             IMFeedback *fbp = &fblp->feedbacks[j];
00377             IMFeedback *fbc = &fblc->feedbacks[j];
00378             IM_FEEDBACK_TYPE(fbp) = IM_FEEDBACK_TYPE(fbc);
00379             IM_FEEDBACK_VALUE(fbp) = IM_FEEDBACK_VALUE(fbc);
00380         }
00381     }
00382     return lp;
00383 }
00384 
00385 Private iml_inst *
00386 iml_make_preedit_draw_inst(
00387     iml_session_t * s,
00388     IMText * text
00389 )
00390 {
00391     if (text && text->encoding != UTF16_CODESET) {
00392         return (iml_make_nop_inst(s));
00393     }
00394     return iml_make_preedit_draw_with_caret_inst(s, text, -1);
00395 }
00396 
00397 Private iml_inst *
00398 iml_make_preedit_draw_with_chgpos_inst(
00399     iml_session_t * s,
00400     IMText * text,
00401     int chg_pos,
00402     int chg_len,
00403     int caret
00404 )
00405 {
00406     iml_inst *lp;
00407     IMPreeditDrawCallbackStruct *p;
00408     UTFCHAR *preedit_buf;
00409     IMFeedbackList *feedback_buf;
00410     int cwl;                /* current len */
00411     int i = 0;
00412     int j;
00413     
00414     if (text && text->encoding != UTF16_CODESET) {
00415         return (iml_make_nop_inst(s));
00416     }
00417     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMPreeditDrawCallbackStruct));
00418     lp->opcode = IMM_PREEDIT_DRAW;
00419     lp->next = NULL;
00420     
00421     p = (IMPreeditDrawCallbackStruct *) & (lp->operand);
00422     p->text = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00423     
00424     if (text == NULL) {
00425         /*
00426         * deletion
00427         */
00428         p->text = NULL;
00429     } else {
00430         /* feedback is required */
00431         if (!text->feedback) {
00432             return (iml_make_nop_inst(s));
00433         }
00434         p->text->encoding = UTF16_CODESET;
00435         p->text->text.utf_chars = text->text.utf_chars;
00436         p->text->char_length = text->char_length;
00437         p->text->feedback = text->feedback;
00438         p->text->count_annotations = text->count_annotations;
00439         p->text->annotations = text->annotations;
00440     }
00441     
00442     p->chg_first = chg_pos;
00443     p->chg_length = chg_len;
00444     p->caret = caret;
00445     
00446 #ifdef DEBUG
00447     printf("iml_make_preedit_draw_with_chgpos_inst()\n");
00448     if (text != NULL) {
00449         printf("     utf_char_length=%d\n", p->text->char_length);
00450     }
00451     printf("  chg_first=%d\n", p->chg_first);
00452     printf("  chg_length=%d\n", p->chg_length);
00453     printf("  caret=%d\n", p->caret);
00454 #endif
00455     
00456     preedit_buf = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * DEFAULTPreEditTextBufferSize);
00457     feedback_buf = (IMFeedbackList *) s->If->m->iml_new(s, sizeof(IMFeedbackList) * DEFAULTPreEditAttrBufferSize);
00458     
00459     cwl = 0;
00460     
00461     for (i = 0; i < p->chg_first; i++, cwl++) {
00462         preedit_buf[cwl] = s->PreEditTextInfo.text->text.utf_chars[i];
00463         feedback_buf[cwl] = s->PreEditTextInfo.text->feedback[i];
00464     }
00465     if (text != NULL) {
00466         for (i = 0; i < p->text->char_length; i++, cwl++) {
00467             preedit_buf[cwl] = p->text->text.utf_chars[i];
00468             feedback_buf[cwl] = p->text->feedback[i];
00469         }
00470     }
00471     for (i = p->chg_first + p->chg_length; i < s->PreEditTextInfo.text->char_length; i++, cwl++) {
00472         preedit_buf[cwl] = s->PreEditTextInfo.text->text.utf_chars[i];
00473         feedback_buf[cwl] = s->PreEditTextInfo.text->feedback[i];
00474     }
00475     preedit_buf[cwl] = 0;
00476     
00477     /*
00478      * save current string as previous string
00479      */
00480     if ((cwl + 1) > s->PreEditTextBufferSize) {
00481         free(s->PreEditTextInfo.text->text.utf_chars);
00482         free(s->PreEditTextInfo.text->feedback);
00483         s->PreEditTextInfo.text->text.utf_chars = (UTFCHAR *) calloc(sizeof(UTFCHAR), cwl + 1);
00484         s->PreEditTextInfo.text->feedback = (IMFeedbackList *) calloc(sizeof(IMFeedbackList), cwl);
00485         s->PreEditTextBufferSize = cwl + 1;
00486         s->PreEditAttrBufferSize = cwl + 1;
00487     }
00488     s->PreEditTextInfo.text->char_length = cwl;
00489     
00490     memcpy(s->PreEditTextInfo.text->text.utf_chars, preedit_buf,
00491           cwl * sizeof(UTFCHAR));
00492 
00493     for (i = 0; i < cwl; i++) {
00494         IMFeedbackList *fblp = &s->PreEditTextInfo.text->feedback[i];
00495         IMFeedbackList *fblc = &feedback_buf[i];
00496         fblp->count_feedbacks = fblc->count_feedbacks;
00497         for (j = 0; j < fblc->count_feedbacks; j++) {
00498             IMFeedback *fbp = &fblp->feedbacks[j];
00499             IMFeedback *fbc = &fblc->feedbacks[j];
00500             IM_FEEDBACK_TYPE(fbp) = IM_FEEDBACK_TYPE(fbc);
00501             IM_FEEDBACK_VALUE(fbp) = IM_FEEDBACK_VALUE(fbc);
00502         }
00503     }
00504     return lp;
00505 }
00506 
00507 Private iml_inst *
00508 iml_make_preedit_caret_inst(
00509     iml_session_t * s,
00510     int caret
00511 )
00512 {
00513     IMPreeditDrawCallbackStruct *p;
00514     iml_inst *lp;
00515     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMPreeditDrawCallbackStruct));
00516     lp->opcode = IMM_PREEDIT_DRAW;
00517     lp->next = NULL;
00518     
00519     p = (IMPreeditDrawCallbackStruct *) & (lp->operand);
00520     p->text = NULL;         /* delete */
00521     p->chg_first = 0;
00522     p->chg_length = 0;             /* nothing will be changed */
00523     p->caret = caret;              /* only set caret position */
00524     
00525     return lp;
00526 }
00527 
00528 Private iml_inst *
00529 iml_make_preedit_erase_inst(
00530     iml_session_t * s
00531 )
00532 {
00533     IMPreeditDrawCallbackStruct *p;
00534     iml_inst *lp;
00535     
00536     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMPreeditDrawCallbackStruct));
00537     lp->opcode = IMM_PREEDIT_DRAW;
00538     lp->next = NULL;
00539     p = (IMPreeditDrawCallbackStruct *) & (lp->operand);
00540     p->chg_first = 0;
00541     p->text = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00542     
00543     p->text->encoding = UTF16_CODESET;
00544     p->text->text.utf_chars = NULL;
00545     p->text->char_length = 0;
00546     p->text->feedback = NULL;
00547     p->text->count_annotations = 0;
00548     p->text->annotations = NULL;
00549     
00550     p->chg_length = s->PreEditTextInfo.text->char_length;      /* previous length */
00551     s->PreEditTextInfo.text->char_length = 0;
00552     p->caret = 0;
00553     return lp;
00554 }
00555 
00556 Private iml_inst *
00557 iml_make_preedit_done_inst(
00558     iml_session_t * s
00559 )
00560 {
00561     iml_inst *lp;
00562     
00563     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00564     lp->opcode = IMM_PREEDIT_DONE;
00565     lp->next = NULL;
00566     lp->size_of_operand = 0;
00567     INACTIVATE_REGION(s, PREEDIT);
00568     return lp;
00569 }
00570 
00571 /*-----------------------------------------------------------------
00572  * Making instance for Status region drawing method
00573  *----------------------------------------------------------------*/
00574 Private iml_inst *
00575 iml_make_status_start_inst(
00576     iml_session_t * s
00577 )
00578 {
00579     iml_inst *lp;
00580     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00581     ACTIVATE_REGION(s, STATUS);
00582     lp->opcode = IMM_STATUS_START;
00583     lp->next = NULL;
00584     lp->size_of_operand = 0;
00585     return lp;
00586 }
00587 
00588 Private iml_inst *
00589 iml_make_status_draw_inst(
00590     iml_session_t * s,
00591     IMText * text
00592 )
00593 {
00594     int i, j;
00595     iml_inst *lp;
00596     IMStatusDrawCallbackStruct *q;
00597 
00598     if (text == NULL) {
00599         return iml_make_nop_inst(s);
00600     }
00601 
00602     if (text->encoding != UTF16_CODESET) {
00603         return iml_make_nop_inst(s);
00604     }
00605     
00606     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMStatusDrawCallbackStruct));
00607     
00608     lp->opcode = IMM_STATUS_DRAW;
00609     lp->next = NULL;
00610 
00611     q = (IMStatusDrawCallbackStruct *) & lp->operand;
00612     q->text = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00613     
00614     q->text->encoding = UTF16_CODESET;
00615     q->text->text.utf_chars = text->text.utf_chars;
00616     q->text->char_length = text->char_length;
00617     q->text->feedback = text->feedback;
00618     q->text->count_annotations = 0;
00619     q->text->annotations = NULL;
00620     
00621     /* copy feedback */
00622     for (i = 0; i < text->char_length; i++) {
00623         IMFeedbackList *fblfrom = &text->feedback[i];
00624         IMFeedbackList *fblto = &s->status_cache.text->feedback[i];
00625         int fcount = IM_FEEDBACK_COUNT(fblfrom);
00626        IM_FEEDBACK_COUNT(fblto) = IM_FEEDBACK_COUNT(fblfrom);
00627         for (j = 0; j < fcount; j++) {
00628             IMFeedback *fbfrom = &fblfrom->feedbacks[j];
00629             IMFeedback *fbto = &fblto->feedbacks[j];
00630            IM_FEEDBACK_TYPE(fbto) = IM_FEEDBACK_TYPE(fbfrom);
00631            IM_FEEDBACK_VALUE(fbto) = IM_FEEDBACK_VALUE(fbfrom);
00632         }
00633     }
00634     memcpy(s->status_cache.text->text.utf_chars,
00635           text->text.utf_chars,
00636           sizeof(UTFCHAR) * text->char_length);
00637     s->status_cache.text->char_length = text->char_length;
00638     
00639     return lp;
00640 }
00641 
00642 Private iml_inst *
00643 iml_make_status_done_inst(
00644     iml_session_t * s
00645 )
00646 {
00647     iml_inst *lp;
00648     
00649     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00650     lp->opcode = IMM_STATUS_DONE;
00651     lp->next = NULL;
00652     lp->size_of_operand = 0;
00653     INACTIVATE_REGION(s, STATUS);
00654     return lp;
00655 }
00656 
00657 /*-----------------------------------------------------------------
00658  * Making instance for Aux region drawing method
00659  *----------------------------------------------------------------*/
00660 Private iml_inst *
00661 iml_make_aux_start_inst(
00662     iml_session_t * s,
00663     IMAuxStartCallbackStruct * a
00664 )
00665 {
00666     iml_inst *lp = (iml_inst *) 0;
00667     IMAuxStartCallbackStruct *ls;
00668     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMAuxStartCallbackStruct));
00669     lp->opcode = IMM_AUX_START_2;
00670     lp->next = NULL;
00671     ls = (IMAuxStartCallbackStruct *) & lp->operand;
00672     ls->aux_name = (char *) a->aux_name;
00673     ls->aux_index = a->aux_index;
00674     return lp;
00675 }
00676 
00677 Private iml_inst *
00678 iml_make_aux_draw_inst(
00679     iml_session_t * s,
00680     IMAuxDrawCallbackStruct * a
00681 )
00682 {
00683     iml_inst *lp = (iml_inst *) 0;
00684     IMAuxDrawCallbackStruct *ls;
00685     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) +
00686                                    sizeof(IMAuxDrawCallbackStruct));
00687     lp->opcode = IMM_AUX_DRAW_2;
00688     lp->next = NULL;
00689     ls = (IMAuxDrawCallbackStruct *) & lp->operand;
00690     
00691     ls->aux_name = (char *) a->aux_name;
00692     ls->aux_index = a->aux_index;
00693     ls->count_integer_values = a->count_integer_values;
00694     ls->integer_values = a->integer_values;
00695     ls->count_string_values = a->count_string_values;
00696     ls->string_values = a->string_values;
00697 
00698     return lp;
00699 }
00700 
00701 Private iml_inst *
00702 iml_make_aux_done_inst(
00703     iml_session_t * s,
00704     IMAuxDoneCallbackStruct * a
00705 )
00706 {
00707     iml_inst *lp = (iml_inst *) 0;
00708     IMAuxDoneCallbackStruct *ls;
00709     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) +
00710                                    sizeof(IMAuxDoneCallbackStruct));
00711     lp->opcode = IMM_AUX_DONE_2;
00712     lp->next = NULL;
00713     ls = (IMAuxDoneCallbackStruct *) & lp->operand;
00714     
00715     ls->aux_name = (char *) a->aux_name;
00716     ls->aux_index = a->aux_index;
00717     
00718     return lp;
00719 }
00720 
00721 /*-----------------------------------------------------------------
00722  * Making instance for Lookup choice region drawing method
00723  *----------------------------------------------------------------*/
00724 
00725 Private iml_inst *
00726 iml_make_lookup_start_inst(
00727     iml_session_t * s,
00728     IMLookupStartCallbackStruct * start
00729 )
00730 {
00731     iml_inst *lp;
00732     IMLookupStartCallbackStruct *ls;
00733     if (start == NULL) {
00734         lp = iml_make_nop_inst(s);
00735         return lp;
00736     }
00737     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) +
00738                                    sizeof(IMLookupStartCallbackStruct));
00739     lp->opcode = IMM_LOOKUP_START | IMM_CB_RESULT_REQUIRED;
00740     lp->next = NULL;
00741     ACTIVATE_REGION(s, LOOKUP);
00742     ls = (IMLookupStartCallbackStruct *) & lp->operand;
00743     ls->event = NULL;
00744     ls->whoIsMaster = start->whoIsMaster;
00745     ls->IMPreference = start->IMPreference;
00746     ls->CBPreference = NULL;
00747     return lp;
00748 }
00749 
00750 Private iml_inst *
00751 iml_make_lookup_draw_inst(
00752     iml_session_t * s,
00753     IMLookupDrawCallbackStruct * draw
00754 )
00755 {
00756     iml_inst *lp;
00757     register IMLookupDrawCallbackStruct *ld;
00758     int i;
00759     
00760     if (draw == NULL) {
00761         return iml_make_nop_inst(s);
00762     }
00763     lp = (iml_inst *) s->If->m->iml_new(s,
00764                                    sizeof(iml_inst) + sizeof(IMLookupDrawCallbackStruct));
00765     lp->opcode = IMM_LOOKUP_DRAW;
00766     lp->next = NULL;
00767     ld = (IMLookupDrawCallbackStruct *) & lp->operand;
00768     
00769     ld->n_choices = draw->n_choices;
00770     ld->index_of_first_candidate = draw->index_of_first_candidate;
00771     ld->index_of_last_candidate = ld->n_choices - 1;
00772     ld->index_of_last_candidate = draw->index_of_last_candidate;
00773     ld->index_of_current_candidate = draw->index_of_current_candidate;
00774     ld->choices = (IMChoiceObject *) s->If->m->iml_new(s, ld->n_choices * sizeof(IMChoiceObject));
00775     ld->max_len = draw->max_len;
00776     ld->title = draw->title;
00777     
00778     for (i = 0; i < ld->n_choices; i++) {
00779         (ld->choices)[i].value = (draw->choices)[i].value;
00780         (ld->choices)[i].label = draw->choices[i].label;
00781     }
00782     
00783     return lp;
00784 }
00785 
00786 Private iml_inst *
00787 iml_make_lookup_done_inst(
00788     iml_session_t * s
00789 )
00790 {
00791     iml_inst *lp;
00792     
00793     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00794     lp->opcode = IMM_LOOKUP_DONE;
00795     lp->next = NULL;
00796     lp->size_of_operand = 0;
00797     INACTIVATE_REGION(s, LOOKUP);
00798     return lp;
00799 }
00800 
00801 Private iml_inst *
00802 iml_make_commit_inst(
00803     iml_session_t * s,
00804     IMText * text    /* byte committed string */
00805 )
00806 {
00807     iml_inst *rv;
00808     IMText *cs;
00809     
00810     if (!text || text->text.utf_chars == NULL || text->char_length <= 0) {
00811         return iml_make_nop_inst(s);
00812     }
00813 
00814     if(text->encoding != UTF16_CODESET){
00815         return iml_make_nop_inst(s);
00816     }
00817 
00818     if (text->char_length == 1 &&
00819        (text->text.utf_chars[0] < 0x20 || text->text.utf_chars[0] == 0x7f)) {
00820         IMKeyEventStruct *key = (IMKeyEventStruct *) s->If->m->iml_new(s, sizeof(IMKeyEventStruct));
00821         key->keyCode = text->text.utf_chars[0];
00822         key->keyChar = text->text.utf_chars[0];
00823         key->modifier = 0;
00824         key->time_stamp = 0;
00825         return iml_make_keypress_inst(s, key);
00826     }
00827     rv = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMText));
00828     rv->opcode = IMM_COMMIT;
00829     rv->next = NULL;
00830     rv->size_of_operand = sizeof(IMText);
00831     cs = (IMText *) & rv->operand;
00832     cs->encoding = UTF16_CODESET;
00833     cs->char_length = text->char_length;
00834     cs->text.utf_chars = text->text.utf_chars;
00835     cs->feedback = text->feedback;
00836     cs->count_annotations = text->count_annotations;
00837     cs->annotations = text->annotations;
00838 
00839     if (text->text.utf_chars[text->char_length - 1] < 0x20) {
00840         IMText *achar = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00841         achar->encoding = UTF16_CODESET;
00842         achar->char_length = 1;
00843         achar->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR));
00844         achar->text.utf_chars[0] = text->text.utf_chars[text->char_length - 1];
00845         achar->feedback = NULL;
00846         achar->count_annotations = 0;
00847         achar->annotations = NULL;
00848         cs->char_length--;
00849         rv->next = s->If->m->iml_make_commit_inst(s, achar);
00850     }
00851 
00852     return rv;
00853 }
00854 
00855 /*-----------------------------------------------------------------
00856  *  Making instance for another method
00857  *----------------------------------------------------------------*/
00858 
00859 Private iml_inst *
00860 iml_make_start_conversion_inst(
00861     iml_session_t * s
00862 )
00863 {
00864     iml_status_t *status;
00865     iml_inst *lp;
00866     s->public_status |= IMLSTATUS_Henkan_Mode;
00867     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(iml_status_t));
00868     lp->opcode = IMM_SET_STATUS;
00869     lp->next = NULL;
00870     status = (iml_status_t *) & (lp->operand);
00871     *status = s->public_status;
00872     return lp;
00873 }
00874 
00875 Private iml_inst *
00876 iml_make_end_conversion_inst(
00877     iml_session_t * s
00878 )
00879 {
00880     iml_status_t *status;
00881     iml_inst *lp;
00882     s->public_status &= ~IMLSTATUS_Henkan_Mode;
00883     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(iml_status_t));
00884     lp->opcode = IMM_SET_STATUS;
00885     lp->next = NULL;
00886     status = (iml_status_t *) & (lp->operand);
00887     *status = s->public_status;
00888     return lp;
00889 }
00890 
00891 /*-----------------------------------------------------------------
00892  *  keypress
00893  *----------------------------------------------------------------*/
00894 Private iml_inst *
00895 iml_make_keypress_inst(
00896     iml_session_t * s,
00897     IMKeyEventStruct * key
00898 )
00899 {
00900     iml_inst *rv;
00901     int sz = sizeof(IMKeyEventStruct) + 1;
00902     IMKeyEventStruct *kp;
00903     
00904     rv = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sz);
00905     rv->opcode = IMM_KEYPRESS;
00906     rv->next = NULL;
00907     rv->size_of_operand = sz;
00908     
00909     kp = (IMKeyEventStruct *) & rv->operand;
00910     
00911 #ifdef DEBUG
00912     printf("iml_make_keypress_inst() keycode=%x\n", key->keyCode);
00913 #endif
00914     
00915     kp->keyCode = key->keyCode;
00916     kp->keyChar = key->keyChar;
00917     kp->modifier = key->modifier;
00918     kp->time_stamp = key->time_stamp;
00919     
00920     return rv;
00921 }
00922 
00923 
00924 /*-----------------------------------------------------------------
00925  *  another convenient method
00926  *----------------------------------------------------------------*/
00927 
00928 Private iml_inst *
00929 iml_link_inst_tail(
00930     iml_inst ** rrv,
00931     iml_inst * lp
00932 )
00933 {
00934     register iml_inst *clp = *rrv;
00935     
00936     if (!(*rrv)) {
00937         *rrv = lp;
00938     } else {
00939         if (clp) {
00940             while (clp->next) {
00941                 clp = clp->next;
00942             }
00943             clp->next = lp;
00944         } else {
00945             clp = lp;
00946         }
00947     }
00948     return *rrv;
00949 }
00950 
00951 /*-----------------------------------------------------------------
00952  *  Private Use Only
00953  *----------------------------------------------------------------*/
00954 
00955 Private iml_inst *
00956 iml_make_nop_inst(
00957     iml_session_t * s
00958 )
00959 {
00960     iml_inst *lp;
00961     
00962     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst));
00963     lp->opcode = IMM_NOP;
00964     lp->next = NULL;
00965     lp->size_of_operand = 0;
00966     return lp;
00967 }
00968 
00969 /*-----------------------------------------------------------------
00970  *  Public sub routines
00971  *----------------------------------------------------------------*/
00972 
00973 Public iml_methods_t *
00974 _iml_dup_iml_methods()
00975 {
00976     iml_methods_t *m = (iml_methods_t *) malloc(sizeof(_iml_methods));
00977     memcpy(m, &_iml_methods, sizeof(_iml_methods));
00978     return m;
00979 }
00980 
00981 #define ALIGN16(p)          (((p) & 0x0f) ? (((p) & ~(0x0f)) + 0x10) : (p))
00982 #define MEM_BLOCK_SIZE             (128 * 1024)
00983 #define MEM_BLOCK_HEADER_SIZE      (ALIGN16(sizeof (iml_inst_mem_block_list_t)))
00984 #define MEM_BLOCK_MAX_SIZE  (MEM_BLOCK_SIZE - MEM_BLOCK_HEADER_SIZE)
00985 #define MEM_ELEM_HEADER_SIZE       (ALIGN16(sizeof (iml_inst_mem_elem_list_t)))
00986 
00987 struct _iml_inst_mem_block_list {
00988     /* memory block header */
00989     size_t size;
00990     size_t used;
00991     size_t rest;
00992     struct _iml_inst_mem_block_list *     next;
00993 
00994     /* memory block */
00995 };
00996 
00997 struct _iml_inst_mem_elem_list {
00998     /* memory header */
00999     struct _iml_inst_mem_elem_list *      next;
01000 
01001     /* memory */
01002 };
01003 
01004 Private void * slot_manager_alloc_small(iml_session_t * s, int size);
01005 Private void * slot_manager_alloc_mem_elem(iml_session_t * s, int size);
01006 Private void * slot_manager_alloc_mem_elem2(iml_session_t * s, int size);
01007 Private void * slot_manager_free(iml_session_t * s);
01008 Private void * slot_manager_free2(iml_session_t * s);
01009 
01010 Private void *
01011 iml_new(
01012     iml_session_t * s,
01013     int size
01014 )
01015 {
01016     size = ALIGN16(size);
01017     if (MEM_BLOCK_MAX_SIZE < size) {
01018        return slot_manager_alloc_mem_elem(s, size);
01019     } else {
01020        return slot_manager_alloc_small(s, size);
01021     }
01022 }
01023 
01024 Private void *
01025 iml_new2(
01026     iml_session_t * s,
01027     int size
01028 )
01029 {
01030     size = ALIGN16(size);
01031     return slot_manager_alloc_mem_elem2(s, size);
01032 }
01033 
01034 Private void *
01035 iml_delete(
01036     iml_session_t * s
01037 )
01038 {
01039     return slot_manager_free(s);
01040 }
01041 
01042 Public void *
01043 iml_delete2(
01044     iml_session_t * s
01045 )
01046 {
01047     return slot_manager_free2(s);
01048 }
01049 
01050 #ifdef sun
01051 mutex_t              memory_block_mutex;
01052 #elif  WIN32
01053 HANDLE        memory_block_mutex;
01054 #else  /* Linux */
01055 pthread_mutex_t      memory_block_mutex;
01056 #endif
01057 
01058 Public void
01059 sunim_slot_manager_init()
01060 {
01061 #ifdef sun
01062 #elif   WIN32
01063     if ((memory_block_mutex = CreateMutex(NULL, FALSE, NULL)) == 0) {
01064         printf("WIN32 Thread: CreateMutex() ERROR\n");
01065         return;
01066     }
01067 #else  /* Linux */
01068 #endif
01069 }
01070 
01071 static iml_inst_mem_block_list_t * memory_block_list;
01072 
01073 Private void *
01074 slot_manager_alloc_small(
01075     iml_session_t * s,
01076     int size
01077 )
01078 {
01079     iml_inst_mem_block_list_t * mbl;
01080     void * retp;
01081 
01082     mbl = s->mem_block_short_term_small;
01083     while (NULL != mbl) {
01084        if (size <= mbl->rest) {
01085            if (mbl->rest < 1024) {
01086               retp = 0;
01087            }
01088            retp = (((char *)mbl) + mbl->used);
01089 
01090            mbl->used += size;
01091            mbl->rest -= size;
01092 
01093            return retp;
01094        }
01095 
01096        mbl = mbl->next;
01097     }
01098 
01099     SUNIM_LOCK(memory_block_mutex);
01100 
01101     if (NULL == memory_block_list) {
01102        SUNIM_UNLOCK(memory_block_mutex);
01103 
01104        mbl = malloc(MEM_BLOCK_SIZE);
01105        if (NULL == mbl) {
01106            return NULL;
01107        }
01108     } else {
01109        mbl = memory_block_list;
01110        memory_block_list = mbl->next;
01111 
01112        SUNIM_UNLOCK(memory_block_mutex);
01113     }
01114 
01115     mbl->used = MEM_BLOCK_HEADER_SIZE;
01116     mbl->size = (MEM_BLOCK_SIZE - mbl->used);
01117     mbl->rest = (MEM_BLOCK_SIZE - mbl->used);
01118     mbl->next = s->mem_block_short_term_small;
01119     s->mem_block_short_term_small = mbl;
01120 
01121     return slot_manager_alloc_small(s, size);
01122 }
01123 
01124 Private void *
01125 slot_manager_alloc_mem_elem(
01126     iml_session_t * s,
01127     int size
01128 )
01129 {
01130     iml_inst_mem_elem_list_t * mel;
01131 
01132     size += MEM_ELEM_HEADER_SIZE;
01133 
01134     mel = malloc(size);
01135     if (NULL == mel) {
01136        return NULL;
01137     }
01138 
01139     mel->next = s->mem_elem_short_term;
01140     s->mem_elem_short_term = mel;
01141 
01142     return (((char *)mel) + MEM_ELEM_HEADER_SIZE);
01143 }
01144 
01145 Private void *
01146 slot_manager_alloc_mem_elem2(
01147     iml_session_t * s,
01148     int size
01149 )
01150 {
01151     iml_inst_mem_elem_list_t * mel;
01152 
01153     size += MEM_ELEM_HEADER_SIZE;
01154 
01155     mel = malloc(size);
01156     if (NULL == mel) {
01157        return NULL;
01158     }
01159 
01160     mel->next = s->mem_elem_long_term;
01161     s->mem_elem_long_term = mel;
01162 
01163     return (((char *)mel) + MEM_ELEM_HEADER_SIZE);
01164 }
01165 
01166 Private void *
01167 slot_manager_free(
01168     iml_session_t * s
01169 )
01170 {
01171     iml_inst_mem_block_list_t * mbl;
01172     iml_inst_mem_elem_list_t * mel;
01173     iml_inst_mem_elem_list_t * mel_n;
01174 
01175     mbl = s->mem_block_short_term_small;
01176     if (NULL != mbl) {
01177        while ((NULL != mbl->next)) {
01178            mbl = mbl->next;
01179        }
01180 
01181        SUNIM_LOCK(memory_block_mutex);
01182        mbl->next = memory_block_list;
01183        memory_block_list = s->mem_block_short_term_small;
01184        SUNIM_UNLOCK(memory_block_mutex);
01185 
01186        s->mem_block_short_term_small = NULL;
01187     }
01188 
01189     mel = s->mem_elem_short_term;
01190     while (NULL != mel) {
01191        mel_n = mel->next;
01192        free(mel);
01193        mel = mel_n;
01194     }
01195 
01196     s->mem_elem_short_term = NULL;
01197 
01198     return NULL;
01199 }
01200 
01201 Private void *
01202 slot_manager_free2(
01203     iml_session_t * s
01204 )
01205 {
01206     iml_inst_mem_elem_list_t * mel;
01207     iml_inst_mem_elem_list_t * mel_n;
01208 
01209     mel = s->mem_elem_long_term;
01210     while (NULL != mel) {
01211        mel_n = mel->next;
01212        free(mel);
01213        mel = mel_n;
01214     }
01215 
01216     s->mem_elem_long_term = NULL;
01217 
01218     return NULL;
01219 }
01220 
01221 Private void
01222 iml_ns_listener_ahead(
01223     iml_session_t * s, /* in */
01224     int ulid,          /* in */
01225     void *value        /* in */
01226 )
01227 {
01228     IMNSListenerStruct *nsl;
01229     iml_inst *lp;
01230     iml_nsl *p = (iml_nsl *)value ;
01231 
01232     lp = (iml_inst *) s->If->m->iml_new(s, sizeof(iml_inst) + sizeof(IMNSListenerStruct));
01233 
01234     lp->opcode = IMM_NS_LISTENER; lp->next = NULL; 
01235     nsl = (IMNSListenerStruct *) & (lp->operand); 
01236     nsl->self = nsl ; /* paranoia */
01237     nsl->listener_id = ulid;
01238     nsl->filename = secure_pathname(p->path_name);
01239     (iml_inst *) s->If->m->iml_execute(s, &lp);
01240     (iml_inst *) s->If->m->iml_delete(s);
01241 
01242 }
01243 
01244 Public int
01245 iml_add_listener(
01246     iml_session_t * s,  /* wanna be iml_desktop_t * 
01247                       * Since iml_desktop_t only carry session_list,
01248                       * it would be difficult to find the right session
01249                       * to execute as surrogate.....
01250                       */
01251     char *attribute,    /* in */
01252     void *listener,     /* in */
01253     void *value         /* in */
01254 )
01255 {
01256     int hotkeyconf;
01257     int unique_listener_id = 0;
01258 
01259     hotkeyconf = lookup_config_for_listener(attribute, value);
01260     if (hotkeyconf == NS_REMOTE) { 
01261       unique_listener_id = s->desktop->addListenerToDesktop (s, listener, value);
01262       iml_ns_listener_ahead(s, unique_listener_id, value); 
01263     }
01264     return unique_listener_id;
01265 }
01266 
01267 Public int
01268 iml_delete_listener(
01269     iml_session_t * s,    /* in */
01270     int listener_id       /* in */
01271 )
01272 {
01273     return listener_id;
01274 }
01275 
01276 Private int 
01277 lookup_config_for_listener(
01278     char *attr,
01279     void *value
01280 )
01281 {
01282     /* TODO!! This also needs to be modified the same way as NS based I/O APIs */
01283     return NS_REMOTE; 
01284 }
01285 
01286 /* Local Variables: */
01287 /* c-file-style: "iiim-project" */
01288 /* End: */