Back to index

im-sdk  12.3.91
imaux.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2003 Sun Microsystems Inc.
00003  *
00004  * This is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  *
00019  * Authors: Hidetoshi Tajima <hidetoshi.tajima@sun.com>
00020  */
00021 
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <sys/mman.h>
00027 #include <dlfcn.h>
00028 #include <link.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <glib.h>
00032 
00033 #include <qwidget.h>
00034 
00035 #include "imaux.h"
00036 #include "imaux-int.h"
00037 #include "X11/XlcPublic.h" /*TODO*/
00038 #include "debug.h"
00039 
00040 
00041 static void delete_aux_ic(IIIMInputContext *context_iiim);
00042 
00043 
00044 static void iiim_aux_download (IIIMCF_downloaded_object obj);
00045 
00046 #define AUX_BASE_DIR "/usr/lib/im"  /*this is old path for FC3, TODO*/       
00047 
00048 #define IS_SPACE(len, ptr)  ((0 < (len)) &&                           \
00049                              (('\t' == *(p)) || (' ' == *(p))))
00050 #define IS_EOL(len, ptr)    (((len) <= 0) || ('\n' == *(p)))
00051 #define IS_NOT_EOL(len, ptr)       ((0 < (len)) && ('\n' != *(p)))
00052 
00053 static aux_handle_t *aux_load (char *aux_file_name);
00054 static aux_handle_t *aux_conf_load (char *aux_file_name);
00055 static aux_handle_t *aux_so_load (char * aux_file_name);
00056 
00057 static aux_t *aux_get (IIIMInputContext *context_iiim, IIIMCF_event ev,
00058                      const IIIMP_card16 *aux_name);
00059 static aux_entry_t *aux_entry_get (const IIIMP_card16 *name);
00060 
00061 typedef struct {
00062   int len;
00063   aux_t *aux;
00064   IIIMCF_event ev;
00065   aux_data_t *pad;
00066 } AUXComposed;
00067 
00068 /*
00069  * X auxiliary object service method
00070  */
00071 static void          service_aux_setvalue(aux_t *,
00072                                         const unsigned char *, int);
00073 static void          service_aux_getvalue(aux_t *,
00074                                         const unsigned char *, int);
00075 static int           service_im_id(aux_t *);
00076 static int           service_ic_id(aux_t *);
00077 static void          service_data_set(aux_t *, int, void *);
00078 static void *        service_data_get(aux_t *, int);
00079 static Display *     service_display(aux_t *);
00080 static Window        service_window(aux_t *);
00081 static XPoint *             service_point(aux_t *, XPoint *);
00082 static XPoint *             service_point_caret(aux_t *, XPoint *);
00083 static size_t        service_utf16_mb(const char **, size_t *,
00084                                     char **, size_t *);
00085 static size_t        service_mb_utf16(const char **, size_t *,
00086                                     char **, size_t *);
00087 static unsigned char *      service_compose(const aux_data_t *, int *);
00088 static int           service_compose_size(aux_data_type_t,
00089                                         const unsigned char *);
00090 static aux_data_t *  service_decompose(aux_data_type_t,
00091                                      const unsigned char *);
00092 static void          service_decompose_free(aux_data_t *);
00093 static void          service_register_X_filter(Display *, Window, int, int,
00094                                             Bool (* filter)(Display *,
00095                                                           Window,
00096                                                           XEvent *,
00097                                                           XPointer),
00098                                             XPointer);
00099 static void          service_unregister_X_filter(Display *, Window,
00100                                               Bool (* filter)(Display *,
00101                                                             Window,
00102                                                             XEvent *,
00103                                                             XPointer),
00104                                               XPointer);
00105 static Bool          service_server(aux_t *);
00106 static Window        service_client_window(aux_t *);
00107 static Window        service_focus_window(aux_t *);
00108 static int           service_screen_number(aux_t *);
00109 static int           service_point_screen(aux_t *, XPoint *);
00110 static int           service_point_caret_screen(aux_t *, XPoint *);
00111 static Bool          service_get_conversion_mode(aux_t*);
00112 static void          service_set_conversion_mode(aux_t*, int);
00113 static aux_t *              service_aux_get_from_id(int im_id, int ic_id,
00114                                           IIIMP_card16 *aux_name,
00115                                           int aux_name_length);
00116 
00117 static aux_service_t
00118 g_aux_service = {
00119   service_aux_setvalue,
00120   service_im_id,
00121   service_ic_id,
00122   service_data_set,
00123   service_data_get,
00124   service_display,
00125   service_window,
00126   service_point,
00127   service_point_caret,
00128   service_utf16_mb,
00129   service_mb_utf16,
00130   service_compose,
00131   service_compose_size,
00132   service_decompose,
00133   service_decompose_free,
00134   service_register_X_filter,
00135   service_unregister_X_filter,
00136   service_server,
00137   service_client_window,
00138   service_focus_window,
00139   service_screen_number,
00140   service_point_screen,
00141   service_point_caret_screen,
00142   service_get_conversion_mode, 
00143   service_set_conversion_mode,
00144   service_aux_getvalue,
00145   service_aux_get_from_id
00146 };
00147 
00148 static aux_ic_info_t *      aux_ic_info = NULL;
00149 
00150 
00151 static gchar*
00152 convert_to_string (const IIIMP_card16 *ucstr)
00153 {
00154   glong read_len, write_len;
00155   gchar *result;
00156   result = g_utf16_to_utf8 (ucstr, -1, &read_len, &write_len, NULL);
00157 
00158   return result;
00159 }
00160 
00161 /* public function */
00162 void
00163 iiim_aux_start (IIIMInputContext *context_iiim,
00164               IIIMCF_event ev)
00165 {
00166   aux_t *aux;
00167   AUXComposed ac;
00168 
00169   aux = aux_get (context_iiim, ev, NULL);
00170   if (!aux)
00171   {
00172     g_message("aux is null\n");
00173     return;
00174   }
00175 
00176   DEBUG_DO(printf("**IMAUX: iiim_aux_start(), name is %s\n", convert_to_string(aux->im->ae->dir.name.ptr)));
00177 
00178   memset(&ac, 0, sizeof(ac));
00179   ac.aux = aux;
00180   ac.ev = ev;
00181 
00182   aux->im->ae->dir.method->start (aux, 
00183                               (const unsigned char *) &ac,
00184                               0); 
00185   return;
00186 }
00187 
00188 void
00189 iiim_aux_draw (IIIMInputContext *context_iiim,
00190               IIIMCF_event ev)
00191 {
00192   aux_t *aux;
00193   AUXComposed ac;
00194 
00195   aux = aux_get (context_iiim, ev, NULL);
00196   if (!aux)
00197     return;
00198 
00199   memset(&ac, 0, sizeof(ac));
00200   ac.aux = aux;
00201   ac.ev = ev;
00202 
00203   aux->im->ae->dir.method->draw(aux,
00204                             (const unsigned char *) &ac,
00205                             0);
00206   return;
00207 }
00208 
00209 void
00210 iiim_aux_done (IIIMInputContext *context_iiim,
00211               IIIMCF_event ev)
00212 {
00213   aux_t *aux;
00214   AUXComposed ac;
00215 
00216   aux = aux_get (context_iiim, ev, NULL);
00217   if (!aux)
00218     return;
00219 
00220   memset(&ac, 0, sizeof(ac));
00221   ac.aux = aux;
00222   ac.ev = ev;
00223 
00224   aux->im->ae->dir.method->done(aux,
00225                             (const unsigned char *) &ac,
00226                             0); 
00227   return;
00228 }
00229 
00230 void
00231 iiim_aux_getvalues_reply (IIIMInputContext *context_iiim,
00232                        IIIMCF_event ev)
00233 {
00234   aux_t *aux;
00235   AUXComposed ac;
00236 
00237   aux = aux_get (context_iiim, ev, NULL);
00238   if (!aux)
00239     return;
00240 
00241   memset(&ac, 0, sizeof(ac));
00242   ac.aux = aux;
00243   ac.ev = ev;
00244 
00245   if (aux->im->ae->dir.method->getvalues_reply)
00246       aux->im->ae->dir.method->getvalues_reply(aux,
00247                                           (const unsigned char *) &ac,
00248                                           0); 
00249   return;
00250 }
00251 
00252 IIIMF_status
00253 iiim_setup_aux_object (IIIMCF_handle iiim)
00254 {
00255   IIIMF_status st;
00256   IIIMCF_object_descriptor *pdesc;
00257   IIIMCF_object_descriptor **ppdescs;
00258   IIIMCF_downloaded_object *pobjs;
00259   int i, n1, n2;
00260 
00261   n1 = 0;
00262   pdesc = NULL;
00263   st = iiimcf_get_object_descriptor_list (iiim, &n1, (const IIIMCF_object_descriptor**)&pdesc);  
00264 
00265   if (st != IIIMF_STATUS_SUCCESS)
00266     return st;
00267 
00268   pobjs = g_new0(IIIMCF_downloaded_object, n1);
00269   ppdescs = g_new0 (IIIMCF_object_descriptor *, n1);
00270 
00271   for (i = 0, n2 = 0; i < n1; i++, pdesc++)
00272     {
00273       if (pdesc->predefined_id == IIIMP_IMATTRIBUTE_BINARY_GUI_OBJECT)
00274        ppdescs[n2++] = pdesc;
00275     }
00276   if (n2 > 0)
00277     {
00278       st =  iiimcf_get_downloaded_objects (iiim, n2, (const IIIMCF_object_descriptor**)ppdescs, pobjs); 
00279       if (st != IIIMF_STATUS_SUCCESS)
00280        {
00281          g_free (ppdescs);
00282          g_free (pobjs); 
00283          return st;
00284        }
00285       for (i = 0; i < n2; i++)
00286        iiim_aux_download (pobjs[i]);
00287     }
00288   g_free (ppdescs);
00289   g_free (pobjs); 
00290 
00291   return IIIMF_STATUS_SUCCESS;
00292 }
00293 
00294 void
00295 IIim_aux_destrory_ic (IIIMInputContext *context_iiim)
00296 {
00297   delete_aux_ic(context_iiim);
00298 }
00299 
00300 void
00301 IIim_aux_set_icfocus (IIIMInputContext *context_iiim)
00302 {
00303   aux_t *aux;
00304   aux_im_data_t *aux_im;
00305 
00306   aux = aux_get (context_iiim, NULL, (IIIMP_card16 *)"");
00307   if (!aux)
00308     return;
00309 
00310   for (aux_im = aux->im_list; aux_im; aux_im = aux_im->next)
00311     {
00312       if (aux_im->ae->if_version >= AUX_IF_VERSION_2 &&
00313               aux_im->ae->dir.method->set_icforcus != NULL)
00314        {
00315          aux->im = aux_im;
00316          aux_im->ae->dir.method->set_icforcus(aux);
00317        }
00318     }
00319 }
00320 
00321 void
00322 IIim_aux_unset_icfocus (IIIMInputContext *context_iiim)
00323 {
00324   aux_t *aux;
00325   aux_im_data_t *aux_im;
00326 
00327   aux = aux_get (context_iiim, NULL, (IIIMP_card16 *)"\0");
00328   if (!aux)
00329     return;
00330 
00331   for (aux_im = aux->im_list; aux_im; aux_im = aux_im->next)
00332     {
00333       if (aux_im->ae->if_version >= AUX_IF_VERSION_2 &&
00334               aux_im->ae->dir.method->set_icforcus != NULL)
00335        {
00336          aux->im = aux_im;
00337          aux_im->ae->dir.method->unset_icforcus(aux);
00338        }
00339     }
00340 }
00341 
00342 
00343 
00344 static gunichar2*
00345 convert_to_utf16 (const char *str, const size_t len, glong *to_left)
00346 {
00347   glong read_len, write_len;
00348   gunichar2 *result = NULL;
00349   result = g_utf8_to_utf16 (str, len, &read_len, &write_len, NULL);
00350 
00351   *to_left = write_len;
00352 
00353   return result;
00354 }  
00355 
00356 /*
00357  * object downloading
00358  */
00359 void
00360 iiim_aux_download (IIIMCF_downloaded_object obj)
00361 {
00362   char *aux_file_name;
00363   char *aux_file_name_buf;
00364   int  aux_file_name_len;
00365   char *file_name = NULL;
00366   char *dir_name;
00367   int  dir_name_len;
00368   IIIMF_status st;
00369   const IIIMP_card16 *u16filename;
00370 
00371   aux_file_name = NULL;
00372   aux_file_name_buf = NULL;
00373 
00374   st = iiimcf_get_downloaded_object_filename (obj, &u16filename);
00375   if (st != IIIMF_STATUS_SUCCESS)
00376     return;
00377 
00378   aux_file_name = convert_to_string (u16filename);
00379   if (aux_file_name == NULL)
00380     return;
00381 
00382   aux_file_name_buf = aux_file_name;
00383 
00384   if (!aux_file_name)
00385     return;
00386 
00387   aux_file_name_len = strlen (aux_file_name);
00388 
00389   /*
00390    * may not start with "/"
00391    * may not start with "../"
00392    * may not contain "/../"
00393    * may not end with "/"
00394    * may not end with "/."
00395    * may not end with "/.."
00396    * may not be ".."
00397    */
00398 
00399   if (((1 <= aux_file_name_len) &&
00400        ('/' == *(aux_file_name + 0))) ||
00401       ((3 <= aux_file_name_len) &&
00402        ('.' == *(aux_file_name + 0)) &&
00403        ('.' == *(aux_file_name + 1)) &&
00404        ('/' == *(aux_file_name + 2))) ||
00405       (NULL != strstr(aux_file_name, "/../")) ||
00406       ((1 <= aux_file_name_len) &&
00407        ('/' == *(aux_file_name + aux_file_name_len - 1))) ||
00408       ((2 <= aux_file_name_len) &&
00409        ('/' == *(aux_file_name + aux_file_name_len - 2)) &&
00410        ('.' == *(aux_file_name + aux_file_name_len - 1))) ||
00411       ((3 <= aux_file_name_len) &&
00412        ('/' == *(aux_file_name + aux_file_name_len - 3)) &&
00413        ('.' == *(aux_file_name + aux_file_name_len - 2)) &&
00414        ('.' == *(aux_file_name + aux_file_name_len - 1))) ||
00415       ((2 == aux_file_name_len) &&
00416        ('.' == *(aux_file_name + 0)) &&
00417        ('.' == *(aux_file_name + 1))))
00418     {
00419       g_free (aux_file_name_buf);
00420       return;
00421     }
00422 
00423   /*
00424    * eliminate leading "./"
00425    */
00426   if ((2 <= aux_file_name_len) &&
00427       ('.' == *(aux_file_name + 0)) &&
00428       ('/' == *(aux_file_name + 1)))
00429     {
00430       aux_file_name += 2;
00431       aux_file_name_len -= 2;
00432     }
00433 
00434   dir_name = AUX_BASE_DIR; 
00435   dir_name_len = strlen (dir_name);
00436 
00437   /* for sure, we need to add a directory separator after dir_name */
00438   if (dir_name_len > 0 && dir_name[dir_name_len-1] == '/')
00439       file_name = g_strconcat (dir_name, aux_file_name, NULL);
00440   else
00441       file_name = g_strconcat (dir_name, "/", aux_file_name, NULL); 
00442 
00443   DEBUG_DO(printf("**IMAUX: file_name is  %s\n", file_name));
00444   (void)aux_load (file_name);
00445 
00446   g_free (aux_file_name_buf);
00447   g_free (file_name); 
00448 
00449   return;
00450 }
00451 
00452 /*
00453  * internal method
00454  */
00455 static aux_handle_t *
00456 aux_load (char *aux_file_name)
00457 {
00458   int fd;
00459   char buf[64];
00460   int magic_len;
00461   int len;
00462 
00463   if (-1 == (fd = open(aux_file_name, O_RDONLY, 0)))
00464     return NULL;
00465 
00466   magic_len = strlen (AUX_CONF_MAGIC);
00467 
00468   len = read (fd, buf, magic_len);
00469 
00470   close(fd);
00471 
00472   if ((len == magic_len) &&
00473       (0 == memcmp (buf, AUX_CONF_MAGIC, len)))
00474     return aux_conf_load (aux_file_name);
00475   else
00476     return aux_so_load (aux_file_name);
00477 }
00478 
00479 static aux_handle_t *aux_handle = NULL;
00480 
00481 static aux_handle_t *
00482 aux_conf_load(
00483     char * aux_file_name
00484 )
00485 {
00486     int              fd;
00487     struct stat      st_buf;
00488     void *           addr;
00489     char *           p;
00490     char *           aux_name;
00491     int              aux_name_len;
00492     char *           aux_so;
00493     int              aux_so_len;
00494     aux_handle_t *   ah;
00495     int              len;
00496     int              dir_name_len;
00497     char *           dir_name_last;
00498 
00499     dir_name_last = strrchr(aux_file_name, '/');
00500     if (NULL == dir_name_last) {
00501        return NULL;
00502     }
00503     dir_name_len = ((dir_name_last - aux_file_name) + 1);
00504 
00505     if (-1 == (fd = open(aux_file_name, O_RDONLY, 0))) {
00506        return NULL;
00507     }
00508 
00509     if (0 != fstat(fd, &st_buf)) {
00510        close(fd);
00511        return NULL;
00512     }
00513 
00514     addr = mmap(0, st_buf.st_size,
00515               PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
00516 
00517     close(fd);
00518 
00519     if (MAP_FAILED == addr) {
00520        return NULL;
00521     }
00522 
00523     ah = NULL;
00524        
00525     for (p = (char *)addr, len = st_buf.st_size; 0 < len; ) {
00526        if ('#' == *p) {
00527            while (IS_NOT_EOL(len, p)) {
00528               p++;
00529               --len;
00530            }
00531            if (IS_EOL(len, p)) {
00532               p++;
00533               --len;
00534            }
00535            continue;
00536        }
00537 
00538        while (IS_SPACE(len, p)) {
00539            p++;
00540            --len;
00541        }
00542        if (IS_EOL(len, p)) {
00543            p++;
00544            --len;
00545            continue;
00546        }
00547 
00548        aux_name = p;
00549        while ((!(IS_SPACE(len, p))) && IS_NOT_EOL(len, p)) {
00550            p++;
00551            --len;
00552        }
00553        if (IS_EOL(len, p)) {
00554            p++;
00555            --len;
00556            continue;
00557        }
00558 
00559        aux_name_len = (p - aux_name);
00560 
00561        while (IS_SPACE(len, p)) {
00562            p++;
00563            --len;
00564        }
00565        if (IS_EOL(len, p)) {
00566            p++;
00567            --len;
00568            continue;
00569        }
00570 
00571        aux_so = p;
00572        while ((!(IS_SPACE(len, p))) && IS_NOT_EOL(len, p)) {
00573            p++;
00574            --len;
00575        }
00576        aux_so_len = (p - aux_so);
00577 
00578        ah = (aux_handle_t *)g_new0 (aux_handle_t, 1);
00579        if (NULL == ah) {
00580            break;
00581        }
00582 
00583        ah->aux_name.len = 0;
00584        ah->aux_name.ptr = NULL;
00585 
00586        ah->aux_name.ptr = convert_to_utf16 (aux_name, aux_name_len,
00587                                         (glong*)&ah->aux_name.len); 
00588        if ('/' == *aux_so) {
00589            ah->file_name = g_new0 (gchar, aux_so_len + 1);
00590        } else {
00591            ah->file_name = g_new0(gchar, dir_name_len + aux_so_len + 1);
00592        } 
00593        if (NULL == ah->file_name) {
00594            g_free(ah->aux_name.ptr);
00595            g_free(ah); 
00596            break;
00597        }
00598        if ('/' == *aux_so) {
00599            memcpy(ah->file_name, aux_so, aux_so_len);
00600            *(ah->file_name + aux_so_len) = '\0';
00601        } else {
00602            memcpy(ah->file_name, aux_file_name, dir_name_len);
00603            memcpy(ah->file_name + dir_name_len, aux_so, aux_so_len);
00604            *(ah->file_name + dir_name_len + aux_so_len) = '\0';
00605        }
00606        ah->handle = NULL;
00607        ah->ae = NULL;
00608        ah->ae_num = 0;
00609        ah->next = aux_handle;
00610        aux_handle = ah;
00611     }
00612 
00613     munmap(addr, st_buf.st_size);
00614 
00615     return ah;
00616 }
00617 
00618 
00619 /*
00620  *
00621  */
00622 static aux_dir_t *
00623 get_aux_dir_from_aux_info (void *handle, unsigned int *ifversion)
00624 {
00625     aux_info_t *aux_info;
00626 
00627     aux_info = (aux_info_t*)dlsym(handle, AUX_INFO_SYMBOL);
00628 
00629     if (aux_info && aux_info->if_version >= AUX_IF_VERSION_2
00630            && aux_info->register_service != NULL) {
00631        aux_info->register_service (AUX_IF_VERSION_2, &g_aux_service);
00632        *ifversion = aux_info->if_version;
00633        return aux_info->dir;
00634     }
00635 
00636     return NULL;
00637 }
00638 
00639 
00640 /*
00641  *
00642  */
00643 static aux_handle_t *
00644 aux_so_load(
00645     char * aux_file_name
00646 )
00647 {
00648     void *           handle = (void *)NULL;
00649     aux_dir_t *      aux_dir;
00650     aux_dir_t *      ad;
00651     int              adn;
00652     aux_handle_t *   ah;
00653     aux_handle_t *   ah_free;
00654     int              i;
00655     unsigned int     ifversion;
00656 
00657     /*
00658      * check whether the object is already loaded
00659      */
00660     for (ah = aux_handle; NULL != ah; ah = ah->next) {
00661        if ((0 == strcmp(aux_file_name, ah->file_name)) &&
00662            (NULL != ah->handle)) {
00663            return ah;
00664        }
00665     }
00666 
00667     /*
00668      * load the object and construct aux_handle_t structure for it
00669      */
00670     handle = dlopen(aux_file_name, RTLD_LAZY);
00671     if (NULL == handle) {
00672        return NULL;
00673     }
00674 
00675     if ((aux_dir = get_aux_dir_from_aux_info (handle, &ifversion)) == NULL) {
00676        aux_dir = (aux_dir_t *)dlsym(handle, AUX_DIR_SYMBOL);
00677        if (NULL == aux_dir) {
00678            dlclose(handle);
00679            return NULL;
00680        }
00681        ifversion = 0;
00682     }
00683 
00684     for (adn = 0, ad = aux_dir; 0 < ad->name.len; ad += 1, adn += 1);
00685 
00686     if (NULL == ah) {
00687        ah = (aux_handle_t *)g_new0 (aux_handle_t, 1);  
00688        if (NULL == ah) {
00689            dlclose(handle);
00690            return NULL;
00691        }
00692        memset(ah, 0, sizeof (aux_handle_t));
00693 
00694        ah_free = ah;
00695     } else {
00696        ah_free = NULL;
00697     }
00698 
00699     if (NULL == ah->file_name) {
00700        ah->file_name = strdup(aux_file_name);
00701        if (NULL == ah->file_name) {
00702            g_free(ah); 
00703            dlclose(handle);
00704            return NULL;
00705        }
00706     }
00707     ah->handle = handle;
00708     ah->ae_num = adn;
00709     ah->ae = g_new0 (aux_entry_t, adn);  
00710     if (NULL == ah->ae) {
00711        if (NULL != ah_free) {
00712            g_free(ah->file_name);
00713            g_free(ah); 
00714        }
00715        dlclose(handle);
00716        return NULL;
00717     }
00718     for (i = 0; i < adn; i++) {
00719        (ah->ae + i)->created = 0;
00720        memcpy(&((ah->ae + i)->dir), aux_dir + i, sizeof (aux_dir_t));
00721        (ah->ae + i)->if_version = ifversion;
00722     }
00723 
00724     ah->next = aux_handle;
00725     aux_handle = ah;
00726     
00727     DEBUG_DO(printf("**IMAUX: %s has been loaded\n", aux_file_name));
00728     return ah;
00729 }
00730 
00731 static int
00732 auxname_strncmp (const IIIMP_card16 *s1,
00733                const IIIMP_card16 *s2,
00734                int len)
00735 {
00736   len /= sizeof (IIIMP_card16);
00737   for (;len > 0; len--, s1++, s2++)
00738     {
00739       if (*s1 > *s2)
00740        return 1;
00741       if (*s1 < *s2)
00742        return -1;
00743       if (!*s1)
00744        return 0;
00745     }
00746   if (!*s1)
00747     return 0;
00748   return 2;
00749 }
00750 
00751 static
00752 aux_im_data_t*
00753 create_aux_im_data (aux_t *aux, const IIIMP_card16 *auxname)
00754 {
00755   aux_entry_t *ae;
00756   aux_im_data_t *aux_im;
00757 
00758   ae = aux_entry_get (auxname);
00759   if (!ae)
00760     return NULL;
00761   
00762   aux_im = g_new0 (aux_im_data_t, 1); 
00763 
00764   /* The following members are only for fake. */
00765  /* context_iiim = (IIIMInputContext *)aux->ic;
00766   handle = im_info_get_handle(context_iiim->iiim_info);
00767   if (handle == NULL)
00768     return NULL;
00769   st = iiimcf_get_im_id(handle, &aux_im->im_id);
00770   if (st != IIIMF_STATUS_SUCCESS)
00771     return NULL;
00772   st = iiimcf_get_ic_id(context_iiim->context, &aux_im->ic_id);
00773   if (st != IIIMF_STATUS_SUCCESS)
00774     return NULL;*/  /*TODO*/
00775   /* end */
00776 
00777   aux_im->ae = ae;
00778   aux_im->next = aux->im_list;
00779   aux->im_list = aux_im;
00780   aux->im = aux_im;
00781   if (!ae->created)
00782     {
00783       if (!ae->dir.method->create(aux))
00784        return NULL;
00785       ae->created = 1;
00786     }
00787   return aux_im;
00788 }
00789 
00790 static aux_t *
00791 aux_get (IIIMInputContext *context_iiim, IIIMCF_event ev,
00792         const IIIMP_card16 *auxname)
00793 {
00794   IIIMF_status st;
00795   aux_t *aux = NULL;
00796   aux_im_data_t *aux_im;
00797   aux_ic_info_t *aux_ic;
00798   IIIMCF_handle handle;
00799 
00800   if(!auxname)
00801       DEBUG_DO(printf("**IMAUX: auxname is null\n"));
00802   if (!context_iiim || !context_iiim->cur_context )
00803     return NULL;
00804 
00805   if (auxname == NULL)
00806     {
00807       st = iiimcf_get_aux_event_value (ev, &auxname,
00808                                    NULL, NULL, NULL, NULL, NULL);
00809       if (st != IIIMF_STATUS_SUCCESS)
00810        return NULL;
00811     }
00812 
00813   /*
00814    * create aux object if it is not created
00815    */
00816   aux = context_iiim->aux;
00817   if (!aux)
00818     {
00819       aux = g_new0 (aux_t, 1); 
00820       aux->ic = (aux_ic_data_t*)context_iiim;
00821       aux->service = &g_aux_service;
00822       context_iiim->aux = aux;
00823 
00824       aux_ic = g_new0 (aux_ic_info_t, 1); 
00825       handle = context_iiim->get_iiimcf_handle(); 
00826       if (handle == NULL)
00827        {
00828          g_free(aux_ic); 
00829          return NULL;
00830        }
00831       st = iiimcf_get_im_id(handle, &aux_ic->im_id);
00832       DEBUG_DO(printf("**IMAUX: aux_ic->im_id is %d\n", aux_ic->im_id));
00833       if (st != IIIMF_STATUS_SUCCESS)
00834        {
00835          g_free(aux_ic); 
00836          return NULL;
00837        }
00838       st = iiimcf_get_ic_id(context_iiim->cur_context, &aux_ic->ic_id); 
00839       DEBUG_DO(printf("**IMAUX: aux_ic->ic_id is %d\n", aux_ic->ic_id));
00840       if (st != IIIMF_STATUS_SUCCESS)
00841        {
00842          g_free(aux_ic);/*TODO*/
00843          return NULL;
00844        }
00845       aux_ic->ic_data = (aux_ic_data_t*)context_iiim;
00846       aux_ic->next = aux_ic_info;
00847       aux_ic_info = aux_ic;
00848       DEBUG_DO(printf("**IMAUX: aux is created\n"));
00849     }
00850 
00851   if (aux)
00852     {
00853       /*
00854        * search for aux_im_data corresponding to auxname.
00855        */
00856       if (*auxname != '\0')
00857        {
00858           DEBUG_DO(printf("**IMAUX: aux_get() auxname is %s\n", convert_to_string(auxname)));
00859          for (aux_im = aux->im_list; aux_im; aux_im = aux_im->next)
00860            {
00861               DEBUG_DO(printf("**IMAUX: aux_get() aux_im->ae->dir.name is %s\n", \
00862                                    convert_to_string(aux_im->ae->dir.name.ptr)));
00863              if (!auxname_strncmp (auxname,
00864                                 aux_im->ae->dir.name.ptr,
00865                                 aux_im->ae->dir.name.len))
00866               {
00867                 aux->im = aux_im;
00868                 return aux;
00869               }
00870            }
00871        }
00872       else
00873        {
00874          aux->im = NULL;
00875          return aux;
00876        }
00877     }
00878   
00879   aux_im = create_aux_im_data (aux, auxname);
00880   if (!aux_im)
00881     return NULL;
00882 
00883   return aux;
00884 }
00885 
00886 static aux_entry_t *
00887 aux_entry_get(
00888     const IIIMP_card16 *name
00889 )
00890 {
00891     aux_handle_t *ah;
00892     aux_handle_t *ah0;
00893     aux_entry_t *ae;
00894     int       i;
00895 
00896     if (!name) return NULL;
00897 
00898     for (ah = aux_handle; NULL != ah; ah = ah->next) {
00899        if ((ah->aux_name.len > 0)
00900            && (!auxname_strncmp(name, ah->aux_name.ptr, ah->aux_name.len))) {
00901            /* This handle is created from a configuration file.
00902               Load SO now.  */
00903            ah0 = aux_so_load(ah->file_name);
00904            if (!ah0) continue;
00905            ah = ah0;
00906        }
00907        for (ae = ah->ae, i = ah->ae_num; 0 < i; ae += 1, --i) {
00908            if (!auxname_strncmp(name, ae->dir.name.ptr, ae->dir.name.len)) {
00909               return ae;
00910            }
00911        }
00912     }
00913 
00914     return NULL;
00915 }
00916 
00917 static int
00918 aux_string_length(
00919     const IIIMP_card16 *str
00920 )
00921 {
00922     int n;
00923     for (n = 0; *str; str++, n++);
00924     return n;
00925 }
00926 
00927 static AUXComposed*
00928 create_composed_from_event(
00929     aux_t *aux,
00930     IIIMCF_event ev
00931 )
00932 {
00933     unsigned char *p;
00934     AUXComposed *pac;
00935     IIIMF_status st;
00936     const IIIMP_card16 *aux_name;
00937     IIIMP_card32 class_idx;
00938     int num_intvals;
00939     const IIIMP_card32 *pintvals;
00940     int num_strvals;
00941     const IIIMP_card16 **pstrs;
00942     aux_data_t *pad;
00943 
00944     int i, n;
00945     int aux_data_t_n;
00946     int aux_name_len, aux_name_n;
00947     int integer_list_n, string_list_n;
00948     int string_n;
00949     int *pstring_len;
00950 
00951 #define ROUNDUP(n) ((n + sizeof(int) - 1) / sizeof(int) * sizeof(int))
00952 
00953     st = iiimcf_get_aux_event_value(ev, &aux_name, &class_idx,
00954                                 &num_intvals, &pintvals,
00955                                 &num_strvals, &pstrs);
00956     if (st != IIIMF_STATUS_SUCCESS) return NULL;
00957 
00958     /* first of all, caliculate size. */
00959     n = ROUNDUP(sizeof(AUXComposed));
00960     aux_data_t_n = n;
00961     n += sizeof(aux_data_t);
00962     aux_name_n = n = ROUNDUP(n);
00963     aux_name_len = aux_string_length(aux_name);
00964     n += (aux_name_len + 1) * sizeof(IIIMP_card16);
00965     if (num_intvals > 0) {
00966        integer_list_n = n = ROUNDUP(n);
00967        n += num_intvals * sizeof(int);
00968     }
00969     pstring_len = NULL;
00970     if (num_strvals > 0) {
00971        pstring_len = (int*) malloc(sizeof(int) * num_strvals);
00972        if (!pstring_len) return NULL;
00973        string_list_n = n = ROUNDUP(n);
00974        n += num_strvals * sizeof(aux_string_t);
00975        string_n = n = ROUNDUP(n);
00976        for (i = 0; i < num_strvals; i++) {
00977            pstring_len[i] = aux_string_length(pstrs[i]);
00978            n += (pstring_len[i] + 1) * sizeof(IIIMP_card16);
00979        }
00980     }
00981     p = (unsigned char*) malloc(n);
00982     if (!p) {
00983        if (pstring_len) g_free(pstring_len);
00984        return NULL;
00985     }
00986     memset(p, 0, n);
00987 
00988     pac = (AUXComposed*) p;
00989     pac->len = n;
00990     pac->ev = ev;
00991     pad = (aux_data_t*)(p + aux_data_t_n);
00992     pac->pad = pad;
00993 
00994     if (aux) {
00995        pac->aux = aux;
00996        pad->im = aux->im->im_id;
00997        pad->ic = aux->im->ic_id;
00998     }
00999 
01000     pad->aux_index = class_idx;
01001     pad->aux_name = p + aux_name_n;
01002     memcpy(pad->aux_name, aux_name, (aux_name_len + 1) * sizeof(IIIMP_card16));
01003     pad->aux_name_length = aux_name_len * sizeof(IIIMP_card16);
01004 
01005     pad->integer_count = num_intvals;
01006     if (num_intvals > 0) {
01007        pad->integer_list = (int*)(p + integer_list_n);
01008        for (i = 0; i < num_intvals; i++) {
01009            pad->integer_list[i] = pintvals[i];
01010        }
01011     }
01012     pad->string_count = num_strvals;
01013     pad->string_ptr = p;
01014     if (num_strvals > 0) {
01015        aux_string_t *pas;
01016 
01017        pad->string_list = pas = (aux_string_t*)(p + string_list_n);
01018        p += string_n;
01019        for (i = 0; i < num_strvals; i++, pas++) {
01020            pas->length = pstring_len[i] * sizeof(IIIMP_card16);
01021            pas->ptr = p;
01022            n = (pstring_len[i] + 1) * sizeof(IIIMP_card16);
01023            memcpy(p, pstrs[i], n);
01024            p += n;
01025        }
01026     }
01027 
01028     if (pstring_len) g_free(pstring_len);
01029     return pac;
01030 
01031 #undef ROUNDUP
01032 }
01033 
01034 static AUXComposed*
01035 create_composed_from_aux_data(const aux_data_t *pad1, int *size)
01036 {
01037     unsigned char *p;
01038     AUXComposed *pac;
01039     aux_data_t *pad2;
01040 
01041     int i, n;
01042     int aux_data_t_n;
01043     int aux_name_n;
01044     int integer_list_n, string_list_n;
01045     int string_n;
01046 
01047 #define ROUNDUP(n) ((n + sizeof(int) - 1) / sizeof(int) * sizeof(int))
01048 
01049     /* first of all, caliculate size. */
01050     n = ROUNDUP(sizeof(AUXComposed));
01051     aux_data_t_n = n;
01052     n += sizeof(aux_data_t);
01053     aux_name_n = n = ROUNDUP(n);
01054     n += pad1->aux_name_length + sizeof(IIIMP_card16);
01055     integer_list_n = n = ROUNDUP(n);
01056     n += pad1->integer_count * sizeof(int);
01057     string_list_n = n = ROUNDUP(n);
01058     n += pad1->string_count * sizeof(aux_string_t);
01059     string_n = n = ROUNDUP(n);
01060     for (i = 0; i < pad1->string_count; i++) {
01061        n += pad1->string_list[i].length + sizeof(IIIMP_card16);
01062     }
01063 
01064     p = (unsigned char*) malloc(n);
01065     if (!p) return NULL;
01066     memset(p, 0, n);
01067 
01068     if (size)
01069       *size = n;
01070     pac = (AUXComposed*) p;
01071     pac->len = n;
01072     pad2 = (aux_data_t*)(p + aux_data_t_n);
01073     pac->pad = pad2;
01074 
01075     *pad2 = *pad1;
01076     pad2->aux_name = p + aux_name_n;
01077     memcpy(pad2->aux_name, pad1->aux_name, pad1->aux_name_length);
01078 
01079     if (pad1->integer_count > 0) {
01080        pad2->integer_list = (int*)(p + integer_list_n);
01081        memcpy(pad2->integer_list, pad1->integer_list,
01082               sizeof(int) * pad1->integer_count);
01083     } else {
01084        pad2->integer_list = NULL;
01085     }
01086 
01087     pad2->string_ptr = p;
01088     if (pad1->string_count > 0) {
01089        aux_string_t *pas1, *pas2;
01090 
01091        pas1= pad1->string_list;
01092        pad2->string_list = pas2 = (aux_string_t*)(p + string_list_n);
01093        p += string_n;
01094        for (i = 0; i < pad1->string_count; i++, pas1++, pas2++) {
01095            pas2->length = pas1->length;
01096            pas2->ptr = p;
01097            memcpy(p, pas1->ptr, pas2->length);
01098            p += pas2->length + sizeof(IIIMP_card16);
01099        }
01100     } else {
01101        pad2->string_list = NULL;
01102     }
01103 
01104     return pac;
01105 
01106 #undef ROUNDUP
01107 }
01108 
01109 static void
01110 delete_aux_ic(IIIMInputContext *context_iiim)
01111 {
01112     aux_t *aux;
01113     aux_im_data_t *aux_im;
01114     aux_ic_info_t *aux_ic;
01115     aux_ic_info_t *prev_aux_ic;
01116 
01117     aux = aux_get (context_iiim, NULL, (IIIMP_card16 *)"");
01118     if (aux)
01119       {
01120        for (aux_im = aux->im_list; aux_im; aux_im = aux_im->next) {
01121          if (aux_im->ae->if_version >= AUX_IF_VERSION_2
01122              && aux_im->ae->dir.method->destroy_ic != NULL)
01123            {
01124              aux->im = aux_im;
01125              aux_im->ae->dir.method->destroy_ic(aux);
01126            }
01127        }
01128       }
01129 
01130     prev_aux_ic = NULL;
01131     for (aux_ic = aux_ic_info; aux_ic != NULL; aux_ic = aux_ic->next) {
01132        if (aux_ic->ic_data == (aux_ic_data_t *)context_iiim) {
01133            if (prev_aux_ic == NULL)
01134               aux_ic_info = aux_ic->next;
01135            else
01136               prev_aux_ic->next = aux_ic->next;
01137            g_free(aux_ic); 
01138            break;
01139        }
01140     }
01141     prev_aux_ic = aux_ic;
01142 }
01143 
01144 /*
01145  * aux service function
01146  */
01147 
01148 static void
01149 service_aux_setvalue(
01150     aux_t * aux,
01151     const unsigned char * p,
01152     int len
01153 )
01154 {
01155     AUXComposed *pac = (AUXComposed*) p;
01156 
01157     if (pac->ev) {
01158       /*im_context_aux_set_values (aux->ic->cur_context, pac->ev);*/ /*TODO*/
01159       ((IIIMInputContext *)(aux->ic))->im_context_aux_set_values(aux->ic->cur_context, pac->ev );
01160      ; 
01161     } else if (pac->pad) {
01162        int i;
01163        aux_data_t *pad = pac->pad;
01164        IIIMF_status st;
01165        IIIMCF_event ev;
01166        IIIMP_card32 *pintvals;
01167        const IIIMP_card16 **pstrs;
01168 
01169        if (pad->integer_count > 0) {
01170            pintvals = (IIIMP_card32*) malloc(sizeof(*pintvals) * pad->integer_count);
01171            if (!pintvals) return;
01172            for (i = 0; i < pad->integer_count; i++) {
01173               pintvals[i] = pad->integer_list[i];
01174            }
01175        } else {
01176            pintvals = NULL;
01177        }
01178        if (pad->string_count > 0) {
01179            pstrs = (const IIIMP_card16**) malloc(sizeof(*pstrs) * pad->string_count);
01180            if (!pstrs) {
01181               if (pintvals) g_free(pintvals);
01182               return;
01183            }
01184            for (i = 0; i < pad->string_count; i++) {
01185               pstrs[i] = (const IIIMP_card16*) pad->string_list[i].ptr;
01186            }
01187        } else {
01188            pstrs = NULL;
01189        }
01190 
01191        st = iiimcf_create_aux_setvalues_event((IIIMP_card16*) pad->aux_name,
01192                                           pad->aux_index,
01193                                           pad->integer_count,
01194                                           pintvals,
01195                                           pad->string_count,
01196                                           pstrs,
01197                                           &ev);
01198        if (st == IIIMF_STATUS_SUCCESS)
01199          /*im_context_aux_set_values ((IIIMInputContext*)aux->ic, ev);*/ /*TODO*/
01200          ((IIIMInputContext *)(aux->ic))->im_context_aux_set_values(aux->ic->cur_context, ev );
01201        if (pintvals) g_free(pintvals);
01202        if (pstrs) g_free(pstrs);
01203     }
01204 
01205 }
01206 
01207 static void
01208 service_aux_getvalue(
01209     aux_t * aux,
01210     const unsigned char * p,
01211     int len
01212 )
01213 {
01214     AUXComposed *pac = (AUXComposed*) p;
01215 
01216     if (pac->ev)
01217       /*im_context_aux_get_values ((IIIMInputContext*)aux->ic, pac->ev);*/ /*TODO*/
01218        ((IIIMInputContext *)(aux->ic))->im_context_aux_set_values(aux->ic->cur_context, pac->ev );
01219     else if (pac->pad) {
01220        int i;
01221        aux_data_t *pad = pac->pad;
01222        IIIMF_status st;
01223        IIIMCF_event ev;
01224        IIIMP_card32 *pintvals;
01225        const IIIMP_card16 **pstrs;
01226 
01227        if (pad->integer_count > 0) {
01228            pintvals = (IIIMP_card32*) malloc(sizeof(*pintvals) * pad->integer_count);
01229            if (!pintvals) return;
01230            for (i = 0; i < pad->integer_count; i++) {
01231               pintvals[i] = pad->integer_list[i];
01232            }
01233        } else {
01234            pintvals = NULL;
01235        }
01236        if (pad->string_count > 0) {
01237            pstrs = (const IIIMP_card16**) malloc(sizeof(*pstrs) * pad->string_count);
01238            if (!pstrs) {
01239               if (pintvals) g_free(pintvals);
01240               return;
01241            }
01242            for (i = 0; i < pad->string_count; i++) {
01243               pstrs[i] = (const IIIMP_card16*) pad->string_list[i].ptr;
01244            }
01245        } else {
01246            pstrs = NULL;
01247        }
01248 
01249        st = iiimcf_create_aux_getvalues_event((IIIMP_card16*) pad->aux_name,
01250                                           pad->aux_index,
01251                                           pad->integer_count,
01252                                           pintvals,
01253                                           pad->string_count,
01254                                           pstrs,
01255                                           &ev);
01256        if (st == IIIMF_STATUS_SUCCESS)
01257          /*im_context_aux_get_values((IIIMInputContext*)aux->ic, ev);*/ /*TODO*/
01258          ((IIIMInputContext *)(aux->ic))->im_context_aux_set_values(aux->ic->cur_context, ev );
01259        if (pintvals) g_free(pintvals);
01260        if (pstrs) g_free(pstrs);
01261     }
01262 
01263 }
01264 
01265 static int
01266 service_im_id(
01267     aux_t * aux
01268 )
01269 {
01270     return aux->im->im_id;
01271 }
01272 
01273 
01274 static int
01275 service_ic_id(
01276     aux_t * aux
01277 )
01278 {
01279     return aux->im->ic_id;
01280 }
01281 
01282 
01283 static void
01284 service_data_set(
01285     aux_t * aux,
01286     int im_id,
01287     void * data
01288 )
01289 {
01290     aux_im_data_t *  aux_im;
01291 
01292     for (aux_im = aux->im; NULL != aux_im; aux_im = aux_im->next) {
01293        if (im_id == aux_im->im_id) {
01294            aux_im->data = data;
01295        }
01296     }
01297 
01298     return;
01299 }
01300 
01301 
01302 static void *
01303 service_data_get(
01304     aux_t * aux,
01305     int im_id
01306 )
01307 {
01308     aux_im_data_t *  aux_im;
01309 
01310     for (aux_im = aux->im; NULL != aux_im; aux_im = aux_im->next) {
01311        if (im_id == aux_im->im_id) {
01312            return aux_im->data;
01313        }
01314     }
01315 
01316     return NULL;
01317 }
01318 
01319 
01320 static Display *
01321 service_display(
01322     aux_t * aux
01323 )
01324 {
01325   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01326   Display *display =  context->get_focus_widget()->x11Display(); 
01327   if (display != NULL)
01328     return display;
01329   else
01330     return NULL;  /*TODO*/
01331 
01332 }
01333 
01334 
01335 static Window
01336 service_window(
01337     aux_t * aux
01338 )
01339 {
01340   QWidget *w;
01341 
01342   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01343   
01344   w = context->get_focus_widget();
01345 
01346   if(w)     
01347     return w->winId();
01348   else
01349     return None;/*TODO*/
01350 }
01351 
01352 static XPoint *
01353 service_point(
01354     aux_t * aux,
01355     XPoint * point
01356 )
01357 {
01358   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01359 
01360   point->x = context->cursor_x;
01361   point->y = context->cursor_y  + context->cursor_h;
01362   return point; /*TODO*/
01363 }
01364 
01365 static XPoint *
01366 service_point_caret(
01367     aux_t * aux,
01368     XPoint * point
01369 )
01370 {
01371   return service_point(aux, point);
01372 }
01373 
01374 /*
01375   convert a utf16 string into a string in locale's encoding
01376   Return value : The byte length of the converted string
01377 */
01378 static size_t
01379 service_utf16_mb (
01380     const char **inbuf,
01381     size_t *inbytesleft,
01382     char **outbuf,
01383     size_t *outbytesleft
01384 )
01385 {
01386   gchar *utf8_string = NULL;
01387   gsize bytes_read = 0, bytes_written = 0;
01388   gchar *result = NULL;
01389 
01390   utf8_string = convert_to_string ((const IIIMP_card16 *)(*inbuf));
01391   result = g_locale_from_utf8 (utf8_string, -1,
01392                             &bytes_read, &bytes_written, NULL);
01393   strcpy (*outbuf, result);
01394   outbuf += bytes_written;
01395   *inbytesleft -= bytes_read;
01396   *outbytesleft -= bytes_written;
01397 
01398   g_free (utf8_string);
01399   g_free (result);
01400   return (size_t)bytes_written;  
01401 }
01402 
01403 /*
01404   convert a string in locale's encoding into a utf16 string.
01405   Return value : The byte length of the converted string
01406 */
01407 static size_t
01408 service_mb_utf16(
01409     const char **inbuf,
01410     size_t *inbytesleft,
01411     char **outbuf,
01412     size_t *outbytesleft
01413 )
01414 {
01415   gchar *utf8_string = NULL;
01416   gsize bytes_read = 0, bytes_written = 0;
01417   gsize r;
01418   gunichar2 *result = NULL;
01419 
01420   utf8_string = g_locale_to_utf8 ((const char*)(*inbuf), *inbytesleft,
01421                               &bytes_read, &bytes_written, NULL);
01422   result = convert_to_utf16 (utf8_string, -1, (glong*)&r);
01423 
01424   memcpy (*outbuf, result, r);
01425   outbuf += r;
01426   *inbytesleft -= bytes_read;
01427   *outbytesleft -= r;
01428 
01429   g_free (utf8_string);
01430   g_free (result);
01431 
01432   return (size_t)r;
01433 }
01434 
01435 
01436 static unsigned char *
01437 service_compose(
01438     const aux_data_t *pad,
01439     int *size
01440 )
01441 {
01442     AUXComposed *pac;
01443 
01444     pac = create_composed_from_aux_data(pad, size);
01445     return (unsigned char*) pac;
01446 }
01447 
01448 static int
01449 service_compose_size(
01450     aux_data_type_t type,
01451     const unsigned char *p
01452 )
01453 {
01454     /* now this function is dummy... */
01455     return 0;
01456 }
01457 
01458 static aux_data_t *
01459 service_decompose(
01460     aux_data_type_t type,
01461     const unsigned char * p
01462 )
01463 {
01464     AUXComposed *pac = (AUXComposed*) p;
01465 
01466     if (pac->pad) {
01467        pac = create_composed_from_aux_data(pac->pad, NULL);
01468        if (!pac) return NULL;
01469        pac->pad->type = type;
01470 
01471        return pac->pad;
01472     }
01473 
01474     if (pac->ev) {
01475        pac = create_composed_from_event(pac->aux, pac->ev);
01476        if (!pac) return NULL;
01477        pac->pad->type = type;
01478 
01479        return pac->pad;
01480     }
01481 
01482     return NULL;
01483 }
01484 
01485 static void
01486 service_decompose_free(
01487     aux_data_t *pad
01488 )
01489 {
01490     if (!pad) return;
01491     if (!pad->string_ptr) return;
01492     g_free(pad->string_ptr);
01493 }
01494 
01495 static void
01496 service_register_X_filter(
01497     Display * display,
01498     Window window,
01499     int       start_type,
01500     int       end_type,
01501     Bool (* filter)(Display *, Window, XEvent *, XPointer),
01502     XPointer client_data
01503 )
01504 {
01505     _XRegisterFilterByType(display, window, start_type, end_type,
01506                         filter, client_data); 
01507 
01508     return;
01509 }
01510 
01511 static void
01512 service_unregister_X_filter(
01513     Display *display,
01514     Window window,
01515     Bool (* filter)(Display *, Window, XEvent *, XPointer),
01516     XPointer client_data
01517 )
01518 {
01519     _XUnregisterFilter(display, window, filter, client_data); 
01520 }
01521 
01522 
01523 static Bool service_server( aux_t * aux)
01524 {
01525   return False;
01526 }
01527 
01528 static Window
01529 service_client_window(
01530     aux_t * aux
01531 )
01532 {
01533 
01534   QWidget *w;
01535 
01536   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01537   
01538   w = context->get_focus_widget();
01539 
01540   if(w)     
01541     return w->winId();
01542   else
01543     return None;/*TODO*/
01544 }
01545 
01546 static Window
01547 service_focus_window(
01548     aux_t * aux
01549 )
01550 {
01551   QWidget *w;
01552 
01553   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01554   
01555   w = context->get_focus_widget();
01556 
01557   if(w)     
01558     return w->winId();
01559   else
01560     return None;/*TODO*/
01561 }
01562 
01563 static int
01564 service_screen_number(
01565     aux_t * aux
01566 )
01567 {
01568   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01569   return (context->get_focus_widget()->x11Screen()); /*TODO*/
01570 }
01571 
01572 static int
01573 service_point_screen(
01574     aux_t * aux,
01575     XPoint * point
01576 )
01577 {
01578   Display *display;
01579   Window window = None;
01580   Window root_window = None;
01581   Window child = None;
01582   int screen_number;
01583   int new_x;
01584   int new_y;
01585 
01586   display = service_display (aux);
01587   if (display == NULL)
01588     {
01589       point->x = -1;
01590       point->y = -1;
01591       return -1;
01592     }
01593   screen_number = service_screen_number (aux);
01594   root_window = RootWindow (display, screen_number);
01595   service_point (aux, point);
01596   window = service_window (aux);
01597    XTranslateCoordinates (display, window, root_window,
01598                       point->x, point->y,
01599                       &new_x, &new_y, &child);
01600   point->x = new_x;
01601   point->y = new_y; 
01602 
01603   return screen_number;
01604 }
01605 
01606 static int
01607 service_point_caret_screen(
01608     aux_t * aux,
01609     XPoint * point
01610 )
01611 {
01612   return service_point_screen (aux, point);
01613 }
01614 
01615 static Bool
01616 service_get_conversion_mode(aux_t * aux)
01617 {
01618   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01619   Bool conversion_mode = FALSE;
01620 
01621   if (context)
01622     iiimcf_get_current_conversion_mode (context->cur_context,
01623                                    &conversion_mode); 
01624   return conversion_mode;
01625 }
01626 
01627 static void
01628 service_set_conversion_mode(aux_t * aux, int conversion_mode)
01629 {
01630   IIIMInputContext *context = (IIIMInputContext*)aux->ic;
01631   DEBUG_DO(printf("**IMAUX: service_set_conversion_mode\n"));
01632   if (context)
01633     {
01634       if (conversion_mode == 1)
01635         ((IIIMInputContext *)(aux->ic))->im_context_change_conversion_mode(aux->ic->cur_context, "on" );
01636       else
01637         ((IIIMInputContext *)(aux->ic))->im_context_change_conversion_mode(aux->ic->cur_context, "off" ); /*TODO*/
01638     }
01639 }
01640 
01641 static aux_t *
01642 service_aux_get_from_id(int im_id, int ic_id,
01643                      IIIMP_card16 *aux_name, int aux_name_length)
01644 {
01645   aux_ic_info_t *aux_ic;
01646 
01647   for (aux_ic = aux_ic_info; aux_ic != NULL; aux_ic = aux_ic->next) {
01648     if (aux_ic->im_id == im_id && aux_ic->ic_id == ic_id)
01649       break;
01650   }
01651   if (aux_ic == NULL)
01652     return NULL;
01653 
01654   return aux_get((IIIMInputContext *)aux_ic->ic_data, NULL, aux_name);
01655 }
01656 
01657 /* Local Variables: */
01658 /* c-file-style: "iiim-project" */
01659 /* End: */