(shift_state): Fix the condition of taking init actions.
[m17n/m17n-lib.git] / src / input.c
index 6172a12..3c3d55e 100644 (file)
@@ -1,5 +1,5 @@
 /* input.c -- input method module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -375,7 +375,22 @@ parse_action_list (MPlist *plist, MPlist *macros)
            }
          else if (action_name == Mpushback)
            {
-             if (! MPLIST_INTEGER_P (pl))
+             if (MPLIST_MTEXT_P (pl))
+               {
+                 MText *mt = MPLIST_MTEXT (pl);
+
+                 if (mtext_nchars (mt) != mtext_nbytes (mt))
+                   MERROR (MERROR_IM, -1);                 
+               }
+             else if (MPLIST_PLIST_P (pl))
+               {
+                 MPlist *p;
+
+                 MPLIST_DO (p, MPLIST_PLIST (pl))
+                   if (! MPLIST_SYMBOL_P (p))
+                     MERROR (MERROR_IM, -1);
+               }
+             else if (! MPLIST_INTEGER_P (pl))
                MERROR (MERROR_IM, -1);
            }
          else if (action_name == Mset || action_name == Madd
@@ -820,7 +835,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
   if (! state)
     state = (MIMState *) MPLIST_VAL (im_info->states);
 
-  MDEBUG_PRINT1 ("\n[IM] state-shift (%s)", MSYMBOL_NAME (state->name));
+  MDEBUG_PRINT1 ("\n  [IM] (shift %s)", MSYMBOL_NAME (state->name));
 
   /* Enter the new state.  */
   ic_info->state = state;
@@ -852,8 +867,6 @@ shift_state (MInputContext *ic, MSymbol state_name)
       ic->preedit_changed = ic->candidates_changed = 1;
       MPLIST_DO (p, ic_info->markers)
        MPLIST_VAL (p) = 0;
-      MPLIST_DO (p, ic_info->vars)
-       MPLIST_VAL (p) = 0;
       ic->cursor_pos = 0;
       memmove (ic_info->keys, ic_info->keys + ic_info->state_key_head,
               sizeof (int) * (ic_info->used - ic_info->state_key_head));
@@ -866,8 +879,7 @@ shift_state (MInputContext *ic, MSymbol state_name)
   if (! ic->status)
     ic->status = im_info->title;
   ic->status_changed = 1;
-  if (ic_info->key_head == ic_info->used
-      && ic_info->map == ic_info->state->map
+  if (ic_info->map == ic_info->state->map
       && ic_info->map->map_actions)
     {
       MDEBUG_PRINT (" init-actions:");
@@ -1216,14 +1228,51 @@ take_action_list (MInputContext *ic, MPlist *action_list)
        }
       else if (name == Mpushback)
        {
-         int num = MPLIST_INTEGER (args);
+         if (MPLIST_INTEGER_P (args))
+           {
+             int num = MPLIST_INTEGER (args);
+
+             if (num > 0)
+               ic_info->key_head -= num;
+             else
+               ic_info->key_head = num;
+             if (ic_info->key_head > ic_info->used)
+               ic_info->key_head = ic_info->used;
+           }
+         else if (MPLIST_MTEXT_P (args))
+           {
+             MText *mt = MPLIST_MTEXT (args);
+             int i, len = mtext_nchars (mt);
+             MSymbol key;
 
-         if (num > 0)
-           ic_info->key_head -= num;
+             ic_info->key_head--;
+             for (i = 0; i < len; i++)
+               {
+                 key = one_char_symbol[MTEXT_DATA (mt)[i]];
+                 if (ic_info->key_head + i < ic_info->used)
+                   ic_info->keys[ic_info->key_head + i] = key;
+                 else
+                   MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
+               }
+           }
          else
-           ic_info->key_head = num;
-         if (ic_info->key_head > ic_info->used)
-           ic_info->key_head = ic_info->used;
+           {
+             MPlist *plist = MPLIST_PLIST (args), *pl;
+             int i = 0;
+             MSymbol key;
+
+             ic_info->key_head--;
+
+             MPLIST_DO (pl, plist)
+               {
+                 key = MPLIST_SYMBOL (pl);
+                 if (ic_info->key_head < ic_info->used)
+                   ic_info->keys[ic_info->key_head + i] = key;
+                 else
+                   MLIST_APPEND1 (ic_info, keys, key, MERROR_IM);
+                 i++;
+               }
+           }
        }
       else if (name == Mcall)
        {
@@ -1335,12 +1384,20 @@ take_action_list (MInputContext *ic, MPlist *action_list)
            actions2 = NULL;
          else
            actions2 = MPLIST_PLIST (args);
+         MDEBUG_PRINT2 ("(%d,%d)", val1, val2);
          if (name == Mequal ? val1 == val2
              : name == Mless ? val1 < val2
              : val1 > val2)
-           ret = take_action_list (ic, actions1);
-         else if (actions2)
-           ret = take_action_list (ic, actions2);
+           {
+             MDEBUG_PRINT ("ok");
+             ret = take_action_list (ic, actions1);
+           }
+         else
+           {
+             MDEBUG_PRINT ("no");
+             if (actions2)
+               ret = take_action_list (ic, actions2);
+           }
          if (ret < 0)
            return ret;
        }
@@ -1393,14 +1450,16 @@ handle_key (MInputContext *ic)
   MSymbol key = ic_info->keys[ic_info->key_head];
   int i;
 
-  MDEBUG_PRINT2 ("[IM] handle `%s' in state %s", 
+  MDEBUG_PRINT2 ("  [IM] handle `%s' in state %s", 
                 MSYMBOL_NAME (key), MSYMBOL_NAME (ic_info->state->name));
 
   if (map->submaps)
     {
+      MSymbol alias;
+
       submap = mplist_get (map->submaps, key);
-      if (! submap && (key = msymbol_get (key, M_key_alias)) != Mnil)
-       submap = mplist_get (map->submaps, key);
+      if (! submap && (alias = msymbol_get (key, M_key_alias)) != Mnil)
+       submap = mplist_get (map->submaps, alias);
     }
 
   if (submap)
@@ -1414,7 +1473,10 @@ handle_key (MInputContext *ic)
        {
          MDEBUG_PRINT (" map-actions:");
          if (take_action_list (ic, map->map_actions) < 0)
-           return -1;
+           {
+             MDEBUG_PRINT ("\n");
+             return -1;
+           }
        }
       else if (map->submaps)
        {
@@ -1437,14 +1499,16 @@ handle_key (MInputContext *ic)
            {
              MDEBUG_PRINT (" branch-actions:");
              if (take_action_list (ic, map->branch_actions) < 0)
-               return -1;
+               {
+                 MDEBUG_PRINT ("\n");
+                 return -1;
+               }
            }
          /* If MAP is still not the root map, shift to the current
             state.  */
          if (ic_info->map != ic_info->state->map)
            shift_state (ic, ic_info->state->name);
        }
-      MDEBUG_PRINT ("\n");
     }
   else
     {
@@ -1493,8 +1557,8 @@ handle_key (MInputContext *ic)
            shift_state (ic,
                         ((MIMState *) MPLIST_VAL (im_info->states))->name);
        }
-      MDEBUG_PRINT ("\n");
     }
+  MDEBUG_PRINT ("\n");
   return 0;
 }
 
@@ -1520,8 +1584,6 @@ reset_ic (MInputContext *ic, MSymbol ignore)
   ic->candidate_list = NULL;
   ic->candidate_show = 0;
   ic->status_changed = ic->preedit_changed = ic->candidates_changed = 1;
-  if (ic_info->map && ic_info->map->map_actions)
-    take_action_list (ic, ic_info->map->map_actions);
 }
 
 static int
@@ -2192,6 +2254,9 @@ minput__init ()
   Minput_candidates_done = msymbol ("input-candidates-done");
   Minput_candidates_draw = msymbol ("input-candidates-draw");
   Minput_set_spot = msymbol ("input-set-spot");
+  Minput_focus_move = msymbol ("input-focus-move");
+  Minput_focus_in = msymbol ("input-focus-in");
+  Minput_focus_out = msymbol ("input-focus-out");
   Minput_toggle = msymbol ("input-toggle");
   Minput_reset = msymbol ("input-reset");
 
@@ -2367,9 +2432,13 @@ MSymbol Minput_candidates_start;
 MSymbol Minput_candidates_done;
 MSymbol Minput_candidates_draw;
 MSymbol Minput_set_spot;
+MSymbol Minput_focus_move;
+MSymbol Minput_focus_in;
+MSymbol Minput_focus_out;
 MSymbol Minput_toggle;
 MSymbol Minput_reset;
 /*** @} */
+
 /*=*/
 
 /***en
@@ -2490,6 +2559,8 @@ minput_open_im (MSymbol language, MSymbol name, void *arg)
   MInputMethod *im;
   MInputDriver *driver;
 
+  MDEBUG_PRINT2 ("  [IM] opening (%s %s) ... ",
+        msymbol_name (language), msymbol_name (name));
   if (language)
     driver = minput_driver;
   else
@@ -2506,9 +2577,11 @@ minput_open_im (MSymbol language, MSymbol name, void *arg)
   im->driver = *driver;
   if ((*im->driver.open_im) (im) < 0)
     {
+      MDEBUG_PRINT (" failed\n");
       free (im);
       return NULL;
     }
+  MDEBUG_PRINT (" ok\n");
   return im;
 }
 
@@ -2529,8 +2602,11 @@ minput_open_im (MSymbol language, MSymbol name, void *arg)
 void
 minput_close_im (MInputMethod *im)
 {
+  MDEBUG_PRINT2 ("  [IM] closing (%s %s) ... ",
+                msymbol_name (im->name), msymbol_name (im->language));
   (*im->driver.close_im) (im);
   free (im);
+  MDEBUG_PRINT (" done\n");
 }
 
 /*=*/
@@ -2567,6 +2643,8 @@ minput_create_ic (MInputMethod *im, void *arg)
 {
   MInputContext *ic;
 
+  MDEBUG_PRINT2 ("  [IM] creating context (%s %s) ... ",
+                msymbol_name (im->name), msymbol_name (im->language));
   MSTRUCT_CALLOC (ic, MERROR_IM);
   ic->im = im;
   ic->arg = arg;
@@ -2578,6 +2656,7 @@ minput_create_ic (MInputMethod *im, void *arg)
   ic->plist = mplist ();
   if ((*im->driver.create_ic) (ic) < 0)
     {
+      MDEBUG_PRINT (" failed\n");
       M17N_OBJECT_UNREF (ic->preedit);
       M17N_OBJECT_UNREF (ic->produced);
       M17N_OBJECT_UNREF (ic->plist);
@@ -2592,6 +2671,7 @@ minput_create_ic (MInputMethod *im, void *arg)
       minput__callback (ic, Minput_status_draw);
     }
 
+  MDEBUG_PRINT (" ok\n");
   return ic;
 }
 
@@ -2618,6 +2698,8 @@ minput_create_ic (MInputMethod *im, void *arg)
 void
 minput_destroy_ic (MInputContext *ic)
 {
+  MDEBUG_PRINT2 ("  [IM] destroying context (%s %s) ... ",
+                msymbol_name (ic->im->name), msymbol_name (ic->im->language));
   if (ic->im->driver.callback_list)
     {
       minput__callback (ic, Minput_preedit_done);
@@ -2628,6 +2710,7 @@ minput_destroy_ic (MInputContext *ic)
   M17N_OBJECT_UNREF (ic->preedit);
   M17N_OBJECT_UNREF (ic->produced);
   M17N_OBJECT_UNREF (ic->plist);
+  MDEBUG_PRINT (" done\n");
   free (ic);
 }