Back to index

im-sdk  12.3.91
iml.c
Go to the documentation of this file.
00001 /*
00002   Copyright 2002-2003 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 HAVE_CONFIG_H
00043 #include <config.h>
00044 #endif
00045 #ifdef HAVE_STDLIB_H
00046 #include <stdlib.h>
00047 #endif
00048 #ifdef HAVE_STRING_H
00049 #include <string.h>
00050 #endif
00051 
00052 #include "SunIM.h"
00053 #include "unit_input.h"
00054 
00055 /* general functions */
00056 IMFeedbackList *create_feedback(iml_session_t *s, int size)
00057 {
00058   int i;
00059   IMFeedbackList *feedback, *fbl;
00060     
00061   if (s) {
00062     feedback = (IMFeedbackList *) s->If->m->iml_new(s, sizeof(IMFeedbackList) * size);
00063     memset(feedback, 0, sizeof(IMFeedbackList) * size);
00064   } else {
00065     feedback = (IMFeedbackList *) calloc(1, sizeof(IMFeedbackList) * size);
00066   }
00067   for (i = 0; i < size; i++) {
00068     fbl = &feedback[i];
00069     fbl->count_feedbacks = 1;
00070     if (s) {
00071       fbl->feedbacks = (IMFeedback *) s->If->m->iml_new(s, sizeof(IMFeedback));
00072       memset(fbl->feedbacks, 0, sizeof(IMFeedback));
00073     } else {
00074       fbl->feedbacks = (IMFeedback *) calloc(1, sizeof(IMFeedback));
00075     }
00076   }
00077   return feedback;
00078 }
00079 
00080 void free_feedback(iml_session_t *s, IMFeedbackList *feedback, int size)
00081 {
00082   int i;
00083   IMFeedbackList *fbl;
00084 
00085   if ((s!= NULL) || (feedback == NULL)) return;
00086 
00087   for (i = 0; i < size; i++) {
00088     fbl = &feedback[i];
00089     if (fbl->feedbacks != NULL)
00090       free(fbl->feedbacks);
00091   }
00092   free(feedback);
00093 }
00094 
00095 int get_feedback(IMFeedbackList * fbl)
00096 {
00097   IMFeedback *fb = &fbl->feedbacks[0];
00098   return IM_FEEDBACK_VALUE(fb);
00099 }
00100 
00101 void set_feedback(IMFeedbackList * fbl, int value)
00102 {
00103   IMFeedback *fb = &fbl->feedbacks[0];
00104   IM_FEEDBACK_TYPE(fb)=IM_DECORATION_FEEDBACK;
00105   IM_FEEDBACK_VALUE(fb)=value;
00106 }
00107 
00108 void set_feedback_private(IMFeedbackList * fbl, int normalfeedback, int fg, int bg, int underline)
00109 {
00110   int count = 0;
00111   IMFeedback *fb;
00112        
00113   fb = &fbl->feedbacks[count];
00114   IM_FEEDBACK_TYPE(fb) = IM_DECORATION_FEEDBACK;
00115   IM_FEEDBACK_VALUE(fb) = normalfeedback;
00116   count++;
00117 
00118   if (fg != -1) {
00119     fb = &fbl->feedbacks[count];
00120     IM_FEEDBACK_TYPE(fb) = IM_FOREGROUND_RGB_FEEDBACK;
00121     IM_FEEDBACK_VALUE(fb) = fg;
00122     count++;
00123   }
00124   if (bg != -1) {
00125     fb = &fbl->feedbacks[count];
00126     IM_FEEDBACK_TYPE(fb) = IM_BACKGROUND_RGB_FEEDBACK;
00127     IM_FEEDBACK_VALUE(fb) = bg;
00128     count++;
00129   }
00130   if (underline != -1) {
00131     fb = &fbl->feedbacks[count];
00132     IM_FEEDBACK_TYPE(fb) = IM_UNDERLINE_RGB_FEEDBACK;
00133     IM_FEEDBACK_VALUE(fb) = underline;
00134     count++;
00135   }
00136   IM_FEEDBACK_COUNT(fbl) = count;
00137 }
00138 
00139 /* UTF16 string handle functions */
00140 int UTFCHARCat(UTFCHAR *dest, UTFCHAR *str1, UTFCHAR *str2)
00141 {
00142   int i;
00143   for (i = 0; *str1; i++) {
00144     *dest++ = *str1++;
00145   }
00146   for (i = 0; *str2; i++) {
00147     *dest++ = *str2++;
00148   }
00149   *dest = 0;
00150   return i;
00151 }
00152 
00153 int UTFCHARCpy(UTFCHAR * dest, UTFCHAR * original)
00154 {
00155   int i;
00156   for (i = 0; *original; i++) {
00157     *dest++ = *original++;
00158   }
00159   *dest = 0;
00160   return i;
00161 }
00162 
00163 int UTFCHARLen(UTFCHAR * p)
00164 {
00165   int i;
00166   for (i = 0; *p; i++)
00167     p++;
00168   return i;
00169 }
00170 
00171 IMText *make_imtext(iml_session_t * s, UTFCHAR * p)
00172 {
00173   int i, len;
00174   IMText *text = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00175 
00176   memset(text, 0, sizeof(IMText));
00177 
00178   len = UTFCHARLen(p);
00179 
00180   text->encoding = UTF16_CODESET;
00181 
00182   text->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * (len + 1));
00183   UTFCHARCpy(text->text.utf_chars, p);
00184   /*
00185 
00186   Notes:  Can not use memcpy to copy UTFCHAR data. 
00187 
00188   log_f("before memcpy: len:%d\n", len);
00189   memcpy(text->text.utf_chars, p, sizeof(UTFCHAR) * len);
00190   log_f("After memcpy: len:%d\n", len);
00191   */
00192   text->char_length = len;
00193 
00194   text->feedback = create_feedback(s, len);
00195 
00196   for (i = 0; i < len; i++) {
00197     set_feedback_private(&text->feedback[i], IMReverse, -1, -1, -1);
00198   }
00199 
00200   return text;
00201 }
00202 
00203 /* Send a Unicode string to the system */
00204 void iml_commit(iml_session_t * s, UTFCHAR *commit_buf)
00205 {
00206   int len;
00207   iml_inst *lp;
00208   IMText *im_text;
00209     
00210   len = UTFCHARLen(commit_buf);
00211   if (len == 0) return;
00212 
00213   im_text = make_imtext(s, commit_buf);
00214   lp = (iml_inst *)s->If->m->iml_make_commit_inst(s, im_text);
00215   s->If->m->iml_execute(s, &lp);
00216 }
00217 
00218 /* Send a KeyPress Event to system */
00219 void iml_sendback_key(iml_session_t *s, IMKeyEventStruct *key)
00220 {
00221   iml_inst *lp;
00222 
00223   lp = (iml_inst *)s->If->m->iml_make_keypress_inst(s, key);
00224   s->If->m->iml_execute(s, &lp);
00225 }
00226 
00227 /* Begin catch the system Key Event */
00228 void iml_conversion_on(iml_session_t * s)
00229 {
00230   iml_inst *lp;
00231     
00232   lp = (iml_inst *)s->If->m->iml_make_start_conversion_inst(s);
00233   lp = s->If->m->iml_execute(s, &lp);
00234 }
00235 
00236 /* Do not catch the system Key Event */
00237 void iml_conversion_off(iml_session_t * s)
00238 {
00239   iml_inst *lp;
00240   iml_inst *rrv = NULL;
00241     
00242   lp = (iml_inst *)s->If->m->iml_make_preedit_done_inst(s);
00243   s->If->m->iml_link_inst_tail(&rrv, lp);
00244   lp = (iml_inst *)s->If->m->iml_make_end_conversion_inst(s);
00245   s->If->m->iml_link_inst_tail(&rrv, lp);
00246   s->If->m->iml_execute(s, &rrv);
00247 }
00248 
00249 /* Start Status Area Information */
00250 void iml_status_start(iml_session_t * s)
00251 {
00252   iml_inst *lp;
00253     
00254   lp = (iml_inst *)s->If->m->iml_make_status_start_inst(s);
00255   s->If->m->iml_execute (s, &lp);
00256 }
00257 
00258 /* Destroy Status Area Information */
00259 void iml_status_enddraw(iml_session_t * s)
00260 {
00261   iml_inst *lp;
00262     
00263   lp = (iml_inst *)s->If->m->iml_make_status_done_inst(s);
00264   s->If->m->iml_execute(s, &lp);
00265 }
00266 
00267 /* Draw Status line information */
00268 void iml_status_draw(iml_session_t * s, UTFCHAR *status_str)
00269 {
00270   iml_inst *lp;
00271   iml_inst *rrv = NULL;
00272   IMText  *im_text;
00273 
00274   iml_status_start(s);
00275 
00276   im_text = make_imtext(s, status_str);
00277   lp = (iml_inst *)s->If->m->iml_make_status_draw_inst(s, im_text);
00278   s->If->m->iml_link_inst_tail(&rrv, lp);
00279   s->If->m->iml_execute(s, &rrv);
00280 }
00281 
00282 void iml_preedit_start(iml_session_t * s)
00283 {
00284   iml_inst *lp;
00285   iml_inst *rrv = NULL;
00286     
00287   lp = (iml_inst *)s->If->m->iml_make_preedit_start_inst(s);
00288   s->If->m->iml_link_inst_tail(&rrv, lp);
00289 }
00290 
00291 /* Destroy Pre_edit Area Information */
00292 void iml_preedit_enddraw(iml_session_t * s)
00293 {
00294   iml_inst *lp;
00295     
00296   lp = (iml_inst *)s->If->m->iml_make_preedit_erase_inst(s);
00297   s->If->m->iml_execute(s, &lp);
00298 }
00299 
00300 /* Draw Pre_edit Area Information */
00301 void iml_preedit_draw(iml_session_t * s, UTFCHAR *preedit_buf, int caret_pos)
00302 {
00303   int i, len;
00304   iml_inst *lp;
00305   iml_inst *rrv = NULL;
00306   IMText *im_text;
00307     
00308   iml_preedit_start(s);
00309 
00310   len = UTFCHARLen(preedit_buf);
00311   log_f("len:%d, caret_pos:%d\n", len, caret_pos);
00312 
00313   if(len == 0) {
00314     lp = (iml_inst *)s->If->m->iml_make_preedit_erase_inst(s);
00315     s->If->m->iml_link_inst_tail(&rrv, lp);
00316     s->If->m->iml_execute(s, &rrv);
00317     return;
00318   }
00319 
00320   im_text = make_imtext(s, preedit_buf);
00321 
00322   if (caret_pos>len) caret_pos = len;
00323   for(i = 0; i < caret_pos; i ++) {
00324     set_feedback(&(im_text->feedback[i]), IMReverse);
00325   }
00326   for(i = caret_pos; i < len; i ++) {
00327     set_feedback(&(im_text->feedback[i]), IMUnderline);
00328   }
00329   /*
00330     set_feedback(&(im_text->feedback[caret_pos - 1]), IMNormal);
00331   */
00332 
00333   lp = (iml_inst *)s->If->m->iml_make_preedit_draw_inst(s, im_text);
00334   s->If->m->iml_link_inst_tail(&rrv, lp);
00335     
00336   if(caret_pos != -1) {
00337     lp = (iml_inst *)s->If->m->iml_make_preedit_caret_inst(s, caret_pos); 
00338     s->If->m->iml_link_inst_tail(&rrv, lp);
00339   }
00340   s->If->m->iml_execute(s, &rrv);
00341 }
00342 
00343 void iml_lookup_start(iml_session_t * s)
00344 {
00345   iml_inst *lp;
00346   IMLookupStartCallbackStruct *start;
00347     
00348   start = (IMLookupStartCallbackStruct *) s->If->m->iml_new(s, sizeof(IMLookupStartCallbackStruct));
00349   memset(start, 0, sizeof(IMLookupStartCallbackStruct));
00350 
00351   start->IMPreference = (LayoutInfo *) s->If->m->iml_new(s, sizeof(LayoutInfo));
00352   memset(start->IMPreference, 0, sizeof(LayoutInfo));
00353 
00354   start->IMPreference->choice_per_window = 7;
00355   start->IMPreference->ncolumns = 1;
00356   start->IMPreference->nrows = 10;
00357   start->IMPreference->drawUpDirection = DrawUpHorizontally;
00358   start->IMPreference->whoOwnsLabel = IMOwnsLabel;
00359 
00360   start->CBPreference = NULL;
00361   start->whoIsMaster = IMIsMaster;
00362 
00363   lp = (iml_inst *)s->If->m->iml_make_lookup_start_inst(s, start);
00364   s->If->m->iml_execute(s, &lp);
00365 }
00366 
00367 /* Destroy Candidate Selection Area */
00368 void iml_lookup_enddraw(iml_session_t *s)
00369 {
00370   iml_inst *lp;
00371 
00372   lp = (iml_inst*)s->If->m->iml_make_lookup_done_inst(s);
00373   s->If->m->iml_execute(s, &lp);
00374 }
00375 
00376 /* Draw Candidate Selection Area */
00377 void iml_lookup_draw(iml_session_t * s, UTFCHAR ** luc_tmp, int luc_num, int label_type)
00378 {
00379   int i, char_len;
00380   char begin_char;
00381   int max_len = 0;
00382   iml_inst *lp;
00383   IMText **candidates, **labels;
00384   IMLookupDrawCallbackStruct *draw;
00385     
00386   if (luc_num <= 0) return;
00387 
00388   iml_lookup_start(s);
00389 
00390   if (luc_num > MAX_CANDIDATES_NUM) 
00391     luc_num = MAX_CANDIDATES_NUM;
00392 
00393   /* Set candidate data */
00394   candidates = (IMText **) s->If->m->iml_new(s, luc_num * sizeof(IMText *));
00395   memset(candidates, 0, luc_num * sizeof(IMText *));
00396   for (i = 0; i < luc_num; i++) {
00397     candidates[i] = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00398     memset(candidates[i], 0, sizeof(IMText));
00399     candidates[i]->encoding = UTF16_CODESET;
00400     candidates[i]->count_annotations = 0;
00401     candidates[i]->annotations = NULL;
00402     char_len = UTFCHARLen(luc_tmp[i]);
00403     candidates[i]->char_length = char_len;
00404     candidates[i]->text.utf_chars = (UTFCHAR *)s->If->m->iml_new(s, sizeof(UTFCHAR) * char_len);
00405     UTFCHARCpy(candidates[i]->text.utf_chars, luc_tmp[i]);
00406     /*
00407       memcpy(candidates[i]->text.utf_chars, luc_tmp[i], sizeof(UTFCHAR) * char_len);
00408     */
00409     candidates[i]->feedback = create_feedback(s, char_len);
00410   }
00411 
00412   /* Set Label data */
00413   switch(label_type) {
00414   case NUMERIC_LABEL:
00415     begin_char = '1';
00416     break;
00417   case LOWER_LABEL:
00418     begin_char = 'a';
00419     break;
00420   case UPPER_LABEL:
00421     begin_char = 'A';
00422     break;
00423   default:
00424     begin_char = '1';
00425   }
00426 
00427   labels = (IMText **) s->If->m->iml_new(s, luc_num  * sizeof(IMText *));
00428   memset(labels, 0, luc_num * sizeof(IMText *));
00429   for (i = 0; i < luc_num; i++) {
00430     labels[i] = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00431     memset(labels[i], 0, sizeof(IMText));
00432     labels[i]->encoding = UTF16_CODESET;
00433     labels[i]->count_annotations = 0;
00434     labels[i]->annotations = NULL;
00435     char_len = 2;
00436     labels[i]->char_length = char_len;
00437     labels[i]->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, sizeof(UTFCHAR) * char_len);
00438     labels[i]->text.utf_chars[0] = (UTFCHAR) (begin_char + i);
00439     labels[i]->text.utf_chars[1] = (UTFCHAR) ('.');
00440     labels[i]->feedback = create_feedback(s, char_len);
00441   }
00442 
00443   draw = (IMLookupDrawCallbackStruct *) s->If->m->iml_new(s, sizeof(IMLookupDrawCallbackStruct));
00444   memset(draw, 0, sizeof(IMLookupDrawCallbackStruct));
00445 
00446   draw->title = (IMText *) s->If->m->iml_new(s, sizeof(IMText));
00447   memset(draw->title, 0, sizeof(IMText));
00448  
00449   draw->n_choices = luc_num ;
00450   draw->index_of_first_candidate = 0;
00451   draw->index_of_last_candidate = luc_num - 1;
00452   draw->index_of_current_candidate = -1;
00453     
00454   /* Set choices data */
00455   draw->choices = (IMChoiceObject *) s->If->m->iml_new(s, luc_num * sizeof(IMChoiceObject));
00456   memset(draw->choices, 0, luc_num * sizeof(IMChoiceObject));
00457     
00458   for (i = 0; i < luc_num; i++) {
00459     IMText *vt;             /* for value */
00460     IMText *lt;             /* for label */
00461 
00462     vt = draw->choices[i].value = candidates[i];
00463     lt = draw->choices[i].label = labels[i];
00464         
00465     if (max_len < vt->char_length)
00466       max_len = vt->char_length;
00467   }
00468 
00469   draw->max_len = max_len;
00470     
00471   lp = (iml_inst *)s->If->m->iml_make_lookup_draw_inst(s, draw);
00472   s->If->m->iml_execute(s, &lp);
00473 }
00474 
00475 /* Start An Auxiliary Window */
00476 void iml_aux_start(iml_session_t * s, char *classname)
00477 {
00478   iml_inst *lp;
00479   IMAuxStartCallbackStruct *aux;
00480 
00481   aux = (IMAuxStartCallbackStruct *) s->If->m->iml_new(s, sizeof(IMAuxStartCallbackStruct));
00482   memset(aux, 0, sizeof(IMAuxStartCallbackStruct));
00483   aux->aux_name = classname;
00484 
00485   lp = (iml_inst *)s->If->m->iml_make_aux_start_inst(s, aux);
00486   s->If->m->iml_execute(s, &lp);
00487 
00488   log_f("iml_aux_start ----- auxwin name :%s \n", classname);
00489 }
00490 
00491 /* Close the Auxiliary Window */
00492 void iml_aux_done(iml_session_t * s, char *classname)
00493 {
00494   iml_inst *lp;
00495   IMAuxDoneCallbackStruct *aux;
00496 
00497   aux = (IMAuxDoneCallbackStruct *)s->If->m->iml_new(s, sizeof(IMAuxDoneCallbackStruct));
00498   memset(aux, 0, sizeof(IMAuxDoneCallbackStruct));
00499   aux->aux_name = classname;
00500 
00501   lp = (iml_inst *)s->If->m->iml_make_aux_done_inst(s, aux);
00502   s->If->m->iml_execute(s, &lp);
00503 
00504   log_f("iml_aux_done -------------------------------- end \n");
00505 }
00506 
00507 /* Draw the Auxiliary Window Items */
00508 void iml_aux_draw(iml_session_t *s, char *classname, 
00509                 int count_integers,  int *integers,
00510                 int count_strings,   int *len_strings,
00511                   unsigned char **strings)
00512 {
00513   iml_inst *lp;
00514   IMText *lt;
00515   IMAuxDrawCallbackStruct *aux;
00516   int i, len;
00517 
00518   aux = (IMAuxDrawCallbackStruct *) s->If->m->iml_new(s, sizeof(IMAuxDrawCallbackStruct));
00519   memset(aux, 0, sizeof(IMAuxDrawCallbackStruct));
00520   aux->aux_name = classname;
00521 
00522   aux->count_integer_values = count_integers;
00523   if (count_integers) {
00524     aux->integer_values = (int *) s->If->m->iml_new(s, sizeof(int) * count_integers);
00525     memset(aux->integer_values, 0, sizeof(int) * count_integers);
00526 
00527     for (i = 0; i < count_integers; i++) {
00528       aux->integer_values[i] = integers[i];
00529     }
00530   }
00531 
00532   aux->count_string_values = count_strings;
00533   if (count_strings) {
00534     aux->string_values = (IMText *) s->If->m->iml_new(s, sizeof(IMText) * count_strings);
00535     memset(aux->string_values, 0, sizeof(IMText) * count_strings);
00536 
00537     aux->string_values->encoding = UTF16_CODESET;
00538     for (i = 0, lt = aux->string_values; i < count_strings; i++, lt++) {
00539       len = len_strings[i];
00540       lt->text.utf_chars = (UTFCHAR *) s->If->m->iml_new(s, len+1);
00541       lt->char_length = len;
00542       memcpy(lt->text.utf_chars, strings[i], len);
00543     }
00544   }
00545 
00546   lp = (iml_inst *)s->If->m->iml_make_aux_draw_inst(s, aux);
00547   s->If->m->iml_execute(s, &lp);
00548 
00549   log_f("iml_aux_draw -------------------------------- end \n");
00550 }
00551 
00552