rpms/imsettings/devel imsettings-xim-fixes.patch, NONE, 1.1 imsettings.spec, 1.26, 1.27

Akira TAGOH tagoh at fedoraproject.org
Wed Mar 18 07:33:18 UTC 2009


Author: tagoh

Update of /cvs/pkgs/rpms/imsettings/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26353

Modified Files:
	imsettings.spec 
Added Files:
	imsettings-xim-fixes.patch 
Log Message:
* Wed Mar 18 2009 Akira TAGOH <tagoh at redhat.com> - 0.106.1-2
- Fix XIM-related issues.
- Fix a parser error during reading Compose data. (#484142)
- Get rid of more debugging messages.

imsettings-xim-fixes.patch:

--- NEW FILE imsettings-xim-fixes.patch ---
Index: applet/imsettings-applet.schemas.in
===================================================================
--- applet/imsettings-applet.schemas.in	(リビジョン 263)
+++ applet/imsettings-applet.schemas.in	(リビジョン 277)
@@ -50,7 +50,7 @@
       <applyto>/apps/imsettings-applet/sync_on_forward</applyto>
       <owner>imsettings-applet</owner>
       <type>bool</type>
-      <default>FALSE</default>
+      <default>TRUE</default>
       <locale name="C">
 	<short>Enable this when accelerator keys etc doesn't work</short>
 	<long>
Index: applet/main.c
===================================================================
--- applet/main.c	(リビジョン 263)
+++ applet/main.c	(リビジョン 277)
@@ -779,7 +779,8 @@
 	val = gconf_client_get(client, "/apps/imsettings-applet/sync_on_forward", NULL);
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (applet->checkbox_sync),
 				     val == NULL ? TRUE : gconf_value_get_bool(val));
-	gconf_value_free(val);
+	if (val)
+		gconf_value_free(val);
 
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (applet->checkbox_showicon),
 				     gtk_status_icon_get_visible(applet->status_icon));
@@ -1223,7 +1224,8 @@
 			     "synchronous", val == NULL ? TRUE : gconf_value_get_bool(val),
 			     NULL);
 	}
-	gconf_value_free(val);
+	if (val)
+		gconf_value_free(val);
 
 	dbus_bus_add_match(applet->conn,
 			   "type='signal',"
Index: backends/xim/loopback.h
===================================================================
--- backends/xim/loopback.h	(リビジョン 263)
+++ backends/xim/loopback.h	(リビジョン 277)
@@ -80,6 +80,9 @@
 struct _XimLoopbackIC {
 	Sequence   *sequence_state;
 	GXimICAttr *icattr;
+	GQueue     *keyeventq;
+	gboolean    wait_for_reply;
+	gboolean    resend;
 };
 
 GType        xim_loopback_get_type(void) G_GNUC_CONST;
Index: backends/xim/proxy.c
===================================================================
--- backends/xim/proxy.c	(リビジョン 263)
+++ backends/xim/proxy.c	(リビジョン 277)
@@ -1337,8 +1337,8 @@
 				    g_queue_get_length(priv->sendq));
 	} else {
 		retval = g_xim_server_connection_cmd_set_ic_values_reply(conn, simid, icid);
-		DEC_PENDING (XIM_PROXY_CONNECTION (conn), G_XIM_SET_IC_VALUES_REPLY, 0, simid, icid);
 	}
+	DEC_PENDING (XIM_PROXY_CONNECTION (conn), G_XIM_SET_IC_VALUES_REPLY, 0, simid, icid);
 	g_free(req);
   end:
 
Index: backends/xim/compose.c
===================================================================
--- backends/xim/compose.c	(リビジョン 263)
+++ backends/xim/compose.c	(リビジョン 277)
@@ -125,12 +125,10 @@
 {
 	GSList *list = NULL, *l;
 
-	if (seq->string) {
-		g_set_error(error, sequence_get_error_quark(), SEQ_ERR_INVALID_SEQUENCE,
-			    "Child sequence won't be matched.");
+	/* Overriding old entry like what XKB does */
+	g_free(seq->string);
+	seq->string = NULL;
 
-		return FALSE;
-	}
 	if (seq->candidates == NULL) {
 		seq->candidates = g_tree_new(_sequence_compare);
 	}
@@ -139,7 +137,7 @@
 			Sequence *s = l->data;
 
 			if (s->keysym == next->keysym &&
-			    s->modifiers == next->modifiers &&+
+			    s->modifiers == next->modifiers &&
 			    s->mod_mask == next->mod_mask) {
 				g_set_error(error, sequence_get_error_quark(), SEQ_ERR_SEQUENCE_EXISTS,
 					    "Sequence [keysym:0x%lx,mods:0x%x,mask:0x%x] already exists.",
@@ -155,6 +153,23 @@
 }
 
 static gboolean
+sequence_replace(Sequence  *seq,
+		 Sequence  *next,
+		 GError   **error)
+{
+	g_free(seq->string);
+	if (seq->candidates) {
+		g_tree_foreach(seq->candidates, _sequence_list_free, NULL);
+		g_tree_destroy(seq->candidates);
+		seq->candidates = NULL;
+	}
+	seq->string = g_strdup(next->string);
+	seq->composed = next->composed;
+
+	return TRUE;
+}
+
+static gboolean
 sequence_terminate(Sequence     *seq,
 		   const gchar  *string,
 		   gulong        keysym,
@@ -186,7 +201,7 @@
 		for (l = list; l != NULL; l = g_slist_next(l)) {
 			Sequence *s = l->data;
 
-			if (s->keysym == keysym && (modifiers & s->mod_mask) == s->modifiers) {
+			if (s->keysym == keysym && (modifiers & ~s->mod_mask) == s->modifiers) {
 				return s;
 			}
 		}
@@ -487,9 +502,7 @@
 
 			keysym = XStringToKeysym(seqbuf);
 			if (keysym == NoSymbol) {
-				/* dirty hack to get rid of known warnings */
-				if (strncmp(seqbuf, "combining_", 10) != 0)
-					g_warning("Invalid symbol: %s", seqbuf);
+				d(g_warning("Invalid symbol: %s", seqbuf));
 				goto fail;
 			}
 			sequence = sequence_new(keysym, modifiers, mod_mask);
@@ -574,7 +587,8 @@
 			symbol[i] = 0;
 			result_keysym = XStringToKeysym(symbol);
 			if (result_keysym == NoSymbol) {
-				g_warning("Invalid symbol for result: %s", symbol);
+				d(g_warning("Invalid symbol for result: %s", symbol));
+				goto fail;
 			}
 			if (rhs_type == RHS_STRING)
 				rhs_type = RHS_BOTH;
@@ -617,8 +631,18 @@
 			} else {
 				if ((i + 1) == seqarray->len) {
 					if (child->candidates != NULL) {
+						/* XXX: XKB seems to be overwriting old data. */
+						sequence_replace(child, s, &error);
+						if (error) {
+							g_warning("%s: %s", error->message, seq);
+							g_clear_error(&error);
+							sequence_free(s);
+							goto fail;
+						}
+#if 0
 						g_warning("Duplicate sequence: %s", seq);
 						goto fail;
+#endif
 					} else if (s->composed != child->composed ||
 						   (s->string == NULL && child->string != NULL) ||
 						   (s->string != NULL && child->string == NULL) ||
Index: backends/xim/loopback.c
===================================================================
--- backends/xim/loopback.c	(リビジョン 263)
+++ backends/xim/loopback.c	(リビジョン 277)
@@ -39,6 +39,23 @@
 #include <libgxim/gximtransport.h>
 #include "loopback.h"
 
+/*
+ * Borrow an idea from IsModifierKey() in Xutil.h
+ */
+#define IS_MODIFIER_KEY(x)						\
+	((((x) >= GDK_Shift_L) && ((x) <= GDK_Hyper_R)) ||		\
+	 (((x) >= GDK_ISO_Lock) && ((x) <= GDK_ISO_Group_Lock)) ||	\
+	 ((x) == GDK_Mode_switch) ||					\
+	 ((x) == GDK_Num_Lock))
+
+typedef struct _XimLoopbackQueueContainer {
+	GXimProtocol *proto;
+	guint16       imid;
+	guint16       icid;
+	guint16       flag;
+	GdkEvent     *event;
+} XimLoopbackQueueContainer;
+
 enum {
 	PROP_0,
 	PROP_SYNCHRONOUS,
@@ -70,6 +87,10 @@
                                                            guint16        imid,
                                                            GSList        *attributes,
                                                            gpointer       data);
+static gboolean xim_loopback_real_xim_destroy_ic          (GXimProtocol  *proto,
+							   guint16        imid,
+							   guint16        icid,
+							   gpointer       data);
 static gboolean xim_loopback_real_xim_set_ic_values       (GXimProtocol  *proto,
                                                            guint16        imid,
                                                            guint16        icid,
@@ -98,6 +119,7 @@
 							   guint16        imid,
 							   guint16        icid,
 							   gpointer       data);
+static gboolean _process_keyevent                         (gpointer       data);
 
 //static guint signals[LAST_SIGNAL] = { 0 };
 
@@ -111,7 +133,12 @@
 static XimLoopbackIC *
 xim_loopback_ic_new(void)
 {
-	return g_new0(XimLoopbackIC, 1);
+	XimLoopbackIC *retval = g_new0(XimLoopbackIC, 1);
+
+	G_XIM_CHECK_ALLOC (retval, NULL);
+	retval->keyeventq = g_queue_new();
+
+	return retval;
 }
 
 static void
@@ -119,7 +146,10 @@
 {
 	XimLoopbackIC *ic = data;
 
-	g_free(ic);
+	if (ic) {
+		g_queue_free(ic->keyeventq);
+		g_free(ic);
+	}
 }
 
 static void
@@ -208,6 +238,7 @@
 		{"XIM_ENCODING_NEGOTIATION", G_CALLBACK (xim_loopback_real_xim_encoding_negotiation), loopback},
 		{"XIM_GET_IM_VALUES", G_CALLBACK (xim_loopback_real_xim_get_im_values), loopback},
 		{"XIM_CREATE_IC", G_CALLBACK (xim_loopback_real_xim_create_ic), loopback},
+		{"XIM_DESTROY_IC", G_CALLBACK (xim_loopback_real_xim_destroy_ic), loopback},
 		{"XIM_SET_IC_VALUES", G_CALLBACK (xim_loopback_real_xim_set_ic_values), loopback},
 		{"XIM_GET_IC_VALUES", G_CALLBACK (xim_loopback_real_xim_get_ic_values), loopback},
 		{"XIM_SET_IC_FOCUS", G_CALLBACK (xim_loopback_real_xim_set_ic_focus), loopback},
@@ -730,6 +761,34 @@
 }
 
 static gboolean
+xim_loopback_real_xim_destroy_ic(GXimProtocol *proto,
+				 guint16       imid,
+				 guint16       icid,
+				 gpointer      data)
+{
+	XimLoopbackConnection *lconn = XIM_LOOPBACK_CONNECTION (proto);
+	XimLoopbackIC *ic = g_hash_table_lookup(lconn->ic_table, GUINT_TO_POINTER ((guint)icid));
+
+	if (ic == NULL) {
+		gchar *msg = g_strdup_printf("Invalid input-context ID: [%d,%d]", imid, icid);
+		gboolean retval;
+
+		g_xim_message_warning(G_XIM_PROTOCOL_GET_IFACE (proto)->message,
+				      msg);
+		retval = g_xim_connection_cmd_error(G_XIM_CONNECTION (proto),
+						    imid, icid, G_XIM_EMASK_VALID_IMID | G_XIM_EMASK_VALID_ICID,
+						    G_XIM_ERR_BadProtocol,
+						    0, msg);
+		g_free(msg);
+
+		return retval;
+	}
+	g_hash_table_remove(lconn->ic_table, GUINT_TO_POINTER ((guint)icid));
+
+	return g_xim_server_connection_cmd_destroy_ic_reply(G_XIM_SERVER_CONNECTION (proto), imid, icid);;
+}
+
+static gboolean
 xim_loopback_real_xim_set_ic_values(GXimProtocol *proto,
 				    guint16       imid,
 				    guint16       icid,
@@ -884,6 +943,27 @@
 				      icid);
 		goto end;
 	}
+	if (!ic->resend &&
+	    (ic->wait_for_reply || g_queue_get_length(ic->keyeventq) > 0)) {
+		XimLoopbackQueueContainer *c = g_new0(XimLoopbackQueueContainer, 1);
+
+		c->proto = g_object_ref(proto);
+		c->imid = imid;
+		c->icid = icid;
+		c->flag = flag;
+		c->event = gdk_event_copy(event);
+		g_queue_push_tail(ic->keyeventq, c);
+		g_xim_message_debug(G_XIM_PROTOCOL_GET_IFACE (proto)->message, "loopback/proto/event",
+				    "Queueing a keyevent. (imid: %d, icid: %d, type: %s, keyval: %X)",
+				    imid, icid,
+				    event->type == GDK_KEY_PRESS ? "KeyPress" : "KeyRelease",
+				    event->key.keyval);
+
+		return TRUE;
+	}
+
+	if (IS_MODIFIER_KEY (event->key.keyval))
+		goto end;
 	if (event->type == GDK_KEY_RELEASE)
 		goto end;
 
@@ -914,8 +994,10 @@
 				lookup_type = G_XIM_XLookupKeySym;
 			retval = g_xim_server_connection_cmd_commit(G_XIM_SERVER_CONNECTION (proto),
 								    imid, icid,
-								    G_XIM_XLookupSynchronous | lookup_type,
+								    (sflag ? G_XIM_XLookupSynchronous : 0) | lookup_type,
 								    keysym, s);
+			/* Ensure that we'll try to find out a sequence from the beginning next time */
+			ic->sequence_state = NULL;
 
 			d(g_print("result: %s [%s]: 0x%x\n", gdk_keyval_name(keysym), string, event->key.hardware_keycode));
 
@@ -929,15 +1011,21 @@
 	} else {
 		ic->sequence_state = NULL;
 	}
-	
 
   end:
 	if (!retval)
 		retval = g_xim_connection_cmd_forward_event(G_XIM_CONNECTION (proto),
 							    imid, icid, sflag, event);
-
-	if (flag & G_XIM_Event_Synchronous)
+	if (flag & G_XIM_Event_Synchronous) {
 		g_xim_connection_cmd_sync_reply(G_XIM_CONNECTION (proto), imid, icid);
+		/* sending XIM_SYNC_REPLY usually means synchronization is done. */
+		ic->wait_for_reply = FALSE;
+	} else if (sflag & G_XIM_Event_Synchronous) {
+		ic->wait_for_reply = TRUE;
+	}
+	if (!ic->wait_for_reply && g_queue_get_length(ic->keyeventq)) {
+		g_idle_add_full(G_PRIORITY_HIGH_IDLE, _process_keyevent, ic->keyeventq, NULL);
+	}
 
 	return retval;
 }
@@ -948,10 +1036,62 @@
 				 guint16       icid,
 				 gpointer      data)
 {
-	/* Nothing to do */
+	XimLoopbackConnection *lconn = XIM_LOOPBACK_CONNECTION (proto);
+	XimLoopbackIC *ic = g_hash_table_lookup(lconn->ic_table, GUINT_TO_POINTER ((guint)icid));
+	gboolean flag = g_atomic_int_get(&ic->wait_for_reply);
+
+  retry:
+	if (flag) {
+		if (!g_atomic_int_compare_and_exchange(&ic->wait_for_reply, flag, FALSE))
+			goto retry;
+	}
+	if (g_queue_get_length(ic->keyeventq) > 0) {
+		g_idle_add_full(G_PRIORITY_HIGH_IDLE, _process_keyevent, ic->keyeventq, NULL);
+	}
+
 	return TRUE;
 }
 
+static gboolean
+_process_keyevent(gpointer data)
+{
+	GQueue *q = data;
+	XimLoopbackQueueContainer *c;
+	XimLoopbackConnection *lconn;
+	XimLoopbackIC *ic;
+	gboolean retval;
+	GClosure *closure;
+
+	c = g_queue_pop_head(q);
+	closure = (GClosure *)g_xim_protocol_lookup_protocol_by_id(c->proto, G_XIM_FORWARD_EVENT, 0);
+	if (closure == NULL) {
+		g_xim_message_bug(G_XIM_PROTOCOL_GET_IFACE (c->proto)->message,
+				  "No closure to re-send back a XIM_FORWARD_EVENT.");
+	} else {
+		lconn = XIM_LOOPBACK_CONNECTION (c->proto);
+		ic = g_hash_table_lookup(lconn->ic_table, GUINT_TO_POINTER ((guint)c->icid));
+		ic->resend = TRUE;
+		g_xim_message_debug(G_XIM_PROTOCOL_GET_IFACE (c->proto)->message, "loopback/proto/event",
+				    "Re-processing XIM_FORWARD_EVENT (imid: %d, icid: %d, type: %s, keyval: %X)",
+				    c->imid, c->icid,
+				    c->event->type == GDK_KEY_PRESS ? "KeyPress" : "KeyRelease",
+				    c->event->key.keyval);
+		retval = g_xim_protocol_closure_emit_signal((GXimProtocolClosure *)closure,
+							    c->proto,
+							    c->imid, c->icid, c->flag, c->event);
+		ic->resend = FALSE;
+		if (!retval) {
+			g_xim_message_warning(G_XIM_PROTOCOL_GET_IFACE (c->proto)->message,
+					      "Unable to re-send back a XIM_FORWARD_EVENT. this event will be discarded.");
+		}
+	}
+	g_object_unref(c->proto);
+	gdk_event_free(c->event);
+	g_free(c);
+
+	return FALSE;
+}
+
 /*
  * Public functions
  */


Index: imsettings.spec
===================================================================
RCS file: /cvs/pkgs/rpms/imsettings/devel/imsettings.spec,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- imsettings.spec	10 Mar 2009 10:13:19 -0000	1.26
+++ imsettings.spec	18 Mar 2009 07:32:48 -0000	1.27
@@ -1,6 +1,6 @@
 Name:		imsettings
 Version:	0.106.1
-Release:	1%{?dist}
+Release:	2%{?dist}
 License:	LGPLv2+
 URL:		http://code.google.com/p/imsettings/
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -15,6 +15,7 @@
 # workaround for KDE, it will be removed when we have a correct fix
 Source1: 	imsettings-kde.sh
 Patch0:		imsettings-constraint-of-language.patch
+Patch1:		imsettings-xim-fixes.patch
 
 Summary:	Delivery framework for general Input Method configuration
 Group:		Applications/System
@@ -80,6 +81,7 @@
 %prep
 %setup -q
 %patch0 -p1 -b .0-lang
+%patch1 -p0 -b .1-xim-fixes
 
 %build
 %configure	\
@@ -197,6 +199,11 @@
 
 
 %changelog
+* Wed Mar 18 2009 Akira TAGOH <tagoh at redhat.com> - 0.106.1-2
+- Fix XIM-related issues.
+- Fix a parser error during reading Compose data. (#484142)
+- Get rid of more debugging messages.
+
 * Tue Mar 10 2009 Akira TAGOH <tagoh at redhat.com> - 0.106.1-1
 - New upstream release.
   - Fix a double-free issue. (#485595)




More information about the fedora-extras-commits mailing list