Back to index

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