[openi18n-im:01412] patch to support key release event

Federic Zhang <[email protected]> Thu, 16 Jun 2005 19:59:15 +0800
Newsgroups gmane.comp.internationalization.input-methods
Message-ID <[email protected]>
Hi,

Attached is the patch to support key release event. It isn't so hard as
we imagine to support it. Somehow the iml_if->need_keyrelease isn't set
correct in this implementation, both press and release event will be
sent to LE. Will try to fix it tomorrow.

-federic
iiim-key-release.diff (text/x-patch, 13.5 KB)
Index: iiimsf/lib/iml/SunIMConf.c
===================================================================
--- iiimsf/lib/iml/SunIMConf.c	(revision 2664)
+++ iiimsf/lib/iml/SunIMConf.c	(working copy)
@@ -147,7 +147,7 @@
   void *(*get_le_info) ();
   IMHotkeyManagerStruct *(*get_hotkey_info) (IMLEName*);
   int count;
-  int if_version_idx, if_lename_idx, if_locales_idx, if_objects_idx;
+  int if_version_idx, if_lename_idx, if_locales_idx, if_objects_idx, if_keyrelease_idx;
   int if_methods_idx, if_thread_lock_idx;
 #ifdef USE_SUNIM_ADAPTER
   int if_locale_dependency_idx;
@@ -155,7 +155,7 @@
 #ifdef ENABLE_EIMIL
   int if_EIMIL_handle_idx;
 #endif
-  IMArg p[9] ; /* XXX FIXME Magic number */
+  IMArg p[10] ; /* XXX FIXME Magic number */
     
 #ifndef	WIN32
   get_le_info = (void *(*) ()) dlsym(module, PROCNAME);
@@ -182,6 +182,8 @@
   if_EIMIL_handle_idx = count++;
   setenv(IFPATH_ENV, iiimf_home, 1);
 #endif
+  IMSetArg(p[count], IF_SUPPORTED_KEYRELEASE, 0); if_keyrelease_idx = count++;
+
   (*get_le_info) (p, count);
     
   If->if_version = (char *) p[if_version_idx].value;
@@ -190,6 +192,7 @@
   If->locale_list = (IMLocale *) p[if_locales_idx].value;
   If->object_list = (IMObjectDescriptorStruct *) p[if_objects_idx].value;
   If->need_thread_lock = (Bool) p[if_thread_lock_idx].value;
+  If->need_keyrelease = (Bool) p[if_keyrelease_idx].value;
 
   /* hotkey infomation */
   get_hotkey_info = (void *(*) ()) dlsym(module, HOTKEY_PROCNAME);
@@ -289,6 +292,7 @@
 	If->object_list = (IMObjectDescriptorStruct *) 0;
 	If->hkm = (IMHotkeyManagerStruct *) 0;
 	If->need_thread_lock = True;
+	If->need_keyrelease = False;
       }
     }
   }
Index: iiimsf/src/LE.cpp
===================================================================
--- iiimsf/src/LE.cpp	(revision 2664)
+++ iiimsf/src/LE.cpp	(working copy)
@@ -433,9 +433,15 @@
     IMInputEvent* pimevent
 )
 {
+    IMKeyEventStruct *pkey;
+
     bind_imlexec(pimlex);
     IMLock lock(get_leif_sync_object(), need_thread_lock_p());
-    if_SendEvent(s, pimevent);
+    /* Assume that only one event will be sent at a time */
+    pkey = ((IMKeyListEvent *)pimevent)->keylist;
+    /* if KeyRelease is interested, send the release event. Otherwise, send only the press event */
+    if (pkey->keyType == IM_KEY_PRESS || iml_if->need_keyrelease)
+       if_SendEvent(s, pimevent);
 
     return true;
 }
Index: iiimsf/src/IIIMP_ICState.cpp
===================================================================
--- iiimsf/src/IIIMP_ICState.cpp	(revision 2664)
+++ iiimsf/src/IIIMP_ICState.cpp	(working copy)
@@ -615,9 +615,12 @@
 	      kev.keyChar = piiimpkey->keychar;
 	      kev.modifier = piiimpkey->modifier;
 	      kev.time_stamp = piiimpkey->time_stamp;
+	      kev.keyType = piiimpkey->keytype;
+printf ("IIIMP_ICState_REQUESTED:: keycode %d, keychar %d, modifier %d type %d\n", kev.keyCode, kev.keyChar, kev.modifier, piiimpkey->keytype);
 	      keyvec.push_back(kev);
 	  }
 
+
 	  IMKeyListEvent *pimkey = &ev.keylist;
 	  memset(pimkey, 0, sizeof(*pimkey));
 	  pimkey->type = IM_EventKeyList;
@@ -708,6 +711,7 @@
     ikev.keychar = pkeyevent->keyChar;
     ikev.modifier = pkeyevent->modifier;
     ikev.time_stamp = pkeyevent->time_stamp;
+    ikev.keytype = pkeyevent->keyType;
 
     IIIMP_keyevent_list *pikl = iiimp_keyevent_list_new(get_iiimptrans()->get_data_s(),
 							1, &ikev);
Index: iiimsf/src/IMKeyUtils.cpp
===================================================================
--- iiimsf/src/IMKeyUtils.cpp	(revision 2664)
+++ iiimsf/src/IMKeyUtils.cpp	(working copy)
@@ -55,8 +55,22 @@
 	keychar = x_keychar;
 	modifier = x_modifier;
 	timestamp = x_timestamp;
+	keytype = 1;            /* set IM_KEY_PRESS by default */
 }
 
+IMKeySpec::IMKeySpec(int x_keycode,
+		     int x_keychar,
+		     int x_modifier,
+		     int x_timestamp,
+		     int x_keytype)
+{
+	keycode = x_keycode;
+	keychar = x_keychar;
+	modifier = x_modifier;
+	timestamp = x_timestamp;
+	keytype = x_keytype;
+}
+
 /*******************************************************************************
                  IMKeyParser (helper object to parse key symbols
 *******************************************************************************/
Index: iiimsf/src/IMKeyUtils.hh
===================================================================
--- iiimsf/src/IMKeyUtils.hh	(revision 2664)
+++ iiimsf/src/IMKeyUtils.hh	(working copy)
@@ -51,6 +51,7 @@
 	int keychar;
 	int modifier;
 	int timestamp;
+	int keytype;
   public:
 	int get_keycode() const
 		{ return keycode; }
@@ -60,12 +61,21 @@
 		{ return modifier; }
 	int get_timestamp() const
 		{ return timestamp; }
+	int get_keytype() const
+		{ return keytype; }
 	IMKeySpec(
 		int keycode,
 		int keychar,
 		int modifier,
 		int timestamp
 		);
+	IMKeySpec(
+		int keycode,
+		int keychar,
+		int modifier,
+		int timestamp,
+		int keytype
+		);
 };
 
 typedef std::list<IMKeySpec> IMKeySpecList;
Index: iiimsf/src/IIIMP_hotkey.cpp
===================================================================
--- iiimsf/src/IIIMP_hotkey.cpp	(revision 2664)
+++ iiimsf/src/IIIMP_hotkey.cpp	(working copy)
@@ -110,6 +110,7 @@
 			kev.keyChar = it3->get_keychar();
 			kev.modifier = it3->get_modifier();
 			kev.time_stamp = it3->get_timestamp();
+			kev.keyType = it3->get_keytype();
 			keyvec.push_back(kev);
     
 			IMKeyListEvent *pimkey = &ev.keylist;
Index: iiimsf/src/IIIMP_IMState.cpp
===================================================================
--- iiimsf/src/IIIMP_IMState.cpp	(revision 2664)
+++ iiimsf/src/IIIMP_IMState.cpp	(working copy)
@@ -114,6 +114,7 @@
 	    keys[i].keychar = it->get_keychar();
 	    keys[i].modifier = it->get_modifier();
 	    keys[i].time_stamp = it->get_timestamp();
+	    keys[i].keytype = it->get_keytype();
 	}
 	pion = iiimp_keyevent_list_new(pdata_s, i, keys);
 	pioff = iiimp_keyevent_list_new(pdata_s, i, keys);
Index: iiimsf/src/IIIMP_hotkey_profile.cpp
===================================================================
--- iiimsf/src/IIIMP_hotkey_profile.cpp	(revision 2664)
+++ iiimsf/src/IIIMP_hotkey_profile.cpp	(working copy)
@@ -79,11 +79,13 @@
     kev[n_keys].keyChar = 0;
     kev[n_keys].modifier = IM_CTRL_MASK|IM_ALT_MASK;
     kev[n_keys].time_stamp = 0;
+    kev[n_keys].keyType = IM_KEY_PRESS;
     n_keys++;
     kev[n_keys].keyCode = IM_VK_SPACE;
     kev[n_keys].keyChar = 0;
     kev[n_keys].modifier = IM_CTRL_MASK|IM_SHIFT_MASK;
     kev[n_keys].time_stamp = 0;
+    kev[n_keys].keyType = IM_KEY_PRESS;
     n_keys++;
 
     hks[n_hotkeys].label = strdup("LE SWITCH");
@@ -101,6 +103,7 @@
 	kev[n_keys].keyChar = it->get_keychar();
 	kev[n_keys].modifier = it->get_modifier();
 	kev[n_keys].time_stamp = it->get_timestamp();
+	kev[n_keys].keyType = it->get_keytype();
     }
 
     hks[n_hotkeys].label = strdup("TRIGGER KEYS");
@@ -117,6 +120,7 @@
     kev[n_keys].keyChar = 0;
     kev[n_keys].modifier = IM_SHIFT_MASK|IM_CTRL_MASK;
     kev[n_keys].time_stamp = 0;
+    kev[n_keys].keyType = IM_KEY_PRESS;
     n_keys++;
 
     hks[n_hotkeys].label = strdup("CYCLE LE SWITCH");
@@ -133,6 +137,7 @@
     kev[n_keys].keyChar = 0;
     kev[n_keys].modifier = IM_SHIFT_MASK|IM_CTRL_MASK;
     kev[n_keys].time_stamp = 0;
+    kev[n_keys].keyType = IM_KEY_PRESS;
     n_keys++;
 
     hks[n_hotkeys].label = strdup("CYCLE LE SWITCH(reverse)");
@@ -351,6 +356,7 @@
 	    keys[j].keychar = it3->get_keychar();
 	    keys[j].modifier = it3->get_modifier();
 	    keys[j].time_stamp = it3->get_timestamp();
+	    keys[j].keytype = it3->get_keytype();
 	}
 	hk[i].hotkeylist = iiimp_keyevent_list_new(pdata_s, keylist->size(), keys);
 	delete[] keys;
Index: include/iml/SunIMMthd.h
===================================================================
--- include/iml/SunIMMthd.h	(revision 2664)
+++ include/iml/SunIMMthd.h	(working copy)
@@ -367,6 +367,7 @@
 #ifdef ENABLE_EIMIL
     EIMIL_handle eh;
 #endif
+
 /*
  * Added to bottom for binary compatibility
  */
@@ -383,6 +384,8 @@
 
     int num_nsm_entries;
     IMNsMapStruct *ns_map;
+
+    Bool need_keyrelease;
 }   iml_if_t;
 
 typedef enum {
@@ -399,8 +402,11 @@
 #endif	/* USE_SUNIM_ADAPTER */
 
 	/* EIMIL extension */
-	IF_EIMIL_HANDLE = 0x100
+	IF_EIMIL_HANDLE = 0x100,
 
+	/* LE extension */
+	IF_SUPPORTED_KEYRELEASE
+
 }   IF_Attribute;
 
 typedef enum {
Index: include/IMProtocolStruct.h
===================================================================
--- include/IMProtocolStruct.h	(revision 2664)
+++ include/IMProtocolStruct.h	(working copy)
@@ -194,11 +194,15 @@
  * a key event for IMKeyListEvent
  */
 
+#define IM_KEY_PRESS     1
+#define IM_KEY_RELEASE   0
+
 typedef struct _IMKeyEventStruct {
   int keyCode;
   int keyChar;
   int modifier;
   int time_stamp;
+  int keyType;      /* For Key Release Event Support */
 } IMKeyEventStruct, *IMKeyList;
 
 /*
Index: include/iiimcf.h
===================================================================
--- include/iiimcf.h	(revision 2664)
+++ include/iiimcf.h	(working copy)
@@ -173,6 +173,7 @@
     IIIMP_int32 keychar;
     IIIMP_int32 modifier;
     IIIMP_int32 time_stamp;
+    IIIMP_int32 keytype;   /* For Key Release Event Support */
 };
 
 /* Hotkeys */
Index: include/iiimp/iiimp-data.h
===================================================================
--- include/iiimp/iiimp-data.h	(revision 2664)
+++ include/iiimp/iiimp-data.h	(working copy)
@@ -230,6 +230,7 @@
     IIIMP_int32		keychar;
     IIIMP_int32		modifier;
     IIIMP_int32		time_stamp;
+    IIIMP_int32		keytype;        /* For Key Release Event Support */
 } IIIMP_keyevent;
 
 typedef struct {
Index: lib/iiimcf/iiimcf.c
===================================================================
--- lib/iiimcf/iiimcf.c	(revision 2664)
+++ lib/iiimcf/iiimcf.c	(working copy)
@@ -208,6 +208,7 @@
 	    pkev->keychar = pimk->keychar;
 	    pkev->modifier = pimk->modifier;
 	    pkev->time_stamp = pimk->time_stamp;
+	    pkev->keytype = pimk->keytype;
 	}
 
 	ph->num_on_keys = i;
@@ -231,6 +232,7 @@
 	    pkev->keychar = pimk->keychar;
 	    pkev->modifier = pimk->modifier;
 	    pkev->time_stamp = pimk->time_stamp;
+	    pkev->keytype = pimk->keytype;
 	}
 
 	ph->num_off_keys = i;
Index: lib/iiimcf/event.c
===================================================================
--- lib/iiimcf/event.c	(revision 2664)
+++ lib/iiimcf/event.c	(working copy)
@@ -405,6 +405,7 @@
     ikev.keychar = pk->keychar;
     ikev.modifier = pk->modifier;
     ikev.time_stamp = pk->time_stamp;
+    ikev.keytype = pk->keytype;
 
     pikl = iiimp_keyevent_list_new(pds, 1, &ikev);
     if (!pikl) return IIIMF_STATUS_MALLOC;
@@ -566,6 +567,7 @@
 	      kev.keychar = pimkev->keychar;
 	      kev.modifier = pimkev->modifier;
 	      kev.time_stamp = pimkev->time_stamp;
+	      kev.keytype = pimkev->keytype;
 	      st = iiimcf_create_keyevent(&kev, (IIIMCF_event*) &pev);
 	      if (st != IIIMF_STATUS_SUCCESS) return st;
 	      st = iiimcf_store_event(pc, pev);
Index: lib/iiimp/data/iiimp-dataP.h
===================================================================
--- lib/iiimp/data/iiimp-dataP.h	(revision 2664)
+++ lib/iiimp/data/iiimp-dataP.h	(working copy)
@@ -367,7 +367,7 @@
 } while(0)
 
 
-#define KEY_EVENT_OBJECT_SIZE	(4 * 4)
+#define KEY_EVENT_OBJECT_SIZE	(4 * 5)   /* Additional one for the new keytype member */
 
 
 typedef struct iiimp_attribute_id {
Index: lib/iiimp/data/comp-keyevent.c
===================================================================
--- lib/iiimp/data/comp-keyevent.c	(revision 2664)
+++ lib/iiimp/data/comp-keyevent.c	(working copy)
@@ -26,7 +26,7 @@
 	return NULL;
     }
 
-    nbyte = ((4 + 4 + 4 + 4) * count);
+    nbyte = ((4 + 4 + 4 + 4 + 4) * count); /* keytype is expected */
 
     data->nbyte = nbyte;
     data->count = count;
@@ -81,6 +81,7 @@
 	PUT32((m->keyevent + i)->keychar, rest, p, data_s->byte_swap);
 	PUT32((m->keyevent + i)->modifier, rest, p, data_s->byte_swap);
 	PUT32((m->keyevent + i)->time_stamp, rest, p, data_s->byte_swap);
+	PUT32((m->keyevent + i)->keytype, rest, p, data_s->byte_swap);
     }
 
     *nbyte = rest;
@@ -142,6 +143,7 @@
 	GET32((l->keyevent + i)->keychar, rest, p, data_s->byte_swap);
 	GET32((l->keyevent + i)->modifier, rest, p, data_s->byte_swap);
 	GET32((l->keyevent + i)->time_stamp, rest, p, data_s->byte_swap);
+	GET32((l->keyevent + i)->keytype, rest, p, data_s->byte_swap);
     }
 
     /* This failed for the scenario of having multiple HOTKEYS and each
Index: iiimgcf/gtkimcontextiiim.c
===================================================================
--- iiimgcf/gtkimcontextiiim.c	(revision 2664)
+++ iiimgcf/gtkimcontextiiim.c	(working copy)
@@ -491,6 +491,10 @@
 	    GdkEventKey *event;
 	    GdkEventKey release_event;
 	    IIIMCF_keyevent kev;
+
+	    /* FIXME - i don't know why the following code is needed */
+	    return FALSE;
+
 	    st = iiimcf_get_keyevent_value (ev, &kev);
 	    if (st != IIIMF_STATUS_SUCCESS)
 	      {
@@ -1680,10 +1684,6 @@
   IIIMCF_event ev;
   gint store_key = 0;
 
-  /* IIIMF doesn't recognize */
-  if (event->type == GDK_KEY_RELEASE)
-    return FALSE;
-
   if (current_setting_enabled &&
       current_setting.im_enabled == IM_OFF)
     goto commit_this_event;
@@ -1741,6 +1741,11 @@
     {
       /* commit this event */
       guint32 unicode;
+
+      /* don't need to commit this event twice */
+      if (event->type == GDK_KEY_RELEASE)
+	return FALSE;
+
       unicode = gdk_keyval_to_unicode (event->keyval);
       if (g_unichar_isprint (unicode))
 	{
Index: iiimgcf/IIIMGdkEventKey.c
===================================================================
--- iiimgcf/IIIMGdkEventKey.c	(revision 2664)
+++ iiimgcf/IIIMGdkEventKey.c	(working copy)
@@ -818,6 +818,8 @@
   int c;
   guint keyval;
 
+  pkev->keytype = e->type == GDK_KEY_PRESS;
+
 #if	USE_KANA_TABLE
   gint kanaflag;
   gint i;