Back to index

im-sdk  12.3.91
le_session.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 
00003 #include "le_info.h"
00004 #include "le_session.h"
00005 #include "le_desktop.h"
00006 
00007 void le_session_ui_callbacks(MInputContext *ic, MSymbol command);
00008 
00009 LeDesktopContextRec *le_session_get_desktop_context(iml_session_t * s);
00010 LeSessionContextRec *le_session_get_session_context(iml_session_t * s);
00011 
00012 extern LeInfoRec *le_info;
00013 
00014 /*****************************************
00015       LeSessionContextRec
00016 *****************************************/
00017 LeSessionContextRec *le_session_context_new()
00018 {
00019     LeSessionContextRec *le_session_context = NULL;
00020 
00021     le_session_context =
00022        (LeSessionContextRec *) calloc(1, sizeof(LeSessionContextRec));
00023     if (le_session_context == NULL)
00024        return NULL;
00025 
00026     le_session_context->current_conversion_status = CONVERSION_OFF;
00027     le_session_context->ic = NULL;
00028     le_session_context->locale = NULL;
00029 
00030     return le_session_context;
00031 }
00032 
00033 LeResult le_session_context_destroy(LeSessionContextRec *
00034                                 le_session_context)
00035 {
00036     if (le_session_context == NULL)
00037        return LE_FAIL;
00038 
00039     if (le_session_context->locale)
00040         free((char *) le_session_context->locale);
00041 
00042     if (le_session_context->ic)
00043         minput_destroy_ic(le_session_context->ic);
00044 
00045     free((char *) le_session_context);
00046 
00047     return LE_OK;
00048 }
00049 
00050 LeResult le_session_context_print(LeSessionContextRec * le_session_context)
00051 {
00052     if (le_session_context == NULL)
00053        return LE_FAIL;
00054 
00055     return LE_OK;
00056 }
00057 
00058 LeResult le_session_context_push_into_m17n_ic(MInputContext *ic,
00059                         LeSessionContextRec *le_session_context)
00060 {
00061     if (ic == (MInputContext *)Mnil)
00062         return LE_FAIL;
00063 
00064     mplist_push (ic->plist, le_info->Miiim_ic, le_session_context);
00065     return LE_OK;
00066 }
00067 
00068 LeSessionContextRec *le_session_context_get_from_m17n_ic(MInputContext *ic)
00069 {
00070     LeSessionContextRec *le_session_context;
00071     MPlist *plist;
00072 
00073     if (ic == (MInputContext *)Mnil)
00074         return NULL;
00075 
00076     for (plist = ic->plist; plist && mplist_key (plist) != Mnil;
00077          plist = mplist_next (plist)) {
00078         if (mplist_key (plist) != le_info->Miiim_ic)
00079             continue;
00080         le_session_context = mplist_value (plist);
00081         if (le_session_context && le_session_context->ic == ic)
00082           return le_session_context;
00083     }
00084     return NULL;
00085 }
00086 
00087 /*****************************************
00088       LE Session for iml_session_t
00089 *****************************************/
00090 LeResult le_session_create(iml_session_t * s)
00091 {
00092     LeSessionContextRec *le_session_context;
00093 
00094     le_session_context = (LeSessionContextRec *) le_session_context_new();
00095     if (le_session_context == NULL)
00096        return LE_FAIL;
00097 
00098     le_session_context->s = s;
00099 
00100     s->specific_data = (void *) le_session_context;
00101 
00102     return LE_OK;
00103 }
00104 
00105 LeResult le_session_destroy(iml_session_t * s)
00106 {
00107     DEBUG_printf("le_session_destroy: s: 0x%x\n", s);
00108 
00109     LeSessionContextRec *le_session_context =
00110        le_session_get_session_context(s);
00111 
00112     if (le_session_context != NULL) {
00113        le_session_context_destroy(le_session_context);
00114     }
00115 
00116     s->specific_data = NULL;
00117 
00118     return LE_OK;
00119 }
00120 
00121 LeResult le_session_set_locale(iml_session_t * s, char *locale)
00122 {
00123     LeResult result;
00124     LeSessionContextRec *le_session_context;
00125 
00126     MInputMethod *im;
00127     MInputContext *ic;
00128 
00129     DEBUG_printf("le_session_set_locale: locale: %s\n", locale);
00130     if (locale == NULL)
00131         return LE_FAIL;
00132 
00133     le_session_context = le_session_get_session_context(s);
00134     if (le_session_context == NULL) 
00135         return LE_FAIL;
00136 
00137     ic = le_session_context->ic;
00138     if (ic) minput_destroy_ic(ic);
00139     le_session_context->ic = (MInputContext *)Mnil;
00140 
00141     if (le_session_context->locale != NULL)
00142         free((char *) le_session_context->locale);
00143     le_session_context->locale = (char *)strdup(locale);
00144 
00145     im = (MInputMethod *)le_info_get_input_method_for_locale(le_info, locale);
00146     if (im == (MInputMethod *)Mnil)
00147         return LE_FAIL;
00148 
00149     DEBUG_printf("minput_create_ic: im: %p\n", im);
00150     ic = minput_create_ic(im, NULL);
00151     if (ic == (MInputContext *)Mnil)
00152         return LE_FAIL;
00153 
00154     le_session_context->im = (MInputMethod *)im;
00155     le_session_context->ic = (MInputContext *)ic;
00156 
00157     DEBUG_printf("mplist_push: ic: %p,  le_session_context: %p\n",
00158                   ic, le_session_context);
00159     result = le_session_context_push_into_m17n_ic(ic, le_session_context);
00160 
00161     return result;
00162 }
00163 
00164 LeResult le_session_switch_to_next_input_method(iml_session_t * s)
00165 {
00166     LeResult result;
00167     LeSessionContextRec *le_session_context;
00168 
00169     MInputMethod *im;
00170     MInputContext *ic;
00171 
00172     char *locale;
00173 
00174     DEBUG_printf("le_session_switch_to_next_input_method \n");
00175     le_session_context = le_session_get_session_context(s);
00176     if (le_session_context == NULL) 
00177         return LE_FAIL;
00178 
00179     locale = le_session_context->locale;
00180     if (locale == NULL)
00181         return LE_FAIL;
00182 
00183     im = le_session_context->im;
00184     im = (MInputMethod *)le_info_get_next_input_method_for_locale(le_info, locale, im);
00185     if (im == (MInputMethod *)Mnil)
00186         return LE_FAIL;
00187 
00188     ic = le_session_context->ic;
00189     if (ic)  minput_destroy_ic(ic);
00190     le_session_context->ic = (MInputContext *)Mnil;
00191 
00192     ic = minput_create_ic(im, NULL);
00193     if (ic == (MInputContext *)Mnil)
00194         return LE_FAIL;
00195 
00196     le_session_context->im = (MInputMethod *)im;
00197     le_session_context->ic = (MInputContext *)ic;
00198 
00199     DEBUG_printf("mplist_push: ic: %p,  le_session_context: %p\n",
00200                   ic, le_session_context);
00201     result = le_session_context_push_into_m17n_ic(ic, le_session_context);
00202 
00203     le_session_ui_callbacks(ic, Minput_status_draw);
00204 
00205     return result;
00206 }
00207 
00208 LeResult le_session_set_focus_in(iml_session_t * s)
00209 {
00210     LeSessionContextRec *le_session_context;
00211     MInputContext *ic;
00212 
00213     le_session_context = le_session_get_session_context(s);
00214     if (le_session_context == NULL) 
00215         return LE_FAIL;
00216 
00217     ic = le_session_context->ic;
00218 
00219     le_session_ui_callbacks(ic, Minput_preedit_draw);
00220     le_session_ui_callbacks(ic, Minput_status_draw);
00221     le_session_ui_callbacks(ic, Minput_candidates_draw);
00222 }
00223 
00224 LeResult le_session_set_focus_out(iml_session_t * s)
00225 {
00226     LeSessionContextRec *le_session_context;
00227     MInputContext *ic;
00228 
00229     le_session_context = le_session_get_session_context(s);
00230     if (le_session_context == NULL) 
00231         return LE_FAIL;
00232 
00233     ic = le_session_context->ic;
00234 
00235     le_session_ui_callbacks(ic, Minput_preedit_done);
00236     le_session_ui_callbacks(ic, Minput_status_done);
00237     le_session_ui_callbacks(ic, Minput_candidates_done);
00238 }
00239 
00240 IMText *le_session_reset(iml_session_t * s)
00241 {
00242     return ((IMText *) NULL);
00243 }
00244 
00245 /*****************************************
00246       LE Session Functions for iml_session_t
00247 *****************************************/
00248 LeDesktopContextRec *le_session_get_desktop_context(iml_session_t * s)
00249 {
00250     return ((LeDesktopContextRec *) s->desktop->specific_data);
00251 }
00252 
00253 LeSessionContextRec *le_session_get_session_context(iml_session_t * s)
00254 {
00255     return ((LeSessionContextRec *) s->specific_data);
00256 }
00257 
00258 ConversionStatus le_session_get_conversion_status(iml_session_t * s)
00259 {
00260     LeSessionContextRec *le_session_context = NULL;
00261 
00262     le_session_context = le_session_get_session_context(s);
00263     if (le_session_context == NULL)
00264        return CONVERSION_OFF;
00265 
00266     return (le_session_context->current_conversion_status);
00267 }
00268 
00269 LeResult le_session_set_conversion_status(iml_session_t * s,
00270                                      ConversionStatus
00271                                      conversion_status)
00272 {
00273     MInputContext *ic;
00274 
00275     LeSessionContextRec *le_session_context;
00276     le_session_context = le_session_get_session_context(s);
00277 
00278     if (le_session_context == NULL)
00279         return;
00280 
00281     ic = le_session_context->ic;
00282 
00283     if (conversion_status == CONVERSION_OFF) {
00284        le_iml_conversion_off(s);
00285 
00286        le_session_ui_callbacks(ic, Minput_preedit_done);
00287        le_session_ui_callbacks(ic, Minput_status_done);
00288        le_session_ui_callbacks(ic, Minput_candidates_done);
00289     } else {
00290        le_iml_conversion_on(s);
00291 
00292        le_session_ui_callbacks(ic, Minput_preedit_draw);
00293        le_session_ui_callbacks(ic, Minput_status_draw);
00294        le_session_ui_callbacks(ic, Minput_candidates_draw);
00295     }
00296 
00297     return LE_OK;
00298 }
00299 
00300 LeResult le_session_toggle_conversion_status(iml_session_t * s)
00301 {
00302     LeSessionContextRec *le_session_context;
00303     ConversionStatus conversion_status;
00304     LeResult result;
00305 
00306     le_session_context = le_session_get_session_context(s);
00307     if (le_session_context == NULL)
00308        return LE_FAIL;
00309 
00310     conversion_status = le_session_context->current_conversion_status;
00311     DEBUG_printf("le_session_toggle_conversion_status: %d\n",
00312                ~conversion_status);
00313     if (conversion_status == CONVERSION_OFF) {
00314        result = le_session_set_conversion_status(s, CONVERSION_ON);
00315     } else {
00316        result = le_session_set_conversion_status(s, CONVERSION_OFF);
00317     }
00318 
00319     return result;
00320 }
00321 
00322 LeResult le_session_set_as_desktop_current_session(iml_session_t * s)
00323 {
00324     LeDesktopContextRec *le_desktop_context = NULL;
00325 
00326     le_desktop_context =
00327        (LeDesktopContextRec *) le_session_get_desktop_context(s);
00328     le_desktop_context_set_current_session(le_desktop_context, s);
00329 
00330     return LE_OK;
00331 }
00332 
00333 
00334 /*****************************************
00335       candidatas_info utilities
00336 *****************************************/
00337 typedef struct {
00338     int num_candidates;
00339     UTFCHAR **labels;
00340     UTFCHAR **candidates;
00341 } candidates_info_t;
00342 
00343 candidates_info_t *candidates_info_new()
00344 {
00345     candidates_info_t *candidates_info = NULL;
00346 
00347     candidates_info = (candidates_info_t *) calloc(1, sizeof(candidates_info_t));
00348 
00349     return candidates_info;
00350 
00351 }
00352 
00353 void candidates_info_destroy(candidates_info_t * candidates_info)
00354 {
00355     int i;
00356 
00357     if (candidates_info == NULL || candidates_info->candidates == NULL)
00358         return;
00359 
00360     for (i = 0; i < candidates_info->num_candidates; i++) {
00361          if (candidates_info->labels[i])
00362              free ((char *)candidates_info->labels[i]);
00363 
00364          if (candidates_info->candidates[i])
00365              free ((char *)candidates_info->candidates[i]);
00366     }
00367 
00368     free ((char *)candidates_info->candidates);
00369 
00370     return;
00371 }
00372 
00373 #define CANDIDATES_NUM_ALLOC   6
00374 int candidates_info_pushback_candidate(candidates_info_t *candidates_info, UTFCHAR *candidate)
00375 {
00376     int i, num_candidates;
00377     UTFCHAR *candidate_temp;
00378     UTFCHAR *label_temp;
00379 
00380     DEBUG_printf("candidates_info_pushback_candidate ==\n");
00381     if (candidates_info == NULL || candidate == NULL)
00382         return 0;
00383 
00384     if (candidates_info->labels == NULL) {
00385         candidates_info->labels = (UTFCHAR **)calloc (CANDIDATES_NUM_ALLOC,
00386                                                       sizeof(UTFCHAR *));
00387         if (candidates_info->labels == NULL)
00388             return 0;
00389     }
00390 
00391     if (candidates_info->candidates == NULL) {
00392         candidates_info->candidates = (UTFCHAR **)calloc (CANDIDATES_NUM_ALLOC,
00393                                                           sizeof(UTFCHAR *));
00394         if (candidates_info->candidates == NULL)
00395             return 0;
00396     }
00397 
00398     num_candidates = candidates_info->num_candidates;
00399     if ((num_candidates + 1) % CANDIDATES_NUM_ALLOC == 0) {
00400         int num = num_candidates + 1 + CANDIDATES_NUM_ALLOC;
00401 
00402         candidates_info->labels = (UTFCHAR **)realloc(candidates_info->labels,
00403                                                       num * sizeof(UTFCHAR *));
00404         if (candidates_info->labels == NULL)
00405             return 0;
00406 
00407         candidates_info->candidates = (UTFCHAR **)realloc(candidates_info->candidates,
00408                                                           num * sizeof(UTFCHAR *));
00409         if (candidates_info->candidates == NULL)
00410             return 0;
00411 
00412         for (i = num_candidates; i < num; i++) {
00413             candidates_info->labels[i] = NULL;
00414             candidates_info->candidates[i] = NULL;
00415         }
00416     }
00417 
00418     DEBUG_printf("candidate: len: %d\n", UTFCHARLen(candidate));
00419     candidate_temp = (UTFCHAR *) calloc (UTFCHARLen(candidate) + 1, sizeof (UTFCHAR));
00420     if (candidate_temp == NULL)
00421         return 0;
00422 
00423     label_temp = (UTFCHAR *) calloc (2, sizeof (UTFCHAR));
00424     if (label_temp == NULL)
00425         return 0;
00426 
00427     UTFCHARCpy(candidate_temp, candidate);
00428     label_temp[0] = ' ';
00429     label_temp[1] = 0;
00430 
00431     candidates_info->candidates[num_candidates] = candidate_temp;
00432     candidates_info->labels[num_candidates] = label_temp;
00433     candidates_info->num_candidates ++;
00434 
00435     return 1;
00436 }
00437 
00438 /*****************************************
00439       callbacks
00440 *****************************************/
00441 void le_session_ui_callbacks(MInputContext *ic, MSymbol command)
00442 {
00443     iml_session_t *s;
00444     LeSessionContextRec *le_session_context;
00445 
00446     MConverter *converter;
00447     UTFCHAR buf[1024];
00448 
00449     int layout_type_vertical = 1;
00450     int layout_capacity = 10;
00451 
00452     le_session_context = le_session_context_get_from_m17n_ic(ic);
00453     DEBUG_printf("le_session_ui_callbacks == le_session_context: %p\n", le_session_context);
00454     if (le_session_context == NULL)
00455         return;
00456 
00457     s = le_session_context->s;
00458     if (s == NULL)
00459         return;
00460 
00461     converter = le_info->converter;
00462 
00463     if (command == Minput_preedit_start) {
00464 
00465         DEBUG_printf("    Minput_preedit_start\n");
00466         le_iml_preedit_start(s);
00467 
00468     } else if (command == Minput_preedit_done) {
00469 
00470         DEBUG_printf("    Minput_preedit_done\n");
00471         le_iml_preedit_enddraw(s);
00472 
00473     } else if (command == Minput_preedit_draw) {
00474 
00475         int len;
00476         int highlight_from, highlight_to;
00477 
00478         DEBUG_printf("    Minput_preedit_draw, caret_pos: %d\n", ic->cursor_pos);
00479 
00480         if (!ic->preedit) {
00481             DEBUG_printf("ic->preedit is NULL, call le_iml_preedit_enddraw\n");
00482             le_iml_preedit_enddraw(s);
00483             return;
00484         }
00485 
00486         memset(buf, 0, sizeof(buf));
00487         mconv_rebind_buffer(converter, (unsigned char *)buf, sizeof (buf));
00488         mconv_encode(converter, ic->preedit);
00489         buf[converter->nbytes] = 0;
00490 
00491         len = UTFCHARLen(buf);
00492         if (len > 0) {
00493 
00494             highlight_from = 0;
00495             highlight_to = 0;
00496             if (ic->candidate_from < ic->candidate_to &&
00497                 ic->candidate_to <= len) {
00498                 highlight_from = ic->candidate_from;
00499                 highlight_to = ic->candidate_to;
00500             }
00501 
00502             le_iml_preedit_draw(s, buf, ic->cursor_pos, highlight_from, highlight_to);
00503         } else {
00504             le_iml_preedit_enddraw(s);
00505         }
00506 
00507     } else if (command == Minput_status_start) {
00508 
00509         DEBUG_printf("    Minput_status_start\n");
00510         le_iml_status_start(s);
00511 
00512     } else if (command == Minput_status_done) {
00513 
00514         DEBUG_printf("    Minput_status_done\n");
00515         buf[0] = 0;
00516         le_iml_status_draw(s, buf);
00517         le_iml_status_enddraw(s);
00518 
00519     } else if (command == Minput_status_draw) {
00520 
00521         DEBUG_printf("    Minput_status_draw\n");
00522 
00523         if (!ic->status)
00524             return;
00525 
00526         memset(buf, 0, sizeof(buf));
00527         mconv_rebind_buffer(converter, (unsigned char *)buf, sizeof (buf));
00528         mconv_encode(converter, ic->status);
00529         buf[converter->nbytes] = 0;
00530         if (buf[0]) {
00531             le_iml_status_draw(s, buf);
00532         }
00533 
00534     } else if (command == Minput_candidates_start) {
00535         LayoutInfo layout;
00536 
00537         DEBUG_printf("    Minput_candidates_start\n");
00538         layout.choice_per_window = layout_capacity;
00539         if (layout_type_vertical) {
00540             layout.ncolumns = 1;
00541             layout.nrows = layout_capacity;
00542             layout.drawUpDirection = DrawUpVertically;
00543         } else {
00544             layout.ncolumns = layout_capacity;
00545             layout.nrows = 1;
00546             layout.drawUpDirection = DrawUpHorizontally;
00547         }
00548         le_iml_lookup_start(s, &layout);
00549 
00550     } else if (command == Minput_candidates_done) {
00551 
00552         DEBUG_printf("    Minput_candidates_done\n");
00553         le_iml_lookup_enddraw(s);
00554 
00555     } else if (command == Minput_candidates_draw) {
00556 
00557         candidates_info_t *candidates_info;
00558 
00559         int cur, i, len;
00560 
00561         MPlist *group;
00562         MText *mt;
00563 
00564         DEBUG_printf("    Minput_candidates_draw\n");
00565         DEBUG_printf("       candidate_index: %d\n", ic->candidate_index);
00566         DEBUG_printf("       candidate_from : %d\n", ic->candidate_from);
00567         DEBUG_printf("       candidate_to   : %d\n", ic->candidate_to);
00568         DEBUG_printf("       candidate_show : %d\n", ic->candidate_show);
00569 
00570         if (!ic->candidate_list || !ic->candidate_show) {
00571             le_iml_lookup_enddraw(s);
00572             return;
00573         }
00574 
00575         i = 0;
00576         group = ic->candidate_list;
00577         while (1) {
00578             if (mplist_key(group) == Mtext)
00579                 len = mtext_len (mplist_value (group));
00580             else
00581                 len = mplist_length (mplist_value (group));
00582             if (i + len > ic->candidate_index)
00583                 break;
00584             i += len;
00585             group = mplist_next (group);
00586         }
00587 
00588         cur = ic->candidate_index - i;
00589 
00590         candidates_info = (candidates_info_t *) candidates_info_new();
00591         if (candidates_info == NULL)
00592             return;
00593 
00594         if (mplist_key (group) == Mtext) {
00595             mt = (MText *) mplist_value (group);
00596             memset(buf, 0, sizeof(buf));
00597             mconv_rebind_buffer(converter, (unsigned char *)buf, sizeof (buf));
00598             mconv_encode(converter, mt);
00599             buf[converter->nbytes] = 0;
00600 
00601             DEBUG_printf("converter->nbytes: %d\n", converter->nbytes);
00602             for (i = 0; i < UTFCHARLen(buf); i++) {
00603                 UTFCHAR candidate[2];
00604 
00605                 candidate[0] = buf[i];
00606                 candidate[1] = 0;
00607                 candidates_info_pushback_candidate(candidates_info, candidate);
00608             }
00609         } else {
00610             MPlist *pl;
00611 
00612             for (pl = (MPlist *) mplist_value (group); mplist_key (pl) != Mnil; pl = mplist_next (pl)) {
00613                 mt = (MText *) mplist_value (pl);
00614                 memset(buf, 0, sizeof(buf));
00615                 mconv_rebind_buffer(converter, (unsigned char *)buf, sizeof (buf));
00616                 mconv_encode(converter, mt);
00617                 buf[converter->nbytes] = 0;
00618                 DEBUG_printf("converter->nbytes: %d\n", converter->nbytes);
00619                 if (buf[0]) {
00620                     candidates_info_pushback_candidate(candidates_info, buf);
00621                 }
00622             }
00623         }
00624 
00625         DEBUG_printf("num_candidates: %d\n", candidates_info->num_candidates);
00626         if (candidates_info->num_candidates == 0) {
00627             candidates_info_destroy(candidates_info);
00628             return;
00629         }
00630 
00631         le_iml_lookup_draw(s,
00632                        candidates_info->num_candidates,
00633                        candidates_info->candidates,
00634                        NULL, candidates_info->labels,
00635                        NULL, NULL, NULL, cur,
00636                        layout_type_vertical ? 1 : 0);
00637 
00638         candidates_info_destroy(candidates_info);
00639 
00640         return;
00641     }
00642 }