[uim-commit] r757 - in trunk: . scm uim

kzk at freedesktop.org kzk at freedesktop.org
Sun Mar 6 09:57:03 PST 2005


Author: kzk
Date: 2005-03-06 09:57:01 -0800 (Sun, 06 Mar 2005)
New Revision: 757

Added:
   trunk/scm/scim.scm
Modified:
   trunk/configure.ac
   trunk/scm/Makefile.am
   trunk/uim/scim.cpp
Log:
* This is the first commit of "uim-scim", the result
  of my CodeFest at AOSS held at Beijing:-)
  In this revision, you can compose preedit and commit
  string, but seems imcomplete now.

* configure.ac
  - target scim version is SCIM 1.2.0, new stable version

* uim/scim.cpp
* scm/scim.scm
  - added

* scm/Makefile.am
  - add scim.scm


Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2005-03-06 13:52:14 UTC (rev 756)
+++ trunk/configure.ac	2005-03-06 17:57:01 UTC (rev 757)
@@ -56,18 +56,18 @@
 
 AC_ARG_WITH(scim,
   AC_HELP_STRING([--with-scim],
-                 [build against SCIM (experimental)]),
+                 [build against SCIM (too experimental)]),
   [
     case $with_scim in
       no)
         use_scim="no"
       ;;
       yes|*)
-        PKG_CHECK_MODULES(SCIM, scim >= 1.0.0, use_scim="yes",use_scim="no")
+        PKG_CHECK_MODULES(SCIM, scim >= 1.2.0, use_scim="yes",use_scim="no")
       ;;
     esac
   ],
-  [ PKG_CHECK_MODULES(SCIM, scim >= 1.0.0, use_scim="yes",use_scim="no") ])
+  [ PKG_CHECK_MODULES(SCIM, scim >= 1.2.0, use_scim="yes",use_scim="no") ])
 
 # ***********************
 # *** Tests for Anthy ***

Modified: trunk/scm/Makefile.am
===================================================================
--- trunk/scm/Makefile.am	2005-03-06 13:52:14 UTC (rev 756)
+++ trunk/scm/Makefile.am	2005-03-06 17:57:01 UTC (rev 757)
@@ -26,13 +26,13 @@
  latin.scm \
  m17nlib.scm \
  spellcheck.scm spellcheck-custom.scm \
- zaurus.scm
+ zaurus.scm \
+ scim.scm
 
 if COMPAT_TABLE
 SCM_FILES += hk.scm
 endif
 
-
 module_names = "pyload"
 
 if ANTHY
@@ -58,7 +58,7 @@
 endif
 
 if SCIM
-#  module_names += "scim"
+  module_names += "scim"
 endif
 
 

Added: trunk/scm/scim.scm
===================================================================
--- trunk/scm/scim.scm	2005-03-06 13:52:14 UTC (rev 756)
+++ trunk/scm/scim.scm	2005-03-06 17:57:01 UTC (rev 757)
@@ -0,0 +1,353 @@
+;;;
+;;; Copyright (c) 2003-2005 uim Project http://uim.freedesktop.org/
+;;;
+;;; All rights reserved.
+;;;
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+;;; 1. Redistributions of source code must retain the above copyright
+;;;    notice, this list of conditions and the following disclaimer.
+;;; 2. Redistributions in binary form must reproduce the above copyright
+;;;    notice, this list of conditions and the following disclaimer in the
+;;;    documentation and/or other materials provided with the distribution.
+;;; 3. Neither the name of authors nor the names of its contributors
+;;;    may be used to endorse or promote products derived from this software
+;;;    without specific prior written permission.
+;;;
+;;; THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+;;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+;;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;;; SUCH DAMAGE.
+;;;;
+
+(require-custom "generic-key-custom.scm")
+
+;;; user configs
+
+(define scim-candidate-max 10)
+
+;; key defs
+(define-key scim-on-key? 'generic-on-key?)
+(define-key scim-off-key? 'generic-off-key?)
+
+;; widgets and actions
+
+;; widgets
+(define scim-widgets '(widget_scim_input_mode))
+
+;; default activity for each widgets
+(define default-widget_scim_input_mode 'action_scim_off)
+
+;; actions of widget_scim_input_mode
+(define scim-input-mode-actions
+  '(action_scim_off
+    action_scim_on))
+
+
+;;; implementations
+
+(register-action 'action_scim_off
+		 (lambda (mc)
+		   (list
+		    'figure_scim_off
+		    "-"
+		    (N_ "off")
+		    (N_ "Direct Input Mode")))
+		 (lambda (mc)
+		   (not (scim-context-on mc)))
+		 (lambda (mc)
+		   (scim-context-set-on! mc #f)))
+
+(register-action 'action_scim_on
+		 (lambda (mc)
+		   (let* ((im (scim-context-im mc))
+			  (name (symbol->string (im-name im))))
+		     (list
+		      'figure_scim_on
+		      "O"
+		      (N_ "on")
+		      (string-append name (N_ " Mode")))))
+		 (lambda (mc)
+		   (scim-context-on mc))
+		 (lambda (mc)
+		   (scim-context-set-on! mc #t)))
+
+;; Update widget definitions based on action configurations. The
+;; procedure is needed for on-the-fly reconfiguration involving the
+;; custom API
+(define scim-configure-widgets
+  (lambda ()
+    (register-widget 'widget_scim_input_mode
+		     (activity-indicator-new scim-input-mode-actions)
+		     (actions-new scim-input-mode-actions))))
+
+(define scim-context-rec-spec
+  (append
+   context-rec-spec
+   ;; renamed from 'id' to avoid conflict with context-id
+   '((mc-id             #f)
+     (on                #f)
+     (showing-candidate #f))))
+
+(define-record 'scim-context scim-context-rec-spec)
+(define scim-context-new-internal scim-context-new)
+
+(define scim-context-new
+  (lambda (id im name)
+    (let ((mc (scim-context-new-internal id im))
+	  (mc-id (scim-lib-alloc-context name)))
+      (scim-context-set-widgets! mc scim-widgets)
+      (scim-context-set-mc-id! mc mc-id)
+      mc)))
+
+(define scim-update-preedit
+  (lambda (mc)
+    (let* ((mid (scim-context-mc-id mc)))
+      (if (scim-lib-preedit-changed? mid)
+	  (if (scim-lib-compose-mode? mid)
+	      (begin
+		(im-clear-preedit mc)
+		(im-pushback-preedit mc
+				     preedit-underline
+				     (scim-lib-get-left-of-candidate mid))
+		(im-pushback-preedit mc
+				     (+ preedit-reverse preedit-cursor)
+				     (scim-lib-get-selected-candidate mid))
+		(im-pushback-preedit mc
+				     preedit-underline
+				     (scim-lib-get-right-of-candidate mid))
+		(im-update-preedit mc))
+	      (begin
+		(im-clear-preedit mc)
+		(im-pushback-preedit mc
+				     preedit-underline
+				     (scim-lib-get-left-of-cursor mid))
+		(im-pushback-preedit mc
+				     preedit-cursor "")
+		(im-pushback-preedit mc
+				     preedit-underline
+				     (scim-lib-get-right-of-cursor mid))
+		(im-update-preedit mc))
+	      )))))
+
+(define scim-update-candidate
+  (lambda (mc)
+    (scim-lib-fill-new-candidates! (scim-context-mc-id mc))
+    (let* ((mid (scim-context-mc-id mc))
+	   (max (scim-lib-get-nr-candidates mid))
+	   (showing-candidate? (scim-context-showing-candidate mc))
+	   (candidates-changed? (scim-lib-candidates-changed? mid)))
+
+      ;; FIXME: Rewrite this seriese of if with cond.
+      ;; close candidate window
+      (if (or
+	   (and showing-candidate? candidates-changed?)
+	   (and showing-candidate? (not (scim-lib-candidate-show? mid))))
+	  (begin
+	    (im-deactivate-candidate-selector mc mid)
+	    (scim-context-set-showing-candidate! mc #f)))
+
+      (if (and
+	   (or
+	    candidates-changed?
+	    (and 
+	     (not showing-candidate?)
+	     (scim-lib-candidate-show? mid)))
+	   (not (= max 0)))
+	  (begin
+	    (im-activate-candidate-selector
+	     mc max scim-candidate-max)
+	    (im-select-candidate
+	     mc (scim-lib-get-candidate-index mid))
+	    (scim-context-set-showing-candidate! mc #t)))
+
+      (if (and showing-candidate?
+	       (scim-lib-candidate-show? mid))
+	  (im-select-candidate mc (scim-lib-get-candidate-index mid))))))
+
+
+(define scim-append-modifiers
+  (lambda (key key-state key-str)
+    (if (shift-key-mask key-state)
+	(set! key-str (string-append "S-" key-str)))
+    (if (control-key-mask key-state)
+	(set! key-str (string-append "C-" key-str)))
+    (if (alt-key-mask key-state)
+	(set! key-str (string-append "A-" key-str)))
+    (if (meta-key-mask key-state)
+	(set! key-str (string-append "M-" key-str)))
+    key-str))
+
+(define scim-proc-direct-state
+  (lambda (mc key key-state)
+   (if (scim-on-key? key key-state)
+       (scim-context-set-on! mc #t)
+       (scim-commit-raw mc))))
+
+(define scim-commit-raw
+  (lambda (mc)
+    (im-commit-raw mc)))
+
+
+; Unfortunatelly, we don't have simple way to translate...
+(define scim-translate-ukey-to-mkey
+  (lambda (key key-state)
+    (scim-append-modifiers
+     key key-state
+     (cdr (assq key
+		'((backspace       . "BackSpace")
+		  (delete          . "Delete")
+		  (escape          . "Escape")
+		  (return          . "Return")
+		  (tab             . "Tab")
+		  (left            . "Left")
+		  (up              . "Up")
+		  (right           . "Right")
+		  (down            . "Down")
+		  (prior           . "Page_Down")
+		  (next            . "Page_Up")
+		  (home            . "Home")
+		  (end             . "End")
+		  (zenkaku-hankaku . "")
+		  (Multi_key       . "")
+		  (Mode_switch     . "")
+		  (Henkan_Mode     . "")
+		  (Muhenkan        . "")
+		  (F1              . "F1")
+		  (F2              . "F2")
+		  (F3              . "F3")
+		  (F4              . "F4")
+		  (F5              . "F5")
+		  (F6              . "F6")
+		  (F7              . "F7")
+		  (F8              . "F8")
+		  (F9              . "F9")
+		  (F10             . "F10")
+		  (F11             . "F11")
+		  (F12             . "F12")
+		  (F13             . "F13")
+		  (F14             . "F14")
+		  (F15             . "F15")
+		  (F16             . "F16")
+		  (F17             . "F17")
+		  (F18             . "F18")
+		  (F19             . "F19")
+		  (F20             . "F20")))))))
+  
+(define scim-init-handler
+  (lambda (id im arg)
+    (scim-context-new id im arg)))
+
+(define scim-release-handler
+  (lambda (mc)
+    #f))
+
+(define scim-push-key
+  (lambda (mc key key-state)
+    (let* ((mid (scim-context-mc-id mc)))
+      (cond
+       ((scim-off-key? key key-state)
+	(scim-context-set-on! mc #f)
+	#t) ;; #t means key event was consumed.
+       ((symbol? key)
+	(let ((mkey (scim-translate-ukey-to-mkey key key-state)))
+	  (scim-lib-push-symbol-key mid mkey)))
+       (else
+	(scim-lib-push-key mid key key-state))))))
+
+(define scim-press-key-handler
+  (lambda (mc key key-state)
+    (let* ((mid (scim-context-mc-id mc)))
+      (if (scim-context-on mc)
+	  (if (scim-push-key mc key key-state)
+	      #f ;; Discard key event
+	      (let* ((result (scim-lib-get-result mid))
+		     (consumed? (car result))
+		     (commit-str (cdr result)))
+		(if (string=? commit-str "")
+		    (im-commit-raw mc)
+		    (begin
+		      (im-commit mc commit-str)
+		      (scim-lib-commit mid)
+		      (if (not consumed?)
+			  (im-commit-raw mc))))))
+	  (scim-proc-direct-state mc key key-state))
+      (scim-update-preedit mc)
+      (scim-update-candidate mc))))
+
+(define scim-release-key-handler
+  (lambda (mc key key-state)
+    #f))
+
+(define scim-reset-handler
+  (lambda (mc)
+    #f))
+
+(define scim-get-candidate-handler
+  (lambda (mc idx accel-enum-hint)
+    (let* ((mid (scim-context-mc-id mc))
+	   (cand (scim-lib-get-nth-candidate
+		  mid idx)))
+      (list cand (digit->string (+ idx 1)) ""))))
+
+(define scim-set-candidate-index-handler
+  (lambda (mc idx)
+    #f))
+
+;; Developer specified IM rejection should be completely withdrawn
+;; after we got flexible install-time IM preference list. These
+;; redundant IMs should be "disabled by default, but can be enabled"
+;; under the feature. But we should invest our time for more valuable
+;; issues.  -- YamaKen 2005-01-25
+(define duplicated-im-list
+  '("scim-ja-anthy"
+    "scim-ja-tcode"
+    "scim-zh-pinyin"
+    "scim-zh-py"))
+
+;; At now, simply enable all IMs. Although they are redundant and
+;; unconfortable, they can be disabled by uim-pref.
+;;   -- YamaKen 2005-01-25
+(define duplicated-im?
+  (if #t
+      (lambda (name)
+	#f)
+      (lambda (name)
+	(member name duplicated-im-list))))
+
+(define scim-register
+  (lambda (i nr-im)
+    (if (> nr-im i)
+	(begin
+	  (if (not (duplicated-im? (scim-lib-nth-input-method-name i)))
+	      (register-im
+	       (string->symbol (scim-lib-nth-input-method-name i))
+	       (scim-lib-nth-input-method-lang i)
+	       "UTF-8"
+	       (scim-lib-nth-input-method-name i)
+	       (N_ "An input method provided by the scim library")
+	       (scim-lib-nth-input-method-name i)
+	       scim-init-handler
+	       scim-release-handler
+	       context-mode-handler
+	       scim-press-key-handler
+	       scim-release-key-handler
+	       scim-reset-handler
+	       scim-get-candidate-handler
+	       scim-set-candidate-index-handler
+	       context-prop-activate-handler
+	       ))
+	      (scim-register (+ i 1) nr-im))
+	())))
+
+(scim-lib-init)
+(scim-register 0 (scim-lib-nr-input-methods))
+(scim-configure-widgets)

Modified: trunk/uim/scim.cpp
===================================================================
--- trunk/uim/scim.cpp	2005-03-06 13:52:14 UTC (rev 756)
+++ trunk/uim/scim.cpp	2005-03-06 17:57:01 UTC (rev 757)
@@ -30,27 +30,625 @@
   SUCH DAMAGE.
 
 */
-
 #include "config.h"
 
+#define Uses_SCIM_CONFIG_PATH
+#define Uses_SCIM_IMENGINE_MODULE
 #define Uses_SCIM_BACKEND
-#define Uses_SCIM_IMENGINE
-#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_PANEL
+#define Uses_SCIM_SOCKET
+#define Uses_SCIM_SOCKET_TRANSACTION
 
 #include <scim.h>
+#include "uim.h"
 #include "uim-scm.h"
+#include "uim-compat-scm.h"
 #include "context.h"
 
 using namespace scim;
 
-void
-plugin_init(void)
+typedef struct SCIMInputMethod SCIMInputMethod;
+struct SCIMInputMethod {
+    WideString imname;
+    String lang;
+    String uuid;
+};
+
+typedef struct SCIMContext SCIMContext;
+struct SCIMContext {
+    IMEngineFactoryPointer factory;
+    IMEngineInstancePointer instance;
+    int id;
+
+    bool is_on;
+
+    WideString preedit_str;
+    AttributeList preedit_attr;
+    int preedit_caret;
+
+    int candidate_num;
+    char **candidates;
+};
+
+static int initialized = 0;
+
+static std::vector<String> engine_list;
+static std::vector<SCIMInputMethod *> im_list;
+static std::vector<SCIMContext *> context_list;
+static std::vector<String> config_modules;
+static std::vector<String> factories;
+
+static ConfigModule *config_module = NULL;
+static ConfigPointer config = NULL;
+
+static BackEndPointer be = NULL;
+static SocketClient panel;
+
+static int instance_count = 0;
+
+static void cb_commit( IMEngineInstanceBase *instance, const WideString &wstr );
+static void cb_preedit_update( IMEngineInstanceBase *instance, const WideString &wstr, const AttributeList &attr );
+static void cb_preedit_hide( IMEngineInstanceBase *instance );
+static void cb_preedit_caret( IMEngineInstanceBase *instance, int caret );
+static void cb_lookup_update( IMEngineInstanceBase *instance, const LookupTable &table );
+static void cb_lookup_show( IMEngineInstanceBase *instance );
+static void cb_lookup_hide( IMEngineInstanceBase *instance );
+
+static const int UIM_PREEDIT_FLAG_UNDERLINE = 1;
+static const int UIM_PREEDIT_FLAG_REVERSE   = 2;
+static const int UIM_PREEDIT_FLAG_CURSOR    = 4;
+static void uim_eval_im_commit(int id, const char *str);
+static void uim_eval_im_clear_preedit(int id);
+static void uim_eval_im_pushback_preedit(int id, int flag, const char *str);
+static void uim_eval_im_update_preedit(int id);
+static void uim_eval_im_activate_candidate_selector(int id, int nr_candidates, int display_limit);
+static void uim_eval_im_select_candidate(int id, int index);
+static void uim_eval_im_deactivate_candidate_selector(int id);
+
+static void uim_keysymbol_to_scim_keysymbol( const char *sym, KeyEvent *key );
+
+#define WideStr_to_CStr(widestr) ((char *)utf8_wcstombs(widestr).c_str())
+#define WideStr_to_String(widestr) ((String)utf8_wcstombs(widestr))
+
+static bool
+check_socket_frontend()
 {
+    SocketAddress address;
+    SocketClient client;
+    uint32 magic;
 
+    address.set_address (scim_get_default_socket_frontend_address ());
+
+    if (!client.connect (address))
+        return false;
+
+    if (!scim_socket_open_connection (magic,
+                                      String ("ConnectionTester"),
+                                      String ("SocketFrontEnd"),
+                                      client,
+                                      1000))
+    {
+        return false;
+    }
+    return true;
 }
 
-void
-plugin_quit(void)
+static void
+create_im_list()
 {
+    std::vector<IMEngineFactoryPointer> factories;
 
+    int num = be->get_factories_for_language( factories );
+
+    std::vector<IMEngineFactoryPointer>::iterator it = factories.begin();
+    for( ; it != factories.end(); ++it )
+    {
+        SCIMInputMethod *scim_im = new SCIMInputMethod();
+        scim_im->imname = (*it)->get_name();
+        scim_im->lang = (*it)->get_language();
+        scim_im->uuid = (*it)->get_uuid();
+
+        im_list.push_back( scim_im );
+    }
 }
+
+
+static uim_lisp
+init_scim()
+{
+    fprintf( stderr, "init_scm()\n" );
+    if( !initialized )
+    {
+        context_list.clear();
+
+        scim_get_imengine_module_list( engine_list );
+        if( std::find( engine_list.begin() , engine_list.end() , "socket") == engine_list.end() )
+        {
+            fprintf(stderr, "Could not find socket module.\n");
+            return uim_scm_f();
+        }
+
+        config_module = new ConfigModule( "simple" );
+        if( !config_module )
+        {
+            fprintf(stderr, "Could not create ConfigModule\n");
+            return uim_scm_f();
+        }
+
+        config = config_module->create_config( "scim" );
+        if( config.null() )
+        {
+            fprintf(stderr, "create_config failed\n");
+            return uim_scm_f();
+        }
+
+        be = new CommonBackEnd( config, engine_list );
+        if( be.null() )
+        {
+            fprintf(stderr, "create CommonBackEnd failed\n");
+            return uim_scm_f();
+        }
+
+        if( !check_socket_frontend() )
+        {
+            /*
+             * 2004-03-03 Kazuki Ohta <mover at hct.zaq.ne.jp> @ChinaOSS CodeFest
+             *
+             * If no SocketFrontend is runnig, launch a SCIM daemon.
+             */
+            fprintf(stderr, "launch SCIM daemon\n");
+            char *new_argv [] = { (char*)"--no-stay", 0 };
+            scim_launch( true,
+                         "simple", //FIX ME
+                         (engine_list.size () ? scim_combine_string_list( engine_list, ',' ) : "all"),
+                         "socket",
+                         new_argv );
+
+            return uim_scm_f();
+        }
+
+        create_im_list();
+
+        initialized = 1;
+    }
+
+    return uim_scm_t();
+}
+
+static uim_lisp
+get_nr_input_methods()
+{
+    return uim_scm_make_int( im_list.size() );
+}
+
+static uim_lisp
+get_input_method_lang(uim_lisp nth_)
+{
+    // FIXME
+    int nth = uim_scm_c_int( nth_ );
+    if( nth < im_list.size() )
+    {
+        return uim_scm_make_str( im_list.at( nth )->lang.c_str() );
+    }
+    
+    return uim_scm_f();
+}
+
+std::string& replace(std::string& str, const std::string sb, const std::string sa)
+{
+    std::string::size_type n, nb = 0;
+
+    while ((n = str.find(sb,nb)) != std::string::npos)
+    {
+        str.replace(n,sb.size(),sa);
+        nb = n + sa.size();
+    }
+
+    return str;
+}
+
+static uim_lisp
+get_input_method_name(uim_lisp nth_)
+{
+    int nth = uim_scm_c_int( nth_ );
+    if( nth < im_list.size() )
+    {
+        // remove space
+        String imname = WideStr_to_String( im_list.at( nth )->imname );
+        replace( imname, " ", "" );
+        const char *orig_name = imname.c_str();
+
+        // add "scim" as prefix
+        char *name = (char *)alloca( strlen(orig_name) + 20 );
+        if( name )
+        {
+            sprintf(name, "scim-%s", orig_name);
+            return uim_scm_make_str( name );
+        }
+
+        return uim_scm_f();
+    }
+
+    return uim_scm_f();
+}
+
+static String
+search_uuid_by_imname( String imname )
+{
+    fprintf(stderr, "search imname = %s\n", imname.c_str() );
+
+    
+    std::vector<SCIMInputMethod*>::iterator it = im_list.begin();
+    for( ; it != im_list.end(); ++it )
+    {
+        fprintf(stderr, "im = %s\n", WideStr_to_CStr( (*it)->imname));
+
+        // remove "scim-" prefix
+        String name = imname.substr( 5, imname.length() - 5 );
+        if( WideStr_to_String((*it)->imname) == name )
+        {
+            return (*it)->uuid;
+        }
+    }
+
+    return "";
+}
+
+static uim_lisp
+alloc_id( uim_lisp name_ )
+{
+    char *imname = uim_scm_c_str(name_);
+    fprintf(stderr, "scim.cpp : alloc_id = %s\n", imname);
+
+    SCIMContext *context = new SCIMContext();
+
+    // create factory by specifying the uuid
+    String uuid = search_uuid_by_imname( imname );
+    if( uuid.empty() )
+    {
+        fprintf( stderr, "failed to search uuid\n" );
+        return uim_scm_f();
+    }
+    context->factory = be->get_factory( uuid );
+
+    fprintf(stderr, "imname = %s\n", WideStr_to_CStr( context->factory->get_name() ));
+    fprintf(stderr, "lang = %s\n", context->factory->get_language().c_str() );
+
+    // initialize context's member variable
+    context->instance = context->factory->create_instance( "UTF-8", instance_count );
+    if( context->instance.null() )
+    {
+        fprintf(stderr, "failed to create IMEngineInstance\n");
+        return uim_scm_f();
+    }
+
+    context->id = instance_count;
+    context->is_on = false;
+
+    // set callbacks for the created instance
+    context->instance->signal_connect_commit_string( slot( cb_commit) );
+    context->instance->signal_connect_update_preedit_string( slot( cb_preedit_update) );
+    context->instance->signal_connect_hide_preedit_string( slot( cb_preedit_hide) );
+    context->instance->signal_connect_update_preedit_caret( slot( cb_preedit_caret) );
+    context->instance->signal_connect_update_lookup_table( slot( cb_lookup_update) );
+    context->instance->signal_connect_show_lookup_table( slot( cb_lookup_show) );
+    context->instance->signal_connect_hide_lookup_table( slot( cb_lookup_hide) );
+    /*
+    context->instance->signal_connect_register_properties( slot( cb_prop_register) );
+    context->instance->signal_connect_update_property( slot( cb_prop_update) );
+    */
+    context->instance->set_frontend_data( static_cast <void*> (context) );
+
+    // and store the context
+    context_list.push_back( context );
+
+    instance_count++;
+
+    free(imname);
+
+    return uim_scm_make_int( context->id );
+}
+
+static uim_lisp
+free_id(uim_lisp id_)
+{
+    return uim_scm_f();
+}
+
+static SCIMContext *get_context_from_id(int id)
+{
+    std::vector<SCIMContext*>::iterator it = context_list.begin();
+    for( ; it != context_list.end(); ++it )
+    {
+        if( id == (*it)->id )
+        {
+            return (*it);
+        }
+    }
+
+    return NULL;
+}
+
+static uim_lisp
+push_key(uim_lisp id_, uim_lisp key_, uim_lisp mod_)
+{
+    fprintf(stderr, "push_key!!!!!\n");
+    int id = uim_scm_c_int( id_ );
+    int code = uim_scm_c_int( key_ );
+    int mod = uim_scm_c_int( mod_ );
+
+    // FIXME
+    // adhoc
+    KeyEvent scim_key;
+    scim_key.code = code;
+    scim_key.mask = mod;
+
+    SCIMContext *ic = get_context_from_id( id );
+    if( ic->instance->process_key_event( scim_key ) )
+    {
+        return uim_scm_t();
+    }
+
+    return uim_scm_f();
+}
+
+static uim_lisp
+push_symbol_key(uim_lisp id_, uim_lisp key_, uim_lisp mod_)
+{
+    int id = uim_scm_c_int( id_ );
+    char *sym = uim_scm_c_str( key_ );
+
+    fprintf(stderr, "push_symbol_key = %s\n", sym);
+
+    KeyEvent scim_key;
+    uim_keysymbol_to_scim_keysymbol(sym, &scim_key);
+    free( sym );
+
+    SCIMContext *ic = get_context_from_id( id );
+    if( ic->instance->process_key_event( scim_key ) )
+    {
+
+        return uim_scm_t();
+    }
+
+    return uim_scm_f();
+}
+
+static uim_lisp
+get_nth_candidate( uim_lisp id_, uim_lisp idx_ )
+{
+    int id = uim_scm_c_int( id_ );
+    int idx = uim_scm_c_int( idx_ );
+
+    SCIMContext *ic = get_context_from_id( id );
+    if( !ic )
+    {
+        return uim_scm_f();
+    }
+
+    return uim_scm_f();
+}
+
+static void cb_commit( IMEngineInstanceBase *instance, const WideString &wstr )
+{
+    fprintf(stdout, "cb_commit\n");
+    SCIMContext *ic = static_cast<SCIMContext*>(instance->get_frontend_data());
+    if( !ic )
+    {
+        return;
+    }
+
+    ic->preedit_str = WideString();
+    ic->preedit_attr.clear();
+    ic->preedit_caret = 0;
+
+    uim_eval_im_clear_preedit( ic->id );
+    uim_eval_im_update_preedit( ic->id );
+    uim_eval_im_commit( ic->id, WideStr_to_CStr( wstr ) );
+}
+
+static void cb_preedit_update( IMEngineInstanceBase *instance, const WideString &wstr, const AttributeList &attr )
+{    
+    fprintf(stdout, "cb_preedit_update : preedit_str = [%s]\n", WideStr_to_CStr(wstr));
+
+    SCIMContext *ic = static_cast<SCIMContext*>(instance->get_frontend_data());
+    if( !ic )
+    {
+        return;
+    }
+
+    ic->preedit_str = wstr;
+    ic->preedit_attr = attr;
+
+    uim_eval_im_clear_preedit( ic->id );
+    uim_eval_im_pushback_preedit( ic->id, 0, WideStr_to_CStr(wstr) );
+    uim_eval_im_update_preedit( ic->id );
+}
+static void cb_preedit_hide( IMEngineInstanceBase *instance )
+{
+    fprintf(stdout, "cb_preedit_hide\n");
+
+    SCIMContext *ic = static_cast<SCIMContext*>(instance->get_frontend_data());
+    if( !ic )
+    {
+        return;
+    }
+
+    ic->preedit_str = WideString();
+    ic->preedit_attr.clear();
+
+    uim_eval_im_update_preedit( ic->id );
+}
+static void cb_preedit_caret( IMEngineInstanceBase *instance, int caret )
+{
+    fprintf(stdout, "cb_preedit_caret\n");
+
+    SCIMContext *ic = static_cast<SCIMContext*>(instance->get_frontend_data());
+    if( !ic )
+    {
+        return;
+    }
+
+    // FIXME
+    // makes nothing in present state
+    ic->preedit_caret = caret;
+
+    uim_eval_im_update_preedit( ic->id );
+}
+static void cb_lookup_update( IMEngineInstanceBase *instance, const LookupTable &table )
+{
+    fprintf(stdout, "cb_lookup_update\n");
+
+    SCIMContext *ic = static_cast<SCIMContext*>(instance->get_frontend_data());
+    if( !ic )
+    {
+        return;
+    }
+
+}
+static void cb_lookup_show( IMEngineInstanceBase *instance )
+{
+    fprintf(stdout, "cb_lookup_show\n");
+}
+static void cb_lookup_hide( IMEngineInstanceBase *instance )
+{
+    fprintf(stdout, "cb_lookup_hide\n");
+}
+
+static void
+uim_eval_im_commit(int id, const char *str)
+{
+  uim_lisp form = uim_scm_list3(uim_scm_make_symbol("im-commit"),
+				uim_scm_make_int(id),
+				uim_scm_make_str(str));
+  uim_scm_eval(form);
+}
+
+static void
+uim_eval_im_clear_preedit(int id)
+{
+  uim_lisp form = uim_scm_list2(uim_scm_make_symbol("im-clear-preedit"),
+				uim_scm_make_int(id));
+  uim_scm_eval(form);
+}
+
+static void
+uim_eval_im_pushback_preedit(int id, int flag, const char *str)
+{
+  uim_lisp form;
+  /*
+   * FIXME! : 2004-02-12 Kazuki Ohta <mover at hct.zaq.ne.jp>
+   * This is very adhoc hack!
+   * Consider multiple attr!
+   */
+  if (flag & UIM_PREEDIT_FLAG_CURSOR) {
+    form = uim_scm_list4(uim_scm_make_symbol("im-pushback-preedit"),
+			 uim_scm_make_int(id),
+			 uim_scm_make_symbol("preedit-cursor"),
+			 uim_scm_make_str(""));
+    uim_scm_eval(form);
+  } else if (flag & UIM_PREEDIT_FLAG_REVERSE)  {
+    form = uim_scm_list4(uim_scm_make_symbol("im-pushback-preedit"),
+			 uim_scm_make_int(id),
+			 uim_scm_make_symbol("preedit-reverse"),
+			 uim_scm_make_str(str));
+    uim_scm_eval(form);
+  } else {
+    form = uim_scm_list4(uim_scm_make_symbol("im-pushback-preedit"),
+			 uim_scm_make_int(id),
+			 uim_scm_make_symbol("preedit-underline"),
+			 uim_scm_make_str(str));
+    uim_scm_eval(form);
+  }
+
+}
+
+static void
+uim_eval_im_update_preedit(int id)
+{
+  uim_lisp form = uim_scm_list2(uim_scm_make_symbol("im-update-preedit"),
+				uim_scm_make_int(id));
+  uim_scm_eval(form);
+}
+
+static void uim_eval_im_activate_candidate_selector(int id, int nr_candidates, int display_limit)
+{
+  uim_lisp form = uim_scm_list4(uim_scm_make_symbol("im-activate-candidate-selector"),
+				uim_scm_make_int(id),
+				uim_scm_make_int(nr_candidates),
+				uim_scm_make_int(display_limit));
+  uim_scm_eval(form);
+}
+
+static void uim_eval_im_select_candidate(int id, int index)
+{
+  uim_lisp form = uim_scm_list3(uim_scm_make_symbol("im-select-candidate"),
+				uim_scm_make_int(id),
+				uim_scm_make_int(index));
+  uim_scm_eval(form);
+}
+
+static void uim_eval_im_deactivate_candidate_selector(int id)
+{
+  uim_lisp form = uim_scm_list2(uim_scm_make_symbol("im-deactivate-candidate-selector"),
+				uim_scm_make_int(id));
+  uim_scm_eval(form);
+}
+
+
+extern "C" void
+uim_plugin_instance_init(void)
+{
+    uim_scm_init_subr_0((char*)"scim-lib-init", init_scim);
+    uim_scm_init_subr_0((char*)"scim-lib-nr-input-methods", get_nr_input_methods);
+    uim_scm_init_subr_1((char*)"scim-lib-nth-input-method-lang", get_input_method_lang);
+    uim_scm_init_subr_1((char*)"scim-lib-nth-input-method-name", get_input_method_name);
+    uim_scm_init_subr_1((char*)"scim-lib-alloc-context", alloc_id);
+    uim_scm_init_subr_1((char*)"scim-lib-free-context", free_id);
+    uim_scm_init_subr_3((char*)"scim-lib-push-key", push_key);
+    uim_scm_init_subr_3((char*)"scim-lib-push-symbol-key", push_symbol_key);
+    uim_scm_init_subr_2((char*)"sicm-lib-nth-candidate", get_nth_candidate);
+}
+
+extern "C" void
+uim_plugin_instance_quit(void)
+{
+
+}
+
+static void
+uim_keysymbol_to_scim_keysymbol( const char *sym, KeyEvent *key )
+{
+    fprintf(stderr, "uim_keysymbol! : sym = %s\n", sym);
+    static struct keycode_map_ {
+        char *symbol;
+        unsigned int keycode;
+    } keycode_map[] = {
+        {(char*)"Escape", SCIM_KEY_Escape},
+        {(char*)"Tab", SCIM_KEY_Tab},
+        {(char*)"BackSpace", SCIM_KEY_BackSpace},
+        {(char*)"Delete", SCIM_KEY_Delete},
+        {(char*)"Return", SCIM_KEY_Return},
+        {(char*)"Left", SCIM_KEY_Left},
+        {(char*)"Up", SCIM_KEY_Up},
+        {(char*)"Right", SCIM_KEY_Right},
+        {(char*)"Down", SCIM_KEY_Down},
+        {(char*)"Prior", SCIM_KEY_Prior},
+        {(char*)"Next", SCIM_KEY_Next},
+        {(char*)"Home", SCIM_KEY_Home},
+        {(char*)"End", SCIM_KEY_End},
+        {NULL, 0}
+    };
+
+    struct keycode_map_ *l;
+    for( l = keycode_map; l->symbol; l++ )
+    {
+        if( strcmp(sym, l->symbol) == 0 )
+        {
+            fprintf(stderr, "keysymbol = %s\n", l->symbol);
+            (*key).code = l->keycode;
+            return;
+        }
+    }
+
+}



More information about the Uim-commit mailing list