Back to index

im-sdk  12.3.91
koinput.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: Karl Park <karl.park@sun.com>
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025 
00026 #include <stdio.h>
00027 #include <ctype.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <sys/stat.h>
00031 #include <dlfcn.h>
00032 #include <assert.h>
00033 
00034 #include "koinput.h"
00035 #include "kole.h"
00036 #include "xaux_locale.h"
00037 #include "encode.h"
00038 #include "kolelog.h"
00039 
00040 #define MAX_LINE_LEN 256
00041 
00042 int                   g_number_of_engines;
00043 const int             g_default_engine_id = 0;
00044 IMEEngineRec  *g_engines[MAX_ENGINE_NUM];
00045 
00046 static void print_core (void);
00047 static void get_ime_line (FILE *fd, char *line);
00048 
00049 
00050 int
00051 koinput_init (void)
00052 {
00053   char   file_name[256], line[MAX_LINE_LEN]; 
00054   char   *engine_name, *engine_path, *engine_options;
00055   char   locale_name[128], *kptr, *ptr;
00056     
00057   int    len, i;
00058   int    locale_flag = ENCODE_ERROR;
00059   FILE   *fd;
00060   int    ret = 0;
00061 
00062 
00063   g_number_of_engines = 0;
00064   for (i=0; i<MAX_ENGINE_NUM; i++)
00065     g_engines[i] = NULL;
00066 
00067   sprintf(file_name, "%s/%s",  LE_IME_MODULES_DIR,
00068          SYSTEM_PROFILE_NAME);
00069 
00070   KOLE_LOG (LOGDEST_STDOUT, "file name :%s\n",file_name);
00071   fd = fopen(file_name, "r");
00072   if (!fd)
00073     return (-1);
00074 
00075   do
00076     {
00077       get_ime_line(fd, line);
00078       if (line[0] == '\0') break;
00079       if (line[0] == '#') continue;
00080 
00081       len = strlen(line);
00082       if (line[0] == '[' && line[len-1] == ']') 
00083        {
00084          /* compute locale_flag */
00085          ptr = line + 1;
00086          while(isspace(*ptr)) ptr++;
00087          /* get locale section name */
00088          kptr = locale_name;
00089          while (*ptr && !isspace(*ptr) && *ptr!=']') 
00090            *(kptr++) = *(ptr++);
00091          *kptr = '\0';
00092 
00093          /* get locale section name */
00094          if (!strcasecmp(locale_name, COMMON_ENGINE_PATH))
00095            locale_flag = ENCODES_NUM;
00096          else
00097            locale_flag = get_encodeid_from_locale(locale_name);
00098          KOLE_LOG (LOGDEST_STDOUT, "locale_name:%s, locale_id:%d\n", locale_name, locale_flag);
00099          continue;
00100        }
00101 
00102       if (locale_flag == ENCODE_ERROR) continue;
00103       /* get IME language engine name */
00104       ptr = line;
00105       engine_name = line;
00106       while (*ptr && !isspace(*ptr)) ptr++;
00107       if (*ptr) {
00108        *ptr = '\0';
00109        ptr++;
00110       }
00111        
00112       while (*ptr && isspace(*ptr)) ptr++;
00113       engine_path = ptr;
00114 
00115       while (*ptr && !isspace(*ptr)) ptr++;
00116       if (*ptr) {
00117        *ptr = '\0';
00118        ptr++;
00119       }
00120       while (*ptr && isspace(*ptr)) ptr++;
00121       engine_options = ptr;
00122 
00123       KOLE_LOG (LOGDEST_STDOUT, "locale_id:%d, locale:%s, Engine Name:%s\n", 
00124           locale_flag, locale_name, engine_name, 
00125           engine_path, engine_options);
00126 
00127       printf ("locale_id:%d, locale:%s, Engine Name:%s\n", 
00128           locale_flag, locale_name, engine_name, 
00129           engine_path, engine_options);
00130 
00131       ret = open_engine (locale_flag, locale_name, 
00132                       engine_name, engine_path, engine_options);
00133       if (ret == -1)
00134        return -1;
00135 
00136     } while (1);     /* end of do */
00137 
00138   fclose(fd);
00139 #if 0  
00140   print_core();
00141 #endif
00142   return 0;
00143 }
00144 
00145 static void
00146 get_ime_line (FILE *fd, char *line)
00147 {
00148   int line_ptr;
00149   char line_buf[256], *ptr;
00150 
00151   line_ptr = 0;
00152   line[0] = '\0';
00153 
00154   /* get line with no space */
00155   while(fgets(line_buf, 255, fd) != NULL) {
00156     ptr = line_buf;
00157 
00158     /* skip space keys */
00159     while(*ptr && isspace(*ptr)) ptr++;
00160 
00161     /* if is space line, get new line */
00162     if (*ptr == '\n' || *ptr == '\0')
00163       continue;
00164 
00165     while(*ptr != '\n' && *ptr != '\0' && line_ptr < MAX_LINE_LEN) 
00166       line[line_ptr++] = *ptr++;
00167 
00168     /* trim right space */
00169     while (isspace(line[line_ptr-1])) line_ptr--;
00170     line[line_ptr] = '\0';
00171 
00172     /* if the line end with '\', then continue read the next line */
00173     if (line[line_ptr-1] == '\\') {
00174       line_ptr--;
00175       line[line_ptr] = '\0';
00176       continue;
00177     }
00178 
00179     break;
00180   }
00181 }
00182 
00183 /* engine_options can be data_path or engine options. */
00184 int
00185 open_engine (int locale_id, char *locale_name, char *engine_name, 
00186             char *engine_path, char *engine_options)
00187 {
00188   int         i;
00189   char        file_name[256];
00190   char        data_path[256];
00191   struct      stat   file_buffer;
00192   Bool          mthd_return;
00193 
00194   void        *so_handler;
00195   IMEBufferMethods   methods;
00196 
00197   int         is_codetable_engine = 0;
00198 
00199   int ret_noptions;
00200   KOLE_config **kole_options;
00201   char *option_file;
00202 
00203   if (g_number_of_engines > MAX_ENGINE_NUM)
00204     return (-1);
00205     
00206   /* read profile from file to memory buffer  */ 
00207   if (*engine_path) {
00208     if (engine_path[0] != '/') {
00209       sprintf(file_name, 
00210              "%s/%s",  LE_IME_MODULES_DIR, 
00211              engine_path);
00212                      
00213     } else {
00214       sprintf(file_name, "%s", engine_path);
00215     }
00216 
00217     KOLE_LOG (LOGDEST_STDOUT, "file_name: %s\n", file_name);
00218   } else {
00219     is_codetable_engine = 1;
00220     sprintf(file_name, "%s/%s.so", LE_IME_MODULES_DIR,
00221            engine_name);
00222               
00223     KOLE_LOG (LOGDEST_STDOUT, "file_name: %s\n", file_name);
00224   }
00225 
00226   if ((stat(file_name, &file_buffer)) == -1) {
00227     if (is_codetable_engine) {
00228       sprintf(file_name, "%s/%s.so", LE_IME_MODULES_DIR,
00229              CODETABLE_ENGINE_NAME);
00230       if ((stat(file_name, &file_buffer)) == -1)
00231        return (-1);
00232     } else {
00233       return (-1);
00234     }
00235   }
00236   KOLE_LOG (LOGDEST_STDOUT, "so_file_name:%s\n", file_name);
00237 
00238   so_handler = (void *) dlopen(file_name, RTLD_LAZY);
00239   assert (so_handler != NULL);
00240   if (!so_handler) {
00241     printf("can not open so file: %s\n", file_name);
00242     return (-1);
00243   } else {
00244     methods = (IMEBufferMethods) dlsym(so_handler, "ime_methods");
00245     assert (methods != NULL);
00246     if (!methods) {
00247       printf("can not open method tables of file:%s\n", file_name);
00248       dlclose(so_handler);
00249       return(-1);
00250     }
00251   }
00252 
00253   printf("file_name: %s\n", file_name);
00254   g_engines[g_number_of_engines] = (IMEEngineRec *)calloc(1, sizeof(IMEEngineRec));
00255   if (g_engines[g_number_of_engines] == NULL) return(0);
00256 
00257   g_engines[g_number_of_engines]->core.baseinfo.engine_id = g_number_of_engines;
00258   g_engines[g_number_of_engines]->core.baseinfo.locale_id = locale_id;
00259   g_engines[g_number_of_engines]->core.baseinfo.status = ENGINE_NOT_INITIATED;
00260   g_engines[g_number_of_engines]->core.baseinfo.ename = (char *)strdup(engine_name);
00261 
00262   g_engines[g_number_of_engines]->core.envinfo.lang_name = (char *)strdup(XAUX_LOCALE_NAME);
00263   g_engines[g_number_of_engines]->core.envinfo.locale_name = (char *)strdup(locale_name);
00264   g_engines[g_number_of_engines]->core.envinfo.data_path = NULL;
00265   g_engines[g_number_of_engines]->core.envinfo.data_ptr = NULL;
00266 
00267   g_engines[g_number_of_engines]->core.keymapinfo.bSet = 0;
00268   for (i=0; i<MAX_KEYMAP_KEY_NUM; i++) 
00269     g_engines[g_number_of_engines]->core.keymapinfo.keymap[i] = NULL;
00270 
00271   g_engines[g_number_of_engines]->so_handler = so_handler;
00272   g_engines[g_number_of_engines]->so_methods = methods;
00273 
00274   if (!(option_file = getenv ("KOLE_OPTION_FILE"))){
00275     mthd_return =
00276       get_configuration (DEFAULT_KOLE_OPTION_FILE, &ret_noptions, &kole_options);
00277   } else
00278     mthd_return =
00279       get_configuration (option_file, &ret_noptions, &kole_options);
00280 
00281   mthd_return = True;
00282 
00283   if (mthd_return)
00284     mthd_return = (*methods->ime_engine_start) (ret_noptions, kole_options);
00285   else /* set default here in case there was problem with reading option */
00286     mthd_return = (*methods->ime_engine_start) (0, NULL);
00287   
00288   if (mthd_return == False) {
00289     KOLE_LOG (LOGDEST_STDERR,
00290              "Failed to initialize the input method engine:%s\n", engine_name);
00291     dlclose (so_handler);
00292     return (-1);
00293   }
00294 
00295   mthd_return =
00296     (*methods->ime_engine_get_hotkeys) (&g_engines[g_number_of_engines]->core.hotkeys.n_count,&g_engines[g_number_of_engines]->core.hotkeys.keylist);
00297   
00298   if (mthd_return == False){
00299     KOLE_LOG (LOGDEST_STDERR,
00300              "Failed to get list of hotkeys, ignoring...");
00301   }
00302   g_number_of_engines ++;
00303   
00304   return (0);
00305 }
00306 
00307 void
00308 koinput_done (void)
00309 {
00310   int i;
00311   char *name;
00312 
00313   for(i=0; i<g_number_of_engines; i++) {
00314     name = g_engines[i]->core.baseinfo.ename;
00315     if (name) free(name);
00316 
00317     name = g_engines[i]->core.envinfo.lang_name;
00318     if (name) free(name);
00319 
00320     name = g_engines[i]->core.envinfo.locale_name;
00321     if (name) free(name);
00322 
00323     if (g_engines[i]->core.hotkeys.n_count > 0){
00324       int j;
00325       for (j = 0; j < g_engines[i]->core.hotkeys.n_count; j++)
00326        free (g_engines[i]->core.hotkeys.keylist[j]);
00327     }
00328     g_engines[i]->so_methods->ime_engine_finish(&(g_engines[i]->core));
00329     dlclose(g_engines[i]->so_handler);
00330     free ((char *)g_engines[i]);
00331     g_engines[i] = NULL;
00332   }
00333   g_number_of_engines = 0;
00334 }
00335 
00336 static void
00337 print_core (void)
00338 {
00339   int i;
00340 
00341   KOLE_LOG (LOGDEST_STDOUT, "g_number_of_engines:%d\n", g_number_of_engines);
00342   for (i = 0; i < g_number_of_engines ; i++) {
00343     KOLE_LOG (LOGDEST_STDOUT, "localeid:%d, imid:%d, ename:%s, kname:%s, status:%d\n", 
00344         g_engines[i]->core.baseinfo.locale_id,
00345         g_engines[i]->core.baseinfo.engine_id,
00346         g_engines[i]->core.baseinfo.ename,
00347         g_engines[i]->core.baseinfo.kname,
00348         g_engines[i]->core.baseinfo.status);
00349   }
00350 }