gedit r6730 - in branches/message_system: . gedit gedit/smclient plugin-loaders/python/bindings
- From: jessevdk svn gnome org
- To: svn-commits-list gnome org
- Subject: gedit r6730 - in branches/message_system: . gedit gedit/smclient plugin-loaders/python/bindings
- Date: Sat, 27 Dec 2008 13:07:00 +0000 (UTC)
Author: jessevdk
Date: Sat Dec 27 13:07:00 2008
New Revision: 6730
URL: http://svn.gnome.org/viewvc/gedit?rev=6730&view=rev
Log:
Implemented new version of the message system. Messages now have to be registered
which results into a message type definition. Messages are then instantiated from
this message definition (so that argument types can be deduced from the type
specification). Bindings are properly implemented and a private message bus is
added to each GeditWindow
Added:
branches/message_system/gedit/gedit-message-type.c
branches/message_system/gedit/gedit-message-type.h
branches/message_system/gedit/msgtest.c
branches/message_system/gedit/smclient/eggsmclient-osx.c
- copied unchanged from r6626, /trunk/gedit/smclient/eggsmclient-osx.c
branches/message_system/gedit/smclient/eggsmclient-win32.c
- copied unchanged from r6626, /trunk/gedit/smclient/eggsmclient-win32.c
Modified:
branches/message_system/ChangeLog
branches/message_system/configure.ac
branches/message_system/gedit/Makefile.am
branches/message_system/gedit/gedit-message-bus.c
branches/message_system/gedit/gedit-message-bus.h
branches/message_system/gedit/gedit-message.c
branches/message_system/gedit/gedit-message.h
branches/message_system/gedit/gedit-window-private.h
branches/message_system/gedit/gedit-window.c
branches/message_system/gedit/gedit-window.h
branches/message_system/gedit/gedit.c
branches/message_system/gedit/smclient/Makefile.am
branches/message_system/plugin-loaders/python/bindings/Makefile.am
branches/message_system/plugin-loaders/python/bindings/gedit.defs
branches/message_system/plugin-loaders/python/bindings/geditmessage.override
Modified: branches/message_system/configure.ac
==============================================================================
--- branches/message_system/configure.ac (original)
+++ branches/message_system/configure.ac Sat Dec 27 13:07:00 2008
@@ -45,7 +45,7 @@
AC_SUBST(ACLOCAL_AMFLAGS, "$ACLOCAL_FLAGS -I m4")
dnl check for win32 platform
-AC_MSG_CHECKING([for some Win32 platform])
+AC_MSG_CHECKING([for Win32 platform])
case "$host" in
*-*-mingw*|*-*-cygwin*)
platform_win32=yes
@@ -57,6 +57,23 @@
AC_MSG_RESULT([$platform_win32])
AM_CONDITIONAL(PLATFORM_WIN32, test "$platform_win32" = "yes")
+dnl check for osx platform
+AC_MSG_CHECKING([for Mac OS X platform])
+case "$host" in
+ *-*-darwin*)
+ platform_osx=yes
+ ;;
+ *)
+ platform_osx=no
+ ;;
+esac
+AC_MSG_RESULT([$platform_osx])
+AM_CONDITIONAL(PLATFORM_OSX, test "$platform_osx" = "yes")
+
+if test "$platform_osx" = "yes"; then
+ AC_DEFINE([PLATFORM_OSX],[1],[Defined if platform is Mac OSX])
+fi
+
dnl ===============================================================
dnl Expanded dirs
dnl ===============================================================
@@ -176,7 +193,6 @@
dnl ================================================================
PKG_CHECK_MODULES(GEDIT, [
- sm >= 1.0.0
libxml-2.0 >= 2.5.0
glib-2.0 >= 2.13.0
gthread-2.0 >= 2.13.0
@@ -189,6 +205,19 @@
AC_SUBST(GEDIT_LIBS)
AC_SUBST(GEDIT_CFLAGS)
+if test "$platform_osx" = "no"; then
+ PKG_CHECK_MODULES(EGG_SMCLIENT, [
+ sm >= 1.0.0
+ ])
+ SM_LIBS="${EGG_SMCLIENT_LIBS}"
+else
+ EGG_SMCLIENT_CFLAGS=
+ EGG_SM_CLIENT_LIBS=
+fi
+
+AC_SUBST(EGG_SMCLIENT_CFLAGS)
+AC_SUBST(EGG_SMCLIENT_LIBS)
+
dnl ================================================================
dnl GConf related settings
dnl ================================================================
Modified: branches/message_system/gedit/Makefile.am
==============================================================================
--- branches/message_system/gedit/Makefile.am (original)
+++ branches/message_system/gedit/Makefile.am Sat Dec 27 13:07:00 2008
@@ -4,6 +4,7 @@
bin_PROGRAMS = gedit
noinst_LTLIBRARIES = libgedit.la
+noinst_PROGRAMS = msgtest
INCLUDES = \
-I$(top_srcdir) \
@@ -20,23 +21,35 @@
-DGEDIT_LOADERDIR=\""$(libdir)/gedit-2/plugin-loaders"\" \
-DGEDIT_ICONDIR=\""$(datadir)/gedit-2/icons"\"
-gedit_SOURCES = \
- gedit.c \
- gedit-message.c \
- gedit-message-bus.c
+gedit_SOURCES = \
+ gedit.c \
+ gedit-message.c \
+ gedit-message-bus.c \
+ gedit-message-type.c
+
+gedit_LDADD = libgedit.la $(GEDIT_LIBS) $(EGG_SMCLIENT_LIBS)
+
+msgtest_SOURCES = \
+ msgtest.c \
+ gedit-message.c \
+ gedit-message-bus.c \
+ gedit-message-type.c
-gedit_LDADD = libgedit.la $(GEDIT_LIBS)
+msgtest_LDADD = $(GEDIT_LIBS)
if PLATFORM_WIN32
gedit_LDFLAGS = -Wl,--export-all-symbols -Wl,--out-implib,libgedit-$(GEDIT_API_VERSION).a
else
-
gedit_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
endif
+if PLATFORM_OSX
+gedit_LDFLAGS += -framework Carbon
+endif
+
libgedit_la_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*"
-libgedit_la_LIBADD = \
+libgedit_la_LIBADD = \
dialogs/libdialogs.la \
smclient/libeggsmclient.la
@@ -89,6 +102,7 @@
gedit-message.h \
gedit-message-area.h \
gedit-message-bus.h \
+ gedit-message-type.h \
gedit-metadata-manager.h \
gedit-notebook.h \
gedit-panel.h \
Modified: branches/message_system/gedit/gedit-message-bus.c
==============================================================================
--- branches/message_system/gedit/gedit-message-bus.c (original)
+++ branches/message_system/gedit/gedit-message-bus.c Sat Dec 27 13:07:00 2008
@@ -8,29 +8,14 @@
typedef struct
{
- gchar *domain;
- gchar *name;
+ gchar *object_path;
+ gchar *method;
GList *listeners;
} Message;
typedef struct
{
- gchar *key;
- GType type;
- gboolean required;
-} PolicyItem;
-
-typedef struct
-{
- gchar *domain;
- gchar *name;
-
- GList *policies; /* list of PolicyItem */
-} Policy;
-
-typedef struct
-{
guint id;
gboolean blocked;
@@ -55,13 +40,15 @@
guint next_id;
- GHashTable *policies;
+ GHashTable *types; /* mapping from identifier to GeditMessageType */
};
/* signals */
enum
{
DISPATCH,
+ REGISTERED,
+ UNREGISTERED,
LAST_SIGNAL
};
@@ -73,28 +60,6 @@
G_DEFINE_TYPE(GeditMessageBus, gedit_message_bus, G_TYPE_OBJECT)
static void
-policy_item_free (PolicyItem *pitem)
-{
- g_free (pitem->key);
- g_free (pitem);
-}
-
-static void
-policy_free (Policy *policy)
-{
- GList *item;
-
- g_free (policy->domain);
- g_free (policy->name);
-
- for (item = policy->policies; item; item = item->next)
- policy_item_free ((PolicyItem *)item->data);
-
- g_list_free (policy->policies);
- g_free (policy);
-}
-
-static void
listener_free (Listener *listener)
{
if (listener->destroy_data)
@@ -106,8 +71,8 @@
static void
message_free (Message *message)
{
- g_free (message->name);
- g_free (message->domain);
+ g_free (message->method);
+ g_free (message->object_path);
g_list_foreach (message->listeners, (GFunc)listener_free, NULL);
g_list_free (message->listeners);
@@ -146,6 +111,17 @@
klass->dispatch = gedit_message_bus_dispatch_real;
+ /**
+ * GeditMessageBus::dispatch:
+ * @bus: a #GeditMessageBus
+ * @message: the #GeditMessage to dispatch
+ *
+ * The "dispatch" signal is emitted when a message is to be dispatched.
+ * The message is dispatched in the default handler of this signal.
+ * Primary use of this signal is to customize the dispatch of a message
+ * (for instance to automatically dispatch all messages over DBus).
+ *2
+ */
message_bus_signals[DISPATCH] =
g_signal_new ("dispatch",
G_OBJECT_CLASS_TYPE (object_class),
@@ -157,43 +133,79 @@
1,
GEDIT_TYPE_MESSAGE);
- g_type_class_add_private (object_class, sizeof(GeditMessageBusPrivate));
-}
+ /**
+ * GeditMessageBus::registered:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the registered method at @object_path
+ *
+ * The "registered" signal is emitted when a message has been registered
+ * on the bus (@method has been registered at @object_path)
+ *
+ */
+ message_bus_signals[REGISTERED] =
+ g_signal_new ("registered",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeditMessageBusClass, registered),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ GEDIT_TYPE_MESSAGE_TYPE);
-inline static gchar *
-msg_identifier (const gchar *domain,
- const gchar *name)
-{
- return g_strconcat (domain, "::", name, NULL);
+ /**
+ * GeditMessageBus::unregistered:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the unregistered method at @object_path
+ *
+ * The "unregistered" signal is emitted when a message has been
+ * unregistered from the bus (@method has been unregistered from
+ * @object_path)
+ *
+ */
+ message_bus_signals[UNREGISTERED] =
+ g_signal_new ("unregistered",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeditMessageBusClass, unregistered),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ GEDIT_TYPE_MESSAGE_TYPE);
+
+ g_type_class_add_private (object_class, sizeof(GeditMessageBusPrivate));
}
static Message *
message_new (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name)
+ const gchar *object_path,
+ const gchar *method)
{
Message *message = g_new (Message, 1);
- message->domain = g_strdup (domain);
- message->name = g_strdup (name);
+ message->object_path = g_strdup (object_path);
+ message->method = g_strdup (method);
message->listeners = NULL;
g_hash_table_insert (bus->priv->messages,
- msg_identifier (domain, name),
+ gedit_message_type_identifier (object_path, method),
message);
return message;
}
static Message *
lookup_message (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
gboolean create)
{
gchar *identifier;
Message *message;
- identifier = msg_identifier (domain, name);
+ identifier = gedit_message_type_identifier (object_path, method);
message = (Message *)g_hash_table_lookup (bus->priv->messages, identifier);
g_free (identifier);
@@ -201,7 +213,7 @@
return NULL;
if (!message)
- message = message_new (bus, domain, name);
+ message = message_new (bus, object_path, method);
return message;
}
@@ -298,14 +310,14 @@
gedit_message_bus_dispatch_real (GeditMessageBus *bus,
GeditMessage *message)
{
- const gchar *domain;
- const gchar *name;
+ const gchar *object_path;
+ const gchar *method;
Message *msg;
- domain = gedit_message_get_domain (message);
- name = gedit_message_get_name (message);
+ object_path = gedit_message_get_object_path (message);
+ method = gedit_message_get_method (message);
- msg = lookup_message (bus, domain, name, FALSE);
+ msg = lookup_message (bus, object_path, method, FALSE);
if (msg)
dispatch_message_real (bus, msg, message);
@@ -365,8 +377,8 @@
static void
process_by_match (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata,
MatchCallback processor)
@@ -374,11 +386,11 @@
Message *message;
GList *item;
- message = lookup_message (bus, domain, name, FALSE);
+ message = lookup_message (bus, object_path, method, FALSE);
if (!message)
{
- g_warning ("No such handler registered for %s::%s", domain, name);
+ g_warning ("No such handler registered for %s.%s", object_path, method);
return;
}
@@ -394,7 +406,7 @@
}
}
- g_warning ("No such handler registered for %s::%s", domain, name);
+ g_warning ("No such handler registered for %s.%s", object_path, method);
}
static void
@@ -412,12 +424,20 @@
NULL,
(GDestroyNotify)g_free);
- self->priv->policies = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)policy_free);
+ self->priv->types = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)gedit_message_type_unref);
}
+/**
+ * gedit_message_bus_get_default:
+ *
+ * Get the default application #GeditMessageBus
+ *
+ * Return value: the default #GeditMessageBus
+ *
+ */
GeditMessageBus *
gedit_message_bus_get_default (void)
{
@@ -433,112 +453,239 @@
return default_bus;
}
-void
+/**
+ * gedit_message_bus_new:
+ *
+ * Create a new message bus. Use #gedit_message_bus_get_default to get the
+ * default, application wide, message bus. Creating a new bus is useful for
+ * associating a specific bus with for instance a #GeditWindow
+ *
+ * Return value: a new #GeditMessageBus
+ *
+ */
+GeditMessageBus *
+gedit_message_bus_new (void)
+{
+ return GEDIT_MESSAGE_BUS (g_object_new (GEDIT_TYPE_MESSAGE_BUS, NULL));
+}
+
+/**
+ * gedit_message_bus_lookup:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ *
+ * Get the registered #GeditMessageType for @method at @object_path. The
+ * returned #GeditMessageType is owned by the bus and should not be unreffed.
+ *
+ * Return value: the registered #GeditMessageType or %NULL if no message type
+ * is registered for @method at @object_path
+ *
+ */
+GeditMessageType *
+gedit_message_bus_lookup (GeditMessageBus *bus,
+ const gchar *object_path,
+ const gchar *method)
+{
+ gchar *identifier;
+
+ g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), NULL);
+ g_return_val_if_fail (object_path != NULL, NULL);
+ g_return_val_if_fail (method != NULL, NULL);
+
+ identifier = gedit_message_type_identifier (object_path, method);
+ return g_hash_table_lookup (bus->priv->types, identifier);
+}
+
+/**
+ * gedit_message_bus_register:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method to register
+ * @num_optional: the number of optional arguments
+ * @...: NULL terminated list of key/gtype method argument pairs
+ *
+ * Register a message on the bus. A message must be registered on the bus before
+ * it can be send. This function registers the type arguments for @method at
+ * @object_path. The arguments are specified with @... which should contain
+ * pairs of const gchar *key and GType terminated by NULL. The last
+ * @num_optional arguments are registered as optional (and are thus not
+ * required when sending a message).
+ *
+ * This function emits a #GeditMessageBus::registered signal
+ *
+ * Return value: the registered #GeditMessageType. The returned reference is
+ * owned by the bus. If you want to keep it alive after
+ * unregistering, use #gedit_message_type_ref
+ *
+ */
+GeditMessageType *
gedit_message_bus_register (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
guint num_optional,
...)
{
gchar *identifier;
gpointer data;
- Policy *policy;
va_list var_args;
- const gchar *key;
- GList *item;
-
- g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
-
- identifier = msg_identifier (domain, name);
- data = g_hash_table_lookup (bus->priv->policies, identifier);
+ GeditMessageType *message_type;
+
+ g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), NULL);
- if (data != NULL)
+ if (gedit_message_bus_is_registered (bus, object_path, method))
{
- /* policy is already registered */
- g_free (identifier);
- return;
+ g_warning ("Message type for '%s.%s' is already registered", object_path, method);
+ return NULL;
}
+
+ identifier = gedit_message_type_identifier (object_path, method);
+ data = g_hash_table_lookup (bus->priv->types, identifier);
- policy = g_new(Policy, 1);
- policy->domain = g_strdup (domain);
- policy->name = g_strdup (name);
- policy->policies = NULL;
-
- /* construct policy items */
va_start (var_args, num_optional);
-
- /* read in required items */
- while ((key = va_arg (var_args, const gchar *)) != NULL)
- {
- GType gtype;
- PolicyItem *pitem;
-
- gtype = va_arg (var_args, GType);
-
- if (!_gedit_message_gtype_supported (gtype))
- {
- g_warning ("Type `%s' is not supported on the message bus",
- g_type_name (gtype));
- continue;
- }
-
- pitem = g_new(PolicyItem, 1);
- pitem->key = g_strdup (key);
- pitem->type = gtype;
-
- policy->policies = g_list_prepend (policy->policies, pitem);
- }
+ message_type = gedit_message_type_new_valist (object_path,
+ method,
+ num_optional,
+ var_args);
+ va_end (var_args);
- for (item = policy->policies; num_optional-- > 0 && item; item = item->next)
- ((PolicyItem *)item->data)->required = FALSE;
+ if (message_type)
+ g_hash_table_insert (bus->priv->types, identifier, message_type);
+ else
+ g_free (identifier);
- policy->policies = g_list_reverse (policy->policies);
- g_hash_table_insert (bus->priv->policies, identifier, policy);
+ g_signal_emit (bus, message_bus_signals[REGISTERED], 0, message_type);
+ return message_type;
}
+/**
+ * gedit_message_bus_unregister:
+ * @bus: a #GeditMessageBus
+ * @message_type: the #GeditMessageType to unregister
+ *
+ * Unregisters a previously registered message type. This is especially useful
+ * for plugins which should unregister message types when they are deactivated.
+ *
+ * This function emits the #GeditMessageBus::unregistered signal
+ *
+ */
void
-gedit_message_bus_unregister (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name)
+gedit_message_bus_unregister (GeditMessageBus *bus,
+ GeditMessageType *message_type)
{
gchar *identifier;
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
- identifier = msg_identifier (domain, name);
- g_hash_table_remove (bus->priv->policies, name);
+ identifier = gedit_message_type_identifier (gedit_message_type_get_object_path (message_type),
+ gedit_message_type_get_method (message_type));
+
+ // Keep message type alive for signal emission
+ gedit_message_type_ref (message_type);
+
+ if (g_hash_table_remove (bus->priv->types, identifier))
+ g_signal_emit (bus, message_bus_signals[UNREGISTERED], 0, message_type);
+
+ gedit_message_type_unref (message_type);
g_free (identifier);
}
+typedef struct
+{
+ GeditMessageBus *bus;
+ const gchar *object_path;
+} UnregisterInfo;
+
+static void
+unregister_each (const gchar *identifier,
+ GeditMessageType *message_type,
+ UnregisterInfo *info)
+{
+ if (strcmp (gedit_message_type_get_object_path (message_type),
+ info->object_path) == 0)
+ {
+ gedit_message_bus_unregister (info->bus, message_type);
+ }
+}
+
+/**
+ * gedit_message_bus_unregister_all:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ *
+ * Unregisters all message types for @object_path. This is especially useful for
+ * plugins which should unregister message types when they are deactivated.
+ *
+ * This function emits the #GeditMessageBus::unregistered signal for all
+ * unregistered message types
+ *
+ */
void
gedit_message_bus_unregister_all (GeditMessageBus *bus,
- const gchar *domain)
+ const gchar *object_path)
{
- GList *pols;
- GList *item;
+ UnregisterInfo info = {bus, object_path};
+
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
+ g_return_if_fail (object_path != NULL);
- pols = g_hash_table_get_values (bus->priv->policies);
-
- for (item = pols; item; item = item->next)
- {
- Policy *policy = (Policy *)item->data;
-
- if (strcmp (policy->domain, domain) == 0)
- {
- gchar *identifier = msg_identifier (policy->domain, policy->name);
- g_hash_table_remove (bus->priv->policies, identifier);
- g_free (identifier);
- }
- }
+ g_hash_table_foreach (bus->priv->types,
+ (GHFunc)unregister_each,
+ &info);
+}
+
+/**
+ * gedit_message_bus_is_registered:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ *
+ * Check whether a message type @method at @object_path is registered on the
+ * bus
+ *
+ * Return value: %TRUE if the @method at @object_path is a registered message
+ * type on the bus
+ *
+ */
+gboolean
+gedit_message_bus_is_registered (GeditMessageBus *bus,
+ const gchar *object_path,
+ const gchar *method)
+{
+ gchar *identifier;
+ gboolean ret;
- g_list_free (pols);
-}
-
+ g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), FALSE);
+ g_return_val_if_fail (object_path != NULL, FALSE);
+ g_return_val_if_fail (method != NULL, FALSE);
+
+ identifier = gedit_message_type_identifier (object_path, method);
+ ret = g_hash_table_lookup (bus->priv->types, identifier) != NULL;
+
+ g_free(identifier);
+ return ret;
+}
+
+/**
+ * gedit_message_bus_connect:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @callback: function to be called when message @method at @object_path is sent
+ * @userdata: userdata to use for the callback
+ * @destroy_data: function to evoke with @userdata as argument when @userdata
+ * needs to be freed
+ *
+ * Connect a callback handler to be evoked when message @method at @object_path
+ * is sent over the bus.
+ *
+ * Return value: the callback identifier
+ *
+ */
guint
gedit_message_bus_connect (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata,
GDestroyNotify destroy_data)
@@ -546,16 +693,24 @@
Message *message;
g_return_val_if_fail (GEDIT_IS_MESSAGE_BUS (bus), 0);
- g_return_val_if_fail (domain != NULL, 0);
- g_return_val_if_fail (name != NULL, 0);
+ g_return_val_if_fail (object_path != NULL, 0);
+ g_return_val_if_fail (method != NULL, 0);
g_return_val_if_fail (callback != NULL, 0);
/* lookup the message and create if it does not exist yet */
- message = lookup_message (bus, domain, name, TRUE);
+ message = lookup_message (bus, object_path, method, TRUE);
return add_listener (bus, message, callback, userdata, destroy_data);
}
+/**
+ * gedit_message_bus_disconnect:
+ * @bus: a #GeditMessageBus
+ * @id: the callback id as returned by #gedit_message_bus_connect
+ *
+ * Disconnects a previously connected message callback
+ *
+ */
void
gedit_message_bus_disconnect (GeditMessageBus *bus,
guint id)
@@ -565,18 +720,40 @@
process_by_id (bus, id, remove_listener);
}
+/**
+ * gedit_message_bus_disconnect_by_func:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @callback: the connected callback
+ * @userdata: the userdata with which the callback was connected
+ *
+ * Disconnects a previously connected message callback by matching the
+ * provided callback function and userdata. See also
+ * #gedit_message_bus_disconnect
+ *
+ */
void
gedit_message_bus_disconnect_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata)
{
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
- process_by_match (bus, domain, name, callback, userdata, remove_listener);
+ process_by_match (bus, object_path, method, callback, userdata, remove_listener);
}
+/**
+ * gedit_message_bus_block:
+ * @bus: a #GeditMessageBus
+ * @id: the callback id
+ *
+ * Blocks evoking the callback specified by @id. Unblock the callback by
+ * using #gedit_message_bus_unblock
+ *
+ */
void
gedit_message_bus_block (GeditMessageBus *bus,
guint id)
@@ -586,18 +763,38 @@
process_by_id (bus, id, block_listener);
}
+/**
+ * gedit_message_bus_block_by_func:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @callback: the callback to block
+ * @userdata: the userdata with which the callback was connected
+ *
+ * Blocks evoking the callback that matches provided @callback and @userdata.
+ * Unblock the callback using #gedit_message_unblock_by_func
+ *
+ */
void
gedit_message_bus_block_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata)
{
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
- process_by_match (bus, domain, name, callback, userdata, block_listener);
+ process_by_match (bus, object_path, method, callback, userdata, block_listener);
}
+/**
+ * gedit_message_bus_unblock:
+ * @bus: a #GeditMessageBus
+ * @id: the callback id
+ *
+ * Unblocks the callback specified by @id
+ *
+ */
void
gedit_message_bus_unblock (GeditMessageBus *bus,
guint id)
@@ -607,81 +804,50 @@
process_by_id (bus, id, unblock_listener);
}
+/**
+ * gedit_message_bus_unblock_by_func:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @callback: the callback to block
+ * @userdata: the userdata with which the callback was connected
+ *
+ * Unblocks the callback that matches provided @callback and @userdata
+ *
+ */
void
gedit_message_bus_unblock_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata)
{
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
- process_by_match (bus, domain, name, callback, userdata, unblock_listener);
+ process_by_match (bus, object_path, method, callback, userdata, unblock_listener);
}
static gboolean
-check_message_policy (GeditMessageBus *bus,
- GeditMessage *message)
+validate_message (GeditMessage *message)
{
- const gchar *domain = gedit_message_get_domain (message);
- const gchar *name = gedit_message_get_name (message);
-
- gchar *identifier = msg_identifier (domain, name);
- Policy *policy = (Policy *)g_hash_table_lookup (bus->priv->policies, identifier);
- PolicyItem *pitem;
- GList *item;
-
- g_free (identifier);
-
- if (policy == NULL)
+ if (!gedit_message_validate (message))
{
- g_warning ("Policy for '%s::%s' could not be found", domain, name);
+ g_warning ("Message '%s.%s' is invalid", gedit_message_get_object_path (message),
+ gedit_message_get_method (message));
return FALSE;
}
- /* check all required and optional arguments */
- for (item = policy->policies; item; item = item->next)
- {
- GType gtype;
- gboolean haskey;
-
- pitem = (PolicyItem *)item->data;
-
- /* check if key exists */
- haskey = gedit_message_has_key (message, pitem->key);
-
- if (pitem->required && !haskey)
- {
- g_warning ("Required key %s not found for %s::%s", pitem->key, domain, name);
- return FALSE;
- }
- else if (!haskey && !pitem->required)
- {
- continue;
- }
-
- gtype = gedit_message_get_key_type (message, pitem->key);
-
- if (!g_type_is_a (pitem->type, gtype) &&
- !g_value_type_transformable (pitem->type, gtype))
- {
- g_warning ("Invalid key type for %s::%s, expected %s, got %s", domain, name, g_type_name (pitem->type), g_type_name (gtype));
- return FALSE;
- }
- }
-
return TRUE;
}
-void
-gedit_message_bus_send_message (GeditMessageBus *bus,
- GeditMessage *message)
+static void
+send_message_real (GeditMessageBus *bus,
+ GeditMessage *message)
{
- g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
- g_return_if_fail (GEDIT_IS_MESSAGE (message));
-
- if (!check_message_policy (bus, message))
+ if (!validate_message (message))
+ {
return;
+ }
bus->priv->message_queue = g_list_prepend (bus->priv->message_queue,
g_object_ref (message));
@@ -693,249 +859,153 @@
NULL);
}
+/**
+ * gedit_message_bus_send_message:
+ * @bus: a #GeditMessageBus
+ * @message: the message to send
+ *
+ * This sends the provided @message asynchronously over the bus. To send
+ * a message synchronously, use #gedit_message_bus_send_message_sync. The
+ * convenience function #gedit_message_bus_send can be used to easily send
+ * a message without constructing the message object explicitly first.
+ *
+ */
void
-gedit_message_bus_send_message_sync (GeditMessageBus *bus,
- GeditMessage *message)
+gedit_message_bus_send_message (GeditMessageBus *bus,
+ GeditMessage *message)
{
g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
g_return_if_fail (GEDIT_IS_MESSAGE (message));
- if (!check_message_policy (bus, message))
- return;
-
- dispatch_message (bus, message);
+ send_message_real (bus, message);
}
-static GType
-policy_find_type (Policy *policy,
- const gchar *key)
+static void
+send_message_sync_real (GeditMessageBus *bus,
+ GeditMessage *message)
{
- GList *item;
-
- for (item = policy->policies; item; item = item->next)
+ if (!validate_message (message))
{
- PolicyItem *pitem = (PolicyItem *)item->data;
-
- if (strcmp (pitem->key, key) == 0)
- return pitem->type;
+ return;
}
- return 0;
+ dispatch_message (bus, message);
+}
+
+/**
+ * gedit_message_bus_send_message:
+ * @bus: a #GeditMessageBus
+ * @message: the message to send
+ *
+ * This sends the provided @message synchronously over the bus. To send
+ * a message asynchronously, use #gedit_message_bus_send_message. The
+ * convenience function #gedit_message_bus_send_sync can be used to easily send
+ * a message without constructing the message object explicitly first.
+ *
+ */
+void
+gedit_message_bus_send_message_sync (GeditMessageBus *bus,
+ GeditMessage *message)
+{
+ g_return_if_fail (GEDIT_IS_MESSAGE_BUS (bus));
+ g_return_if_fail (GEDIT_IS_MESSAGE (message));
+
+ send_message_sync_real (bus, message);
}
static GeditMessage *
create_message (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
va_list var_args)
{
- const gchar **keys = NULL;
- GType *types = NULL;
- GValue *values = NULL;
- gint num = 0;
- const gchar *key;
- gchar *identifier;
- GeditMessage *message;
- Policy *policy;
- gint i;
+ GeditMessageType *message_type;
- identifier = msg_identifier (domain, name);
- policy = g_hash_table_lookup (bus->priv->policies, identifier);
- g_free (identifier);
+ message_type = gedit_message_bus_lookup (bus, object_path, method);
- if (policy == NULL)
+ if (!message_type)
{
- g_warning ("Policy for %s::%s not found", domain, name);
+ g_warning ("Could not find message type for '%s.%s'", object_path, method);
return NULL;
}
-
- while ((key = va_arg (var_args, const gchar *)) != NULL)
- {
- gchar *error = NULL;
- GType gtype;
- GValue value = {0,};
-
- gtype = policy_find_type (policy, key);
-
- if (!gtype)
- {
- g_warning ("Key %s not registered in policy for %s::%s", key, domain, name);
- return NULL;
- }
-
- g_value_init (&value, gtype);
- G_VALUE_COLLECT (&value, var_args, 0, &error);
-
- if (error)
- {
- g_warning ("%s: %s", G_STRLOC, error);
- g_free (error);
-
- /* leak value, might have gone bad */
- continue;
- }
-
- num++;
-
- keys = g_realloc (keys, sizeof(gchar *) * num);
- types = g_realloc (types, sizeof(GType) * num);
- values = g_realloc (values, sizeof(GValue) * num);
-
- keys[num - 1] = key;
- types[num - 1] = gtype;
-
- memset (&values[num - 1], 0, sizeof(GValue));
- g_value_init (&values[num - 1], types[num - 1]);
- g_value_copy (&value, &values[num - 1]);
-
- g_value_unset (&value);
- }
-
- message = gedit_message_new (domain, name, NULL);
- gedit_message_set_types (message, keys, types, num);
- gedit_message_set_valuesv (message, keys, values, num);
-
- g_free (keys);
- g_free (types);
-
- for (i = 0; i < num; i++)
- g_value_unset (&values[i]);
- g_free (values);
-
- return message;
+ return gedit_message_type_instantiate_valist (message_type,
+ var_args);
}
+/**
+ * gedit_message_bus_send:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @...: NULL terminated list of key/value pairs
+ *
+ * This provides a convenient way to quickly send a message @method at
+ * @object_path asynchronously over the bus. @... specifies key (string) value
+ * pairs used to construct the message arguments. To send a message
+ * synchronously use #gedit_message_bus_send_sync
+ *
+ */
void
gedit_message_bus_send (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
...)
{
va_list var_args;
GeditMessage *message;
- va_start (var_args, name);
+ va_start (var_args, method);
- message = create_message (bus, domain, name, var_args);
+ message = create_message (bus, object_path, method, var_args);
if (message)
{
- gedit_message_bus_send_message (bus, message);
+ send_message_real (bus, message);
g_object_unref (message);
}
+ else
+ {
+ g_warning ("Could not instantiate message");
+ }
va_end (var_args);
}
+/**
+ * gedit_message_bus_send_sync:
+ * @bus: a #GeditMessageBus
+ * @object_path: the object path
+ * @method: the method
+ * @...: NULL terminated list of key/value pairs
+ *
+ * This provides a convenient way to quickly send a message @method at
+ * @object_path synchronously over the bus. @... specifies key (string) value
+ * pairs used to construct the message arguments. To send a message
+ * asynchronously use #gedit_message_bus_send
+ *
+ * Return value: the constructed #GeditMessage. The caller owns a reference
+ * to the #GeditMessage and should call g_object_unref when
+ * it is no longer needed.
+ */
GeditMessage *
gedit_message_bus_send_sync (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
...)
{
va_list var_args;
GeditMessage *message;
- va_start (var_args, name);
- message = create_message (bus, domain, name, var_args);
+ va_start (var_args, method);
+ message = create_message (bus, object_path, method, var_args);
if (message)
- gedit_message_bus_send_message_sync (bus, message);
+ send_message_sync_real (bus, message);
va_end (var_args);
return message;
}
-typedef struct
-{
- gchar *domain;
- gchar *name;
- GeditMessageBus *bus;
-} PropertyProxy;
-
-static void
-property_proxy_message (GObject *object,
- GParamSpec *spec,
- PropertyProxy *proxy)
-{
- GeditMessage *message;
- GValue value = {0,};
-
- message = gedit_message_new (proxy->domain,
- proxy->name,
- spec->name, spec->value_type,
- NULL);
-
- g_value_init (&value, spec->value_type);
- g_object_get_property (object, spec->name, &value);
- gedit_message_set_value (message, spec->name, &value);
-
- gedit_message_bus_send_message (proxy->bus, message);
-
- g_object_unref (message);
- g_value_unset (&value);
-}
-
-static PropertyProxy *
-property_proxy_new (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name)
-{
- PropertyProxy *proxy;
-
- proxy = g_new (PropertyProxy, 1);
- proxy->domain = g_strdup (domain);
- proxy->name = g_strdup (name);
- proxy->bus = bus;
-
- return proxy;
-}
-
-static void
-property_proxy_free (PropertyProxy *proxy,
- GClosure *closure)
-{
- g_free (proxy->domain);
- g_free (proxy->name);
- g_free (proxy);
-}
-
-void
-gedit_message_bus_proxy_property (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
- GObject *object,
- const gchar *property)
-{
- GParamSpec *spec;
- gchar *detailed;
-
- spec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
- property);
-
- if (!spec)
- {
- g_warning ("Could not connect proxy because property `%s' does not exist for %s",
- property,
- g_type_name (G_OBJECT_TYPE (object)));
- return;
- }
-
- if (!_gedit_message_gtype_supported (spec->value_type))
- {
- g_warning ("Type of property `%s' is not supported on the message bus",
- g_type_name (spec->value_type));
- return;
- }
-
- detailed = g_strconcat ("notify::", property, NULL);
- g_signal_connect_data (object,
- detailed,
- G_CALLBACK (property_proxy_message),
- property_proxy_new (bus, domain, name),
- (GClosureNotify)property_proxy_free,
- 0);
- g_free (detailed);
-}
+// ex:ts=8:noet:
Modified: branches/message_system/gedit/gedit-message-bus.h
==============================================================================
--- branches/message_system/gedit/gedit-message-bus.h (original)
+++ branches/message_system/gedit/gedit-message-bus.h Sat Dec 27 13:07:00 2008
@@ -3,6 +3,7 @@
#include <glib-object.h>
#include <gedit/gedit-message.h>
+#include <gedit/gedit-message-type.h>
G_BEGIN_DECLS
@@ -27,36 +28,49 @@
struct _GeditMessageBusClass {
GObjectClass parent_class;
- void (*dispatch) (GeditMessageBus *bus,
- GeditMessage *message);
+ void (*dispatch) (GeditMessageBus *bus,
+ GeditMessage *message);
+ void (*registered) (GeditMessageBus *bus,
+ GeditMessageType *message_type);
+ void (*unregistered) (GeditMessageBus *bus,
+ GeditMessageType *message_type);
};
-typedef void (* GeditMessageCallback) (GeditMessageBus *bus,
- GeditMessage *message,
- gpointer userdata);
+typedef void (* GeditMessageCallback) (GeditMessageBus *bus,
+ GeditMessage *message,
+ gpointer userdata);
GType gedit_message_bus_get_type (void) G_GNUC_CONST;
-GeditMessageBus *gedit_message_bus_get_default (void);
+GeditMessageBus *gedit_message_bus_get_default (void);
+GeditMessageBus *gedit_message_bus_new (void);
/* registering messages */
-void gedit_message_bus_register (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
- guint num_optional,
- ...) G_GNUC_NULL_TERMINATED;
+GeditMessageType *gedit_message_bus_lookup (GeditMessageBus *bus,
+ const gchar *object_path,
+ const gchar *method);
+GeditMessageType *gedit_message_bus_register (GeditMessageBus *bus,
+ const gchar *object_path,
+ const gchar *method,
+ guint num_optional,
+ ...) G_GNUC_NULL_TERMINATED;
void gedit_message_bus_unregister (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name);
+ GeditMessageType *message_type);
void gedit_message_bus_unregister_all (GeditMessageBus *bus,
- const gchar *domain);
+ const gchar *object_path);
+
+gboolean gedit_message_bus_is_registered (GeditMessageBus *bus,
+ const gchar *object_path,
+ const gchar *method);
+
+
/* connecting to message events */
guint gedit_message_bus_connect (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata,
GDestroyNotify destroy_data);
@@ -65,8 +79,8 @@
guint id);
void gedit_message_bus_disconnect_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata);
@@ -74,42 +88,36 @@
void gedit_message_bus_block (GeditMessageBus *bus,
guint id);
void gedit_message_bus_block_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata);
void gedit_message_bus_unblock (GeditMessageBus *bus,
guint id);
void gedit_message_bus_unblock_by_func (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
GeditMessageCallback callback,
gpointer userdata);
/* sending messages */
void gedit_message_bus_send_message (GeditMessageBus *bus,
GeditMessage *message);
-
void gedit_message_bus_send_message_sync (GeditMessageBus *bus,
GeditMessage *message);
void gedit_message_bus_send (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
...) G_GNUC_NULL_TERMINATED;
GeditMessage *gedit_message_bus_send_sync (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
+ const gchar *object_path,
+ const gchar *method,
...) G_GNUC_NULL_TERMINATED;
-/* automatic property proxy over the bus */
-void gedit_message_bus_proxy_property (GeditMessageBus *bus,
- const gchar *domain,
- const gchar *name,
- GObject *object,
- const gchar *property);
-
G_END_DECLS
#endif /* __GEDIT_MESSAGE_BUS_H__ */
+
+// ex:ts=8:noet:
Added: branches/message_system/gedit/gedit-message-type.c
==============================================================================
--- (empty file)
+++ branches/message_system/gedit/gedit-message-type.c Sat Dec 27 13:07:00 2008
@@ -0,0 +1,428 @@
+#include "gedit-message-type.h"
+
+typedef struct
+{
+ GType type;
+ gboolean required;
+} ArgumentInfo;
+
+struct _GeditMessageType
+{
+ gint ref_count;
+
+ gchar *object_path;
+ gchar *method;
+
+ guint num_arguments;
+ guint num_required;
+
+ GHashTable *arguments; // mapping of key -> ArgumentInfo
+};
+
+/**
+ * gedit_message_type_unref:
+ * @message_type: the #GeditMessageType
+ *
+ * Increases the reference count on @message_type
+ *
+ * Return value: @message_type
+ *
+ */
+GeditMessageType *
+gedit_message_type_ref (GeditMessageType *message_type)
+{
+ g_return_val_if_fail (message_type != NULL, NULL);
+ g_atomic_int_inc (&message_type->ref_count);
+
+ return message_type;
+}
+
+/**
+ * gedit_message_type_unref:
+ * @message_type: the #GeditMessageType
+ *
+ * Decreases the reference count on @message_type. When the reference count
+ * drops to 0, @message_type is destroyed
+ *
+ */
+void
+gedit_message_type_unref (GeditMessageType *message_type)
+{
+ g_return_if_fail (message_type != NULL);
+
+ if (!g_atomic_int_dec_and_test (&message_type->ref_count))
+ return;
+
+ g_free (message_type->object_path);
+ g_free (message_type->method);
+
+ g_hash_table_destroy (message_type->arguments);
+ g_free (message_type);
+}
+
+/**
+ * gedit_message_type_get_type:
+ *
+ * Retrieves the GType object which is associated with the
+ * #GeditMessageType class.
+ *
+ * Return value: the GType associated with #GeditMessageType.
+ **/
+GType
+gedit_message_type_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (!our_type)
+ our_type = g_boxed_type_register_static (
+ "GeditMessageType",
+ (GBoxedCopyFunc) gedit_message_type_ref,
+ (GBoxedFreeFunc) gedit_message_type_unref);
+
+ return our_type;
+}
+
+/**
+ * gedit_message_type_identifier:
+ * @object_path: the object path
+ * @method: the method
+ *
+ * Get the string identifier for @method at @object_path
+ *
+ * Return value: the identifier for @method at @object_path
+ *
+ */
+gchar *
+gedit_message_type_identifier (const gchar *object_path,
+ const gchar *method)
+{
+ return g_strconcat (object_path, ".", method, NULL);
+}
+
+/**
+ * gedit_message_type_is_supported:
+ * @type: the #GType
+ *
+ * Returns if @type is #GType supported by the message system
+ *
+ * Return value: %TRUE if @type is a supported #GType
+ *
+ */
+gboolean
+gedit_message_type_is_supported (GType type)
+{
+ gint i = 0;
+
+ static const GType type_list[] =
+ {
+ G_TYPE_BOOLEAN,
+ G_TYPE_CHAR,
+ G_TYPE_UCHAR,
+ G_TYPE_INT,
+ G_TYPE_UINT,
+ G_TYPE_LONG,
+ G_TYPE_ULONG,
+ G_TYPE_INT64,
+ G_TYPE_UINT64,
+ G_TYPE_ENUM,
+ G_TYPE_FLAGS,
+ G_TYPE_FLOAT,
+ G_TYPE_DOUBLE,
+ G_TYPE_STRING,
+ G_TYPE_POINTER,
+ G_TYPE_BOXED,
+ G_TYPE_OBJECT,
+ G_TYPE_INVALID
+ };
+
+ if (!G_TYPE_IS_VALUE_TYPE (type))
+ return FALSE;
+
+ while (type_list[i] != G_TYPE_INVALID)
+ {
+ if (g_type_is_a (type, type_list[i]))
+ return TRUE;
+ i++;
+ }
+
+ return FALSE;
+}
+
+/**
+ * gedit_message_type_newv:
+ * @object_path: the object path
+ * @method: the method
+ * @num_optional: number of optional arguments
+ * @var_args: key/gtype pair variable argument list
+ *
+ * Create a new #GeditMessageType for @method at @object_path. Argument names
+ * and values are supplied by the NULL terminated variable argument list.
+ * The last @num_optional provided arguments are considered optional
+ *
+ * Return value: the newly constructed #GeditMessageType
+ *
+ */
+GeditMessageType *
+gedit_message_type_new_valist (const gchar *object_path,
+ const gchar *method,
+ guint num_optional,
+ va_list var_args)
+{
+ GeditMessageType *message_type;
+
+ g_return_val_if_fail (object_path != NULL, NULL);
+ g_return_val_if_fail (method != NULL, NULL);
+
+ message_type = g_new(GeditMessageType, 1);
+
+ message_type->object_path = g_strdup(object_path);
+ message_type->method = g_strdup(method);
+ message_type->num_arguments = 0;
+ message_type->arguments = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)g_free);
+
+ gedit_message_type_set_valist (message_type, num_optional, var_args);
+ return message_type;
+}
+
+/**
+ * gedit_message_type_newv:
+ * @object_path: the object path
+ * @method: the method
+ * @num_optional: number of optional arguments
+ * @...: key/gtype pair variable argument list
+ *
+ * Create a new #GeditMessageType for @method at @object_path. Argument names
+ * and values are supplied by the NULL terminated variable argument list.
+ * The last @num_optional provided arguments are considered optional
+ *
+ * Return value: the newly constructed #GeditMessageType
+ *
+ */
+GeditMessageType *
+gedit_message_type_new (const gchar *object_path,
+ const gchar *method,
+ guint num_optional,
+ ...)
+{
+ GeditMessageType *message_type;
+ va_list var_args;
+
+ va_start(var_args, num_optional);
+ message_type = gedit_message_type_new_valist (object_path, method, num_optional, var_args);
+ va_end(var_args);
+
+ return message_type;
+}
+
+void
+gedit_message_type_set (GeditMessageType *message_type,
+ guint num_optional,
+ ...)
+{
+ va_list va_args;
+
+ va_start (va_args, num_optional);
+ gedit_message_type_set_valist (message_type, num_optional, va_args);
+ va_end (va_args);
+}
+
+void
+gedit_message_type_set_valist (GeditMessageType *message_type,
+ guint num_optional,
+ va_list var_args)
+{
+ const gchar *key;
+ ArgumentInfo **optional = g_new0(ArgumentInfo *, num_optional);
+ guint i;
+ guint added = 0;
+
+ // parse key -> gtype pair arguments
+ while ((key = va_arg (var_args, const gchar *)) != NULL)
+ {
+ // get corresponding GType
+ GType gtype = va_arg (var_args, GType);
+ ArgumentInfo *info;
+
+ if (!gedit_message_type_is_supported (gtype))
+ {
+ g_error ("Message type '%s' is not supported", g_type_name (gtype));
+
+ gedit_message_type_unref (message_type);
+ g_free (optional);
+
+ return;
+ }
+
+ info = g_new(ArgumentInfo, 1);
+ info->type = gtype;
+ info->required = TRUE;
+
+ g_hash_table_insert (message_type->arguments, g_strdup (key), info);
+
+ ++message_type->num_arguments;
+ ++added;
+
+ if (num_optional > 0)
+ {
+ for (i = 0; i < num_optional - 1; ++i)
+ {
+ optional[i + 1] = optional[i];
+ }
+
+ *optional = info;
+ }
+ }
+
+ message_type->num_required += added;
+
+ // set required for last num_optional arguments
+ for (i = 0; i < num_optional; ++i)
+ {
+ if (optional[i])
+ {
+ optional[i]->required = FALSE;
+ --message_type->num_required;
+ }
+ }
+
+ g_free (optional);
+}
+
+/**
+ * gedit_message_type_instantiate:
+ * @message_type: the #GeditMessageType
+ * @va_args: NULL terminated variable list of key/value pairs
+ *
+ * Instantiate a new message from the message type with specific values
+ * for the message arguments
+ *
+ * Return value: the newly created message
+ *
+ */
+GeditMessage *
+gedit_message_type_instantiate_valist (GeditMessageType *message_type,
+ va_list va_args)
+{
+ GeditMessage *message;
+
+ g_return_val_if_fail (message_type != NULL, NULL);
+
+ message = GEDIT_MESSAGE (g_object_new (GEDIT_TYPE_MESSAGE, "type", message_type, NULL));
+ gedit_message_set_valist (message, va_args);
+
+ return message;
+}
+
+/**
+ * gedit_message_type_instantiate:
+ * @message_type: the #GeditMessageType
+ * @...: NULL terminated variable list of key/value pairs
+ *
+ * Instantiate a new message from the message type with specific values
+ * for the message arguments
+ *
+ * Return value: the newly created message
+ *
+ */
+GeditMessage *
+gedit_message_type_instantiate (GeditMessageType *message_type,
+ ...)
+{
+ GeditMessage *message;
+ va_list va_args;
+
+ va_start (va_args, message_type);
+ message = gedit_message_type_instantiate_valist (message_type, va_args);
+ va_end (va_args);
+
+ return message;
+}
+
+/**
+ * gedit_message_type_get_object_path:
+ * @message_type: the #GeditMessageType
+ *
+ * Get the message type object path
+ *
+ * Return value: the message type object path
+ *
+ */
+const gchar *
+gedit_message_type_get_object_path (GeditMessageType *message_type)
+{
+ return message_type->object_path;
+}
+
+/**
+ * gedit_message_type_get_method:
+ * @message_type: the #GeditMessageType
+ *
+ * Get the message type method
+ *
+ * Return value: the message type method
+ *
+ */
+const gchar *
+gedit_message_type_get_method (GeditMessageType *message_type)
+{
+ return message_type->method;
+}
+
+/**
+ * gedit_message_type_lookup:
+ * @message_type: the #GeditMessageType
+ * @key: the argument key
+ *
+ * Get the argument key #GType
+ *
+ * Return value: the #GType of @key
+ *
+ */
+GType
+gedit_message_type_lookup (GeditMessageType *message_type,
+ const gchar *key)
+{
+ ArgumentInfo *info = g_hash_table_lookup (message_type->arguments, key);
+
+ if (!info)
+ return G_TYPE_INVALID;
+
+ return info->type;
+}
+
+typedef struct
+{
+ GeditMessageTypeForeach func;
+ gpointer user_data;
+} ForeachInfo;
+
+static void
+foreach_gtype (const gchar *key,
+ ArgumentInfo *info,
+ ForeachInfo *finfo)
+{
+ finfo->func (key, info->type, info->required, finfo->user_data);
+}
+
+/**
+ * gedit_message_type_foreach:
+ * @message_type: the #GeditMessageType
+ * @func: the callback function
+ * @user_data: user data supplied to the callback function
+ *
+ * Calls @func for each argument in the message type
+ *
+ */
+void
+gedit_message_type_foreach (GeditMessageType *message_type,
+ GeditMessageTypeForeach func,
+ gpointer user_data)
+{
+ ForeachInfo info = {func, user_data};
+ g_hash_table_foreach (message_type->arguments, (GHFunc)foreach_gtype, &info);
+}
+
+// ex:ts=8:noet:
Added: branches/message_system/gedit/gedit-message-type.h
==============================================================================
--- (empty file)
+++ branches/message_system/gedit/gedit-message-type.h Sat Dec 27 13:07:00 2008
@@ -0,0 +1,66 @@
+#ifndef __GEDIT_MESSAGE_TYPE_H__
+#define __GEDIT_MESSAGE_TYPE_H__
+
+#include <glib-object.h>
+#include <stdarg.h>
+
+#include "gedit-message.h"
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_MESSAGE_TYPE (gedit_message_type_get_type ())
+#define GEDIT_MESSAGE_TYPE(x) ((GeditMessageType *)(x))
+
+typedef void (*GeditMessageTypeForeach) (const gchar *key,
+ GType type,
+ gboolean required,
+ gpointer user_data);
+
+typedef struct _GeditMessageType GeditMessageType;
+
+GType gedit_message_type_get_type (void) G_GNUC_CONST;
+
+gboolean gedit_message_type_is_supported (GType type);
+gchar *gedit_message_type_identifier (const gchar *object_path,
+ const gchar *method);
+
+GeditMessageType *gedit_message_type_new (const gchar *object_path,
+ const gchar *method,
+ guint num_optional,
+ ...) G_GNUC_NULL_TERMINATED;
+GeditMessageType *gedit_message_type_new_valist (const gchar *object_path,
+ const gchar *method,
+ guint num_optional,
+ va_list va_args);
+
+void gedit_message_type_set (GeditMessageType *message_type,
+ guint num_optional,
+ ...) G_GNUC_NULL_TERMINATED;
+void gedit_message_type_set_valist (GeditMessageType *message_type,
+ guint num_optional,
+ va_list va_args);
+
+GeditMessageType *gedit_message_type_ref (GeditMessageType *message_type);
+void gedit_message_type_unref (GeditMessageType *message_type);
+
+
+GeditMessage *gedit_message_type_instantiate_valist (GeditMessageType *message_type,
+ va_list va_args);
+GeditMessage *gedit_message_type_instantiate (GeditMessageType *message_type,
+ ...) G_GNUC_NULL_TERMINATED;
+
+const gchar *gedit_message_type_get_object_path (GeditMessageType *message_type);
+const gchar *gedit_message_type_get_method (GeditMessageType *message_type);
+
+GType gedit_message_type_lookup (GeditMessageType *message_type,
+ const gchar *key);
+
+void gedit_message_type_foreach (GeditMessageType *message_type,
+ GeditMessageTypeForeach func,
+ gpointer user_data);
+
+G_END_DECLS
+
+#endif /* __GEDIT_MESSAGE_TYPE_H__ */
+
+// ex:ts=8:noet:
Modified: branches/message_system/gedit/gedit-message.c
==============================================================================
--- branches/message_system/gedit/gedit-message.c (original)
+++ branches/message_system/gedit/gedit-message.c Sat Dec 27 13:07:00 2008
@@ -1,4 +1,5 @@
#include "gedit-message.h"
+#include "gedit-message-type.h"
#include <string.h>
#include <gobject/gvaluecollector.h>
@@ -8,15 +9,16 @@
enum {
PROP_0,
- PROP_DOMAIN,
- PROP_NAME
+ PROP_OBJECT_PATH,
+ PROP_METHOD,
+ PROP_TYPE
};
struct _GeditMessagePrivate
{
- gchar *domain;
- gchar *name;
-
+ GeditMessageType *type;
+ gboolean valid;
+
GHashTable *values;
};
@@ -27,9 +29,7 @@
{
GeditMessage *message = GEDIT_MESSAGE (object);
- g_free (message->priv->domain);
- g_free (message->priv->name);
-
+ gedit_message_type_unref (message->priv->type);
g_hash_table_destroy (message->priv->values);
G_OBJECT_CLASS (gedit_message_parent_class)->finalize (object);
@@ -45,11 +45,14 @@
switch (prop_id)
{
- case PROP_DOMAIN:
- g_value_set_string (value, msg->priv->domain);
+ case PROP_OBJECT_PATH:
+ g_value_set_string (value, gedit_message_type_get_object_path (msg->priv->type));
break;
- case PROP_NAME:
- g_value_set_string (value, msg->priv->name);
+ case PROP_METHOD:
+ g_value_set_string (value, gedit_message_type_get_method (msg->priv->type));
+ break;
+ case PROP_TYPE:
+ g_value_set_boxed (value, msg->priv->type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -67,11 +70,8 @@
switch (prop_id)
{
- case PROP_DOMAIN:
- msg->priv->domain = g_strdup (g_value_get_string (value));
- break;
- case PROP_NAME:
- msg->priv->name = g_strdup (g_value_get_string (value));
+ case PROP_TYPE:
+ msg->priv->type = GEDIT_MESSAGE_TYPE (g_value_dup_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -79,6 +79,25 @@
}
}
+static GValue *
+add_value (GeditMessage *message,
+ const gchar *key)
+{
+ GValue *value;
+ GType type = gedit_message_type_lookup (message->priv->type, key);
+
+ if (type == G_TYPE_INVALID)
+ return NULL;
+
+ value = g_new0 (GValue, 1);
+ g_value_init (value, type);
+ g_value_reset (value);
+
+ g_hash_table_insert (message->priv->values, g_strdup (key), value);
+
+ return value;
+}
+
static void
gedit_message_class_init (GeditMessageClass *klass)
{
@@ -88,23 +107,48 @@
object_class->get_property = gedit_message_get_property;
object_class->set_property = gedit_message_set_property;
- g_object_class_install_property (object_class, PROP_DOMAIN,
- g_param_spec_string ("domain",
- "DOMAIN",
- "The message domain",
+ /**
+ * GeditMessage:object_path:
+ *
+ * The messages object path (e.g. /gedit/object/path)
+ *
+ */
+ g_object_class_install_property (object_class, PROP_OBJECT_PATH,
+ g_param_spec_string ("object-path",
+ "OBJECT_PATH",
+ "The message object path",
NULL,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS |
- G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class, PROP_NAME,
- g_param_spec_string ("name",
- "NAME",
- "The message name",
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GeditMessage:method:
+ *
+ * The messages method
+ *
+ */
+ g_object_class_install_property (object_class, PROP_METHOD,
+ g_param_spec_string ("method",
+ "METHOD",
+ "The message method",
NULL,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GeditMEssage:type:
+ *
+ * The message type
+ *
+ */
+ g_object_class_install_property (object_class, PROP_TYPE,
+ g_param_spec_boxed ("type",
+ "TYPE",
+ "The message type",
+ GEDIT_TYPE_MESSAGE_TYPE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_type_class_add_private (object_class, sizeof(GeditMessagePrivate));
}
@@ -127,60 +171,6 @@
(GDestroyNotify)destroy_value);
}
-gboolean
-_gedit_message_gtype_supported (GType type)
-{
- gint i = 0;
-
- static const GType type_list[] =
- {
- G_TYPE_BOOLEAN,
- G_TYPE_CHAR,
- G_TYPE_UCHAR,
- G_TYPE_INT,
- G_TYPE_UINT,
- G_TYPE_LONG,
- G_TYPE_ULONG,
- G_TYPE_INT64,
- G_TYPE_UINT64,
- G_TYPE_ENUM,
- G_TYPE_FLAGS,
- G_TYPE_FLOAT,
- G_TYPE_DOUBLE,
- G_TYPE_STRING,
- G_TYPE_POINTER,
- G_TYPE_BOXED,
- G_TYPE_OBJECT,
- G_TYPE_INVALID
- };
-
- if (!G_TYPE_IS_VALUE_TYPE (type))
- return FALSE;
-
- while (type_list[i] != G_TYPE_INVALID)
- {
- if (g_type_is_a (type, type_list[i]))
- return TRUE;
- i++;
- }
-
- return FALSE;
-}
-
-static void
-add_value (GeditMessage *message,
- const gchar *key,
- GType gtype)
-{
- GValue *value;
-
- value = g_new0 (GValue, 1);
- g_value_init (value, gtype);
- g_value_reset (value);
-
- g_hash_table_insert (message->priv->values, g_strdup (key), value);
-}
-
static gboolean
set_value_real (GValue *to,
const GValue *from)
@@ -211,141 +201,60 @@
inline static GValue *
value_lookup (GeditMessage *message,
- const gchar *key)
-{
- return (GValue *)g_hash_table_lookup (message->priv->values, key);
-}
-
-GeditMessage*
-gedit_message_new (const gchar *domain,
- const gchar *name,
- ...)
-{
- va_list var_args;
- GeditMessage *message;
-
- va_start (var_args, name);
- message = gedit_message_new_valist (domain, name, var_args);
- va_end (var_args);
-
- return message;
-}
-
-GeditMessage *
-gedit_message_new_valist (const gchar *domain,
- const gchar *name,
- va_list var_args)
-{
- GeditMessage *message;
- const gchar *key;
- GArray *keys;
- GArray *types;
-
- message = g_object_new (GEDIT_TYPE_MESSAGE, "domain", domain, "name", name, NULL);
-
- keys = g_array_new (FALSE, FALSE, sizeof (const gchar *));
- types = g_array_new (FALSE, FALSE, sizeof (GType));
-
- while ((key = va_arg (var_args, const gchar *)) != NULL)
- {
- /* get corresponding GType */
- GType gtype = va_arg (var_args, GType);
-
- g_array_append_val (keys, key);
- g_array_append_val (types, gtype);
- }
-
- gedit_message_set_types (message,
- (const gchar **)keys->data,
- (GType *)types->data,
- keys->len);
-
- g_array_free (keys, TRUE);
- g_array_free (types, TRUE);
-
- return message;
-}
-
-GeditMessage *
-gedit_message_new_hash (const gchar *domain,
- const gchar *name,
- GHashTable *values)
+ const gchar *key,
+ gboolean create)
{
- GeditMessage *message;
- const gchar *key;
- GList *keys;
- GList *item;
- GValue *value;
+ GValue *ret = (GValue *)g_hash_table_lookup (message->priv->values, key);
- message = g_object_new (GEDIT_TYPE_MESSAGE, "domain", domain, "name", name, NULL);
- keys = g_hash_table_get_keys (values);
+ if (!ret && create)
+ ret = add_value (message, key);
- for (item = keys; item; item = item->next)
- {
- key = (const gchar *)(item->data);
- value = g_hash_table_lookup (values, key);
-
- if (value == NULL)
- continue;
-
- if (!_gedit_message_gtype_supported (G_VALUE_TYPE (value)))
- {
- g_warning ("GType %s is not supported, ignoring key %s",
- g_type_name (G_VALUE_TYPE (value)),
- key);
- continue;
- }
-
- add_value (message, key, G_VALUE_TYPE (value));
- gedit_message_set_value (message, key, value);
- }
-
- g_list_free (keys);
-
- return message;
-}
-
-void
-gedit_message_set_types (GeditMessage *message,
- const gchar **keys,
- GType *types,
- gint n_types)
-{
- gint i;
-
- g_return_if_fail (GEDIT_IS_MESSAGE (message));
-
- g_hash_table_ref (message->priv->values);
- g_hash_table_destroy (message->priv->values);
-
- for (i = 0; i < n_types; i++)
- {
- if (!_gedit_message_gtype_supported (types[i]))
- {
- g_warning ("GType %s is not supported, ignoring key %s", g_type_name (types[i]), keys[i]);
- continue;
- }
-
- add_value (message, keys[i], types[i]);
- }
-}
-
+ return ret;
+}
+
+/**
+ * gedit_message_get_method:
+ * @message: the #GeditMessage
+ *
+ * Get the message method
+ *
+ * Return value: the message method
+ *
+ */
const gchar *
-gedit_message_get_name (GeditMessage *message)
+gedit_message_get_method (GeditMessage *message)
{
g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
- return message->priv->name;
+ return gedit_message_type_get_method (message->priv->type);
}
+/**
+ * gedit_message_get_object_path:
+ * @message: the #GeditMessage
+ *
+ * Get the message object path
+ *
+ * Return value: the message object path
+ *
+ */
const gchar *
-gedit_message_get_domain (GeditMessage *message)
+gedit_message_get_object_path (GeditMessage *message)
{
g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
- return message->priv->domain;
+ return gedit_message_type_get_object_path (message->priv->type);
}
+/**
+ * gedit_message_set_value:
+ * @message: the #GeditMessage
+ * @...: a NULL terminated variable list of key/value pairs
+ *
+ * Set values of message arguments. The supplied @var_args should contain
+ * pairs of keys and argument values
+ *
+ */
void
gedit_message_set (GeditMessage *message,
...)
@@ -359,6 +268,15 @@
va_end (ap);
}
+/**
+ * gedit_message_set_value:
+ * @message: the #GeditMessage
+ * @var_args: a NULL terminated variable list of key/value pairs
+ *
+ * Set values of message arguments. The supplied @var_args should contain
+ * pairs of keys and argument values
+ *
+ */
void
gedit_message_set_valist (GeditMessage *message,
va_list var_args)
@@ -370,7 +288,7 @@
while ((key = va_arg (var_args, const gchar *)) != NULL)
{
/* lookup the key */
- GValue *container = value_lookup (message, key);
+ GValue *container = value_lookup (message, key, TRUE);
GValue value = {0,};
gchar *error = NULL;
@@ -399,6 +317,15 @@
}
}
+/**
+ * gedit_message_set_value:
+ * @message: the #GeditMessage
+ * @key: the argument key
+ * @value: the argument value
+ *
+ * Set value of message argument @key to @value
+ *
+ */
void
gedit_message_set_value (GeditMessage *message,
const gchar *key,
@@ -407,7 +334,7 @@
GValue *container;
g_return_if_fail (GEDIT_IS_MESSAGE (message));
- container = value_lookup (message, key);
+ container = value_lookup (message, key, TRUE);
if (!container)
{
@@ -420,6 +347,16 @@
set_value_real (container, value);
}
+/**
+ * gedit_message_set_valuesv:
+ * @message: the #GeditMessage
+ * @keys: keys to set values for
+ * @values: values to set
+ * @n_values: number of arguments to set values for
+ *
+ * Set message argument values.
+ *
+ */
void
gedit_message_set_valuesv (GeditMessage *message,
const gchar **keys,
@@ -436,6 +373,16 @@
}
}
+/**
+ * gedit_message_get_valist:
+ * @message: the #GeditMessage
+ * @...: a NULL variable argument list of key/value container pairs
+ *
+ * Get values of message arguments. The supplied @var_args should contain
+ * pairs of keys and pointers to variables which are set to the argument
+ * value for the specified key
+ *
+ */
void
gedit_message_get (GeditMessage *message,
...)
@@ -449,6 +396,16 @@
va_end (ap);
}
+/**
+ * gedit_message_get_valist:
+ * @message: the #GeditMessage
+ * @var_args: a NULL variable argument list of key/value container pairs
+ *
+ * Get values of message arguments. The supplied @var_args should contain
+ * pairs of keys and pointers to variables which are set to the argument
+ * value for the specified key
+ *
+ */
void
gedit_message_get_valist (GeditMessage *message,
va_list var_args)
@@ -463,7 +420,7 @@
GValue copy = {0,};
gchar *error = NULL;
- container = value_lookup (message, key);
+ container = value_lookup (message, key, FALSE);
if (!container)
{
@@ -492,6 +449,16 @@
}
}
+/**
+ * gedit_message_get_value:
+ * @message: the #GeditMessage
+ * @key: the argument key
+ * @value: value return container
+ *
+ * Get the value of a specific message argument. @value will be initialized
+ * with the correct type
+ *
+ */
void
gedit_message_get_value (GeditMessage *message,
const gchar *key,
@@ -501,7 +468,7 @@
g_return_if_fail (GEDIT_IS_MESSAGE (message));
- container = value_lookup (message, key);
+ container = value_lookup (message, key, FALSE);
if (!container)
{
@@ -515,64 +482,95 @@
set_value_real (value, container);
}
+/**
+ * gedit_message_get_key_type:
+ * @message: the #GeditMessage
+ * @key: the argument key
+ *
+ * Get the type of a message argument
+ *
+ * Return value: the type of @key
+ *
+ */
GType
gedit_message_get_key_type (GeditMessage *message,
const gchar *key)
{
- GValue *container;
+ g_return_val_if_fail (GEDIT_IS_MESSAGE (message), G_TYPE_INVALID);
+ g_return_val_if_fail (message->priv->type != NULL, G_TYPE_INVALID);
- g_return_val_if_fail (GEDIT_IS_MESSAGE (message), 0);
-
- container = value_lookup (message, key);
-
- if (!container)
- {
- g_warning ("%s: Invalid key `%s'",
- G_STRLOC,
- key);
- return 0;
- }
-
- return G_VALUE_TYPE (container);
+ return gedit_message_type_lookup (message->priv->type, key);
}
-GStrv
-gedit_message_get_keys (GeditMessage *message)
+/**
+ * gedit_message_has_key:
+ * @message: the #GeditMessage
+ * @key: the argument key
+ *
+ * Check whether the message has a specific key
+ *
+ * Return value: %TRUE if @message has argument @key
+ *
+ */
+gboolean
+gedit_message_has_key (GeditMessage *message,
+ const gchar *key)
{
- GList *keys;
- GList *item;
- GStrv result;
- gint i = 0;
-
- g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
-
- result = g_new0 (gchar *, g_hash_table_size (message->priv->values) + 1);
-
- keys = g_hash_table_get_keys (message->priv->values);
-
- for (item = keys; item; item = item->next)
- result[i++] = g_strdup ((gchar *)(item->data));
+ g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
- g_list_free (keys);
- return result;
+ return value_lookup (message, key, FALSE) != NULL;
}
-GHashTable *
-gedit_message_get_hash (GeditMessage *message)
+typedef struct
{
- g_return_val_if_fail (GEDIT_IS_MESSAGE (message), NULL);
- return message->priv->values;
+ GeditMessage *message;
+ gboolean valid;
+} ValidateInfo;
+
+static void
+validate_key (const gchar *key,
+ GType type,
+ gboolean required,
+ ValidateInfo *info)
+{
+ GValue *value;
+
+ if (!info->valid || !required)
+ return;
+
+ value = value_lookup (info->message, key, FALSE);
+
+ if (!value)
+ info->valid = FALSE;
}
+/**
+ * gedit_message_validate:
+ * @message: the #GeditMessage
+ *
+ * Validates the message arguments according to the message type
+ *
+ * Return value: %TRUE if the message is valid
+ *
+ */
gboolean
-gedit_message_has_key (GeditMessage *message,
- const gchar *key)
+gedit_message_validate (GeditMessage *message)
{
- GValue *container;
-
+ ValidateInfo info = {message, TRUE};
+
g_return_val_if_fail (GEDIT_IS_MESSAGE (message), FALSE);
+ g_return_val_if_fail (message->priv->type != NULL, FALSE);
- container = value_lookup (message, key);
+ if (!message->priv->valid)
+ {
+ gedit_message_type_foreach (message->priv->type,
+ (GeditMessageTypeForeach)validate_key,
+ &info);
+
+ message->priv->valid = info.valid;
+ }
- return container != NULL;
+ return message->priv->valid;
}
+
+// ex:ts=8:noet:
Modified: branches/message_system/gedit/gedit-message.h
==============================================================================
--- branches/message_system/gedit/gedit-message.h (original)
+++ branches/message_system/gedit/gedit-message.h Sat Dec 27 13:07:00 2008
@@ -14,6 +14,9 @@
#define GEDIT_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_MESSAGE))
#define GEDIT_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_MESSAGE, GeditMessageClass))
+/* forward declaration of GeditMessageType */
+struct _GeditMessageType;
+
typedef struct _GeditMessage GeditMessage;
typedef struct _GeditMessageClass GeditMessageClass;
typedef struct _GeditMessagePrivate GeditMessagePrivate;
@@ -30,23 +33,7 @@
GType gedit_message_get_type (void) G_GNUC_CONST;
-GeditMessage *gedit_message_new (const gchar *domain,
- const gchar *name,
- ...) G_GNUC_NULL_TERMINATED;
-GeditMessage *gedit_message_new_valist (const gchar *domain,
- const gchar *name,
- va_list var_args);
-GeditMessage *gedit_message_new_hash (const gchar *domain,
- const gchar *name,
- GHashTable *values);
-
-void gedit_message_set_types (GeditMessage *message,
- const gchar **keys,
- GType *types,
- gint n_types);
-
-const gchar *gedit_message_get_domain (GeditMessage *message);
-const gchar *gedit_message_get_name (GeditMessage *message);
+struct _GeditMessageType gedit_message_get_message_type (GeditMessage *message);
void gedit_message_get (GeditMessage *message,
...) G_GNUC_NULL_TERMINATED;
@@ -59,7 +46,7 @@
void gedit_message_set (GeditMessage *message,
...) G_GNUC_NULL_TERMINATED;
void gedit_message_set_valist (GeditMessage *message,
- va_list var_args);
+ va_list var_args);
void gedit_message_set_value (GeditMessage *message,
const gchar *key,
GValue *value);
@@ -68,16 +55,22 @@
GValue *values,
gint n_values);
+const gchar *gedit_message_get_object_path (GeditMessage *message);
+const gchar *gedit_message_get_method (GeditMessage *message);
+
gboolean gedit_message_has_key (GeditMessage *message,
const gchar *key);
-GStrv gedit_message_get_keys (GeditMessage *message);
-GType gedit_message_get_key_type (GeditMessage *message,
+//GStrv gedit_message_get_keys (GeditMessage *message);
+GType gedit_message_get_key_type (GeditMessage *message,
const gchar *key);
-GHashTable *gedit_message_get_hash (GeditMessage *message);
-gboolean _gedit_message_gtype_supported (GType type);
+gboolean gedit_message_validate (GeditMessage *message);
+
+//GHashTable *gedit_message_get_hash (GeditMessage *message);
G_END_DECLS
#endif /* __GEDIT_MESSAGE_H__ */
+
+// ex:ts=8:noet:
Modified: branches/message_system/gedit/gedit-window-private.h
==============================================================================
--- branches/message_system/gedit/gedit-window-private.h (original)
+++ branches/message_system/gedit/gedit-window-private.h Sat Dec 27 13:07:00 2008
@@ -46,7 +46,9 @@
GtkWidget *bottom_panel;
GtkWidget *hpaned;
- GtkWidget *vpaned;
+ GtkWidget *vpaned;
+
+ GeditMessageBus *message_bus;
/* statusbar and context ids for statusbar messages */
GtkWidget *statusbar;
Modified: branches/message_system/gedit/gedit-window.c
==============================================================================
--- branches/message_system/gedit/gedit-window.c (original)
+++ branches/message_system/gedit/gedit-window.c Sat Dec 27 13:07:00 2008
@@ -155,6 +155,12 @@
window->priv->window_group = NULL;
}
+ if (window->priv->message_bus != NULL)
+ {
+ g_object_unref (window->priv->message_bus);
+ window->priv->message_bus = NULL;
+ }
+
/* Now that there have broken some reference loops,
* force collection again.
*/
@@ -3077,6 +3083,7 @@
window->priv->state = GEDIT_WINDOW_STATE_NORMAL;
window->priv->destroy_has_run = FALSE;
window->priv->dispose_has_run = FALSE;
+ window->priv->message_bus = gedit_message_bus_new ();
window->priv->window_group = gtk_window_group_new ();
gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW (window));
@@ -3674,6 +3681,24 @@
return ret;
}
+/**
+ * gedit_window_get_message_bus:
+ * @window: a #GeditWindow
+ *
+ * Gets the #GeditMessageBus associated with @window. The returned reference
+ * is owned by the window and should not be unreffed.
+ *
+ * Return value: the #GeditMessageBus associated with @window
+ */
+GeditMessageBus *
+gedit_window_get_message_bus (GeditWindow *window)
+{
+ g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
+
+ return window->priv->message_bus;
+}
+
+
/* for backward compat since it is public api */
GeditTab *
gedit_window_get_tab_from_uri (GeditWindow *window,
@@ -3691,4 +3716,3 @@
return tab;
}
-
Modified: branches/message_system/gedit/gedit-window.h
==============================================================================
--- branches/message_system/gedit/gedit-window.h (original)
+++ branches/message_system/gedit/gedit-window.h Sat Dec 27 13:07:00 2008
@@ -36,6 +36,7 @@
#include <gedit/gedit-tab.h>
#include <gedit/gedit-panel.h>
+#include <gedit/gedit-message-bus.h>
G_BEGIN_DECLS
@@ -155,6 +156,10 @@
GeditTab *gedit_window_get_tab_from_uri (GeditWindow *window,
const gchar *uri);
+
+/* Message bus */
+GeditMessageBus *gedit_window_get_message_bus (GeditWindow *window);
+
/*
* Non exported functions
*/
Modified: branches/message_system/gedit/gedit.c
==============================================================================
--- branches/message_system/gedit/gedit.c (original)
+++ branches/message_system/gedit/gedit.c Sat Dec 27 13:07:00 2008
@@ -39,7 +39,10 @@
#include <glib/gi18n.h>
#include <glib/goption.h>
+
+#ifndef PLATFORM_OSX
#include <gdk/gdkx.h>
+#endif
#include "gedit-app.h"
#include "gedit-commands.h"
@@ -325,11 +328,13 @@
if (!GTK_WIDGET_REALIZED (window))
gtk_widget_realize (GTK_WIDGET (window));
+#ifdef GDK_WINDOWING_X11
if (startup_timestamp <= 0)
startup_timestamp = gdk_x11_get_server_time (GTK_WIDGET (window)->window);
gdk_x11_window_set_user_time (GTK_WIDGET (window)->window,
startup_timestamp);
+#endif
gtk_window_present (GTK_WINDOW (window));
@@ -485,7 +490,7 @@
gedit_debug_message (DEBUG_APP, "Create bacon connection");
- connection = bacon_message_connection_new ("gedit");
+ connection = bacon_message_connection_new ("gedit-message-system");
if (connection != NULL)
{
@@ -529,7 +534,9 @@
GEDIT_ICONDIR);
/* Set the associated .desktop file */
+#ifndef PLATFORM_OSX
egg_set_desktop_file (DATADIR "/applications/gedit.desktop");
+#endif
/* Load user preferences */
gedit_debug_message (DEBUG_APP, "Init prefs manager");
Added: branches/message_system/gedit/msgtest.c
==============================================================================
--- (empty file)
+++ branches/message_system/gedit/msgtest.c Sat Dec 27 13:07:00 2008
@@ -0,0 +1,37 @@
+#include "gedit-message-bus.h"
+
+static void
+fb_set_root_cb (GeditMessageBus *bus, GeditMessage *message, gpointer user_data)
+{
+ gchar *uri = NULL;
+
+ gedit_message_get (message, "uri", &uri, NULL);
+ g_message ("Setting root to: %s", uri);
+
+ g_free (uri);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GeditMessageBus *bus;
+
+ g_type_init ();
+
+ bus = gedit_message_bus_get_default ();
+
+ /* registering a new message on the bus */
+ GeditMessageType *message_type = gedit_message_bus_register (bus, "/plugins/filebrowser", "set_root", 0, "uri", G_TYPE_STRING, NULL);
+
+ /* register callback for the message type */
+ gedit_message_bus_connect (bus, "/plugins/filebrowser", "set_root", fb_set_root_cb, NULL, NULL);
+
+ /* sending the set_root message */
+ gedit_message_bus_send_sync (bus, "/plugins/filebrowser", "set_root", "uri", "/hello/world", NULL);
+
+ /* unregister message type */
+ gedit_message_bus_unregister (bus, message_type);
+ g_object_unref (bus);
+
+ return 0;
+}
Modified: branches/message_system/gedit/smclient/Makefile.am
==============================================================================
--- branches/message_system/gedit/smclient/Makefile.am (original)
+++ branches/message_system/gedit/smclient/Makefile.am Sat Dec 27 13:07:00 2008
@@ -1,23 +1,36 @@
+if PLATFORM_WIN32
+platform_sources = eggsmclient-win32.c
+platform_logout_test_ldflags = -mwindows
+else
+if PLATFORM_OSX
+platform_defines = -xobjective-c
+platform_ldflags = -framework Carbon
+platform_sources = eggsmclient-osx.c
+else
platform_defines = -DEGG_SM_CLIENT_BACKEND_XSMP
-platform_ltlibraries = libeggdesktopfile.la
platform_libs = libeggdesktopfile.la -lSM -lICE
+platform_ltlibraries = libeggdesktopfile.la
platform_sources = eggsmclient-xsmp.c
-platform_app_ldflags =
-platform_programs = egg-launch
+endif
+endif
INCLUDES = \
-DG_LOG_DOMAIN=\""EggSMClient"\" \
+ $(GEDIT_CFLAGS) \
$(platform_defines) \
- $(GEDIT_CFLAGS)
+ $(EGG_SMCLIENT_CFLAGS)
noinst_LTLIBRARIES = \
libeggsmclient.la \
$(platform_ltlibraries)
libeggsmclient_la_LIBADD = \
- $(GEDIT_LIBS) \
+ $(EGG_SMCLIENT_LIBS) \
$(platform_libs)
+libeggsmclient_la_LDFLAGS = \
+ $(platform_ldflags)
+
libeggsmclient_la_SOURCES = \
eggsmclient.c \
eggsmclient.h \
@@ -25,11 +38,13 @@
$(platform_sources)
libeggdesktopfile_la_LIBADD = \
- $(GEDIT_LIBS)
+ $(EGG_LIBS)
libeggdesktopfile_la_SOURCES = \
eggdesktopfile.c \
eggdesktopfile.h
EXTRA_DIST = \
+ eggsmclient-osx.c \
+ eggsmclient-win32.c \
eggsmclient-xsmp.c
Modified: branches/message_system/plugin-loaders/python/bindings/Makefile.am
==============================================================================
--- branches/message_system/plugin-loaders/python/bindings/Makefile.am (original)
+++ branches/message_system/plugin-loaders/python/bindings/Makefile.am Sat Dec 27 13:07:00 2008
@@ -3,9 +3,9 @@
noinst_LTLIBRARIES = \
gedit.la
-nodist_gedit_la_SOURCES = \
+nodist_gedit_la_SOURCES = \
gedit.c \
- geditutils.c \
+ geditutils.c \
geditcommands.c
gedit_la_LDFLAGS = \
@@ -59,7 +59,7 @@
gedit/gedit-document.h \
gedit/gedit-encodings.h \
gedit/gedit-plugin.h \
- $(srcdir)/../gedit-plugin-python.h \
+ plugin-loaders/python/gedit-plugin-python.h \
gedit/gedit-view.h \
gedit/gedit-statusbar.h \
gedit/gedit-tab.h \
@@ -67,6 +67,9 @@
gedit/gedit-window.h \
gedit/gedit-help.h \
gedit/gedit-debug.h \
+ gedit/gedit-message-type.h \
+ gedit/gedit-message.h \
+ gedit/gedit-message-bus.h \
gedit/gedit-language-manager.h
BINDING_UTILS_HEADERS_SRCDIR_IN = \
@@ -100,6 +103,7 @@
geditutils.defs \
geditcommands.override \
geditcommands.defs \
+ geditmessage.override \
geditplugin.override
CLEANFILES = $(BUILT_SOURCES)
Modified: branches/message_system/plugin-loaders/python/bindings/gedit.defs
==============================================================================
--- branches/message_system/plugin-loaders/python/bindings/gedit.defs (original)
+++ branches/message_system/plugin-loaders/python/bindings/gedit.defs Sat Dec 27 13:07:00 2008
@@ -163,6 +163,13 @@
;; )
)
+(define-boxed MessageType
+ (in-module "Gedit")
+ (c-name "GeditMessageType")
+ (gtype-id "GEDIT_TYPE_MESSAGE_TYPE")
+ (copy-func "gedit_message_type_ref")
+ (release-func "gedit_message_type_unref")
+)
;; From ../../gedit/gedit-app.h
@@ -971,6 +978,12 @@
(return-type "GeditWindowState")
)
+(define-method get_message_bus
+ (of-object "GeditWindow")
+ (c-name "gedit_window_get_message_bus")
+ (return-type "GeditMessageBus*")
+)
+
(define-method get_tab_from_uri
(of-object "GeditWindow")
(c-name "gedit_window_get_tab_from_uri")
@@ -1018,15 +1031,72 @@
(return-type "GeditMessageBus*")
)
+(define-function gedit_message_bus_new
+ (c-name "gedit_message_bus_new")
+ (is-constructor-of "GeditMessageBus")
+ (return-type "GeditMessageBus*")
+)
+
+(define-method lookup
+ (of-object "GeditMessageBus")
+ (c-name "gedit_message_bus_lookup")
+ (return-type "GeditMessageType*")
+ (parameters
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ )
+)
+
+(define-method register
+ (of-object "GeditMessageBus")
+ (c-name "gedit_message_bus_register")
+ (return-type "GeditMessageType*")
+ (parameters
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ '("guint" "num_optional")
+ )
+ (varargs #t)
+)
+
+(define-method unregister
+ (of-object "GeditMessageBus")
+ (c-name "gedit_message_bus_unregister")
+ (return-type "none")
+ (parameters
+ '("GeditMessageType*" "message_type")
+ )
+)
+
+(define-method unregister_all
+ (of-object "GeditMessageBus")
+ (c-name "gedit_message_bus_unregister_all")
+ (return-type "none")
+ (parameters
+ '("const-gchar*" "object_path")
+ )
+)
+
+(define-method is_registered
+ (of-object "GeditMessageBus")
+ (c-name "gedit_message_bus_is_registered")
+ (return-type "gboolean")
+ (parameters
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ )
+)
+
(define-method connect
(of-object "GeditMessageBus")
(c-name "gedit_message_bus_connect")
(return-type "guint")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
'("GeditMessageCallback" "callback")
'("gpointer" "userdata")
+ '("GDestroyNotify" "destroy_data")
)
)
@@ -1044,8 +1114,8 @@
(c-name "gedit_message_bus_disconnect_by_func")
(return-type "none")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
'("GeditMessageCallback" "callback")
'("gpointer" "userdata")
)
@@ -1065,8 +1135,8 @@
(c-name "gedit_message_bus_block_by_func")
(return-type "none")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
'("GeditMessageCallback" "callback")
'("gpointer" "userdata")
)
@@ -1086,8 +1156,8 @@
(c-name "gedit_message_bus_unblock_by_func")
(return-type "none")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
'("GeditMessageCallback" "callback")
'("gpointer" "userdata")
)
@@ -1116,8 +1186,8 @@
(c-name "gedit_message_bus_send")
(return-type "none")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
)
(varargs #t)
)
@@ -1127,65 +1197,129 @@
(c-name "gedit_message_bus_send_sync")
(return-type "GeditMessage*")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
)
(varargs #t)
)
+;; From gedit-message-type.h
-;; From gedit-message.h
-
-(define-function gedit_message_get_type
- (c-name "gedit_message_get_type")
+(define-function gedit_message_type_get_type
+ (c-name "gedit_message_type_get_type")
(return-type "GType")
)
-(define-function gedit_message_new
- (c-name "gedit_message_new")
- (is-constructor-of "GeditMessage")
- (return-type "GeditMessage*")
+(define-function gedit_message_type_is_supported
+ (c-name "gedit_message_type_is_supported")
+ (return-type "gboolean")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
+ '("GType" "type")
+ )
+)
+
+(define-function gedit_message_type_identifier
+ (c-name "gedit_message_type_identifier")
+ (return-type "gchar*")
+ (parameters
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ )
+)
+
+(define-function gedit_message_type_new
+ (c-name "gedit_message_type_new")
+ (is-constructor-of "GeditMessageType")
+ (return-type "GeditMessageType*")
+ (parameters
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ '("guint" "num_optional")
)
(varargs #t)
)
-(define-function gedit_message_new_valist
- (c-name "gedit_message_new_valist")
- (return-type "GeditMessage*")
+(define-function gedit_message_type_new_valist
+ (c-name "gedit_message_type_new_valist")
+ (return-type "GeditMessageType*")
(parameters
- '("const-gchar*" "domain")
- '("const-gchar*" "name")
- '("va_list" "var_args")
+ '("const-gchar*" "object_path")
+ '("const-gchar*" "method")
+ '("guint" "num_optional")
+ '("va_list" "va_args")
)
)
-(define-method set_types
- (of-object "GeditMessage")
- (c-name "gedit_message_set_types")
+(define-method ref
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_ref")
+ (return-type "GeditMessageType*")
+)
+
+(define-method unref
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_unref")
(return-type "none")
+)
+
+(define-method instantiate_valist
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_instantiate_valist")
+ (return-type "GeditMessage*")
(parameters
- '("const-gchar**" "keys")
- '("GType*" "types")
- '("gint" "n_types")
+ '("va_list" "va_args")
)
)
-(define-method get_domain
- (of-object "GeditMessage")
- (c-name "gedit_message_get_domain")
+(define-method instantiate
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_instantiate")
+ (return-type "GeditMessage*")
+ (parameters
+ )
+ (varargs #t)
+)
+
+(define-method get_object_path
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_get_object_path")
(return-type "const-gchar*")
)
-(define-method get_name
- (of-object "GeditMessage")
- (c-name "gedit_message_get_name")
+(define-method get_method
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_get_method")
(return-type "const-gchar*")
)
+(define-method lookup
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_lookup")
+ (return-type "GType")
+ (parameters
+ '("const-gchar*" "key")
+ )
+)
+
+(define-method foreach
+ (of-object "GeditMessageType")
+ (c-name "gedit_message_type_foreach")
+ (return-type "none")
+ (parameters
+ '("GeditMessageTypeForeach" "func")
+ '("gpointer" "user_data")
+ )
+)
+
+
+;; From gedit-message.h
+
+(define-function gedit_message_get_type
+ (c-name "gedit_message_get_type")
+ (return-type "GType")
+)
+
(define-method get
(of-object "GeditMessage")
(c-name "gedit_message_get")
@@ -1253,6 +1387,18 @@
)
)
+(define-method get_object_path
+ (of-object "GeditMessage")
+ (c-name "gedit_message_get_object_path")
+ (return-type "const-gchar*")
+)
+
+(define-method get_method
+ (of-object "GeditMessage")
+ (c-name "gedit_message_get_method")
+ (return-type "const-gchar*")
+)
+
(define-method has_key
(of-object "GeditMessage")
(c-name "gedit_message_has_key")
@@ -1262,14 +1408,22 @@
)
)
-(define-method get_keys
+(define-method get_key_type
(of-object "GeditMessage")
- (c-name "gedit_message_get_keys")
- (return-type "gchar**")
+ (c-name "gedit_message_get_key_type")
+ (return-type "GType")
(parameters
+ '("const-gchar*" "key")
)
)
+(define-method validate
+ (of-object "GeditMessage")
+ (c-name "gedit_message_validate")
+ (return-type "gboolean")
+)
+
+
;; From ../../gedit/gedit-debug.h
(define-function debug
Modified: branches/message_system/plugin-loaders/python/bindings/geditmessage.override
==============================================================================
--- branches/message_system/plugin-loaders/python/bindings/geditmessage.override (original)
+++ branches/message_system/plugin-loaders/python/bindings/geditmessage.override Sat Dec 27 13:07:00 2008
@@ -33,80 +33,6 @@
}
static int
-_helper_wrap_message_types(PyObject *args, gchar ***keys, GType **types, gint *num, gboolean direct)
-{
- guint len, i;
- Py_ssize_t pos;
-
- len = PyTuple_Size(args);
-
- if (len == 1 && PyDict_Check(PyTuple_GetItem(args, 0)))
- {
- /* get key -> gtype from mapping */
- PyObject *dict = PyTuple_GetItem(args, 0);
- PyObject *key;
- PyObject *value;
-
- *num = PyDict_Size(dict);
- *types = g_new0(GType, *num);
- *keys = g_new0(gchar *, *num + 1);
- pos = 0;
- i = 0;
-
- while (PyDict_Next(dict, &pos, &key, &value)) {
- (*keys)[i] = _helper_wrap_get_string (key);
-
- if (direct) {
- (*types)[i] = _helper_wrap_get_gtype_from_pytype(value);
- } else {
- (*types)[i] = _helper_wrap_get_gtype_from_pytype((PyObject *)value->ob_type);
- }
-
- if ((*types)[i] == 0 || (*keys)[i] == NULL) {
- g_free(*types);
- g_strfreev(*keys);
- return 0;
- }
-
- i++;
- }
- }
- else
- {
- if (len % 2 != 0) {
- PyErr_SetString(PyExc_TypeError,
- "Even number of arguments expected (name/type pairs)");
- return 0;
- }
-
- *num = len / 2;
- *types = g_new(GType, *num);
- *keys = g_new0(gchar *, *num + 1);
-
- for (i = 0; i < *num; i++) {
- PyObject *key = PyTuple_GetItem(args, i * 2);
- PyObject *value = PyTuple_GetItem(args, i * 2 + 1);
-
- (*keys)[i] = _helper_wrap_get_string (key);
-
- if (direct) {
- (*types)[i] = _helper_wrap_get_gtype_from_pytype(value);
- } else {
- (*types)[i] = _helper_wrap_get_gtype_from_pytype((PyObject *)value->ob_type);
- }
-
- if ((*types)[i] == 0 || (*keys)[i] == NULL) {
- g_free(*types);
- g_strfreev(*keys);
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-static int
_helper_wrap_list_to_gvalue (GValue *gvalue, PyObject *pyvalue)
{
int num;
@@ -178,94 +104,82 @@
return 1;
}
-static int
-_helper_wrap_message_set_values(GeditMessage *message, PyObject *args)
+typedef void (*ParsePairFunc)(PyObject *key, PyObject *value, gpointer user_data);
+
+static void
+_helper_parse_pairs_dict (PyObject *dict, ParsePairFunc func, gpointer user_data)
{
- guint len;
+ if (!dict)
+ return;
+
+ PyObject *key, *value;
Py_ssize_t i;
+
+ while (PyDict_Next(dict, &i, &key, &value))
+ {
+ func(key, value, user_data);
+ }
+}
+
+static void
+_helper_parse_pairs(PyObject *args, PyObject *kwargs, ParsePairFunc func, gpointer user_data)
+{
+ guint len;
+ guint i;
len = PyTuple_Size(args);
-
- if (len == 1 && PyDict_Check(PyTuple_GetItem(args, 0)))
+
+ for (i = 0; i < len; ++i)
{
- /* do key -> value from mapping */
- PyObject *dict = PyTuple_GetItem(args, 0);
- PyObject *pykey, *pyvalue;
+ PyObject *d = PyTuple_GetItem(args, i);
- i = 0;
-
- while (PyDict_Next(dict, &i, &pykey, &pyvalue)) {
- if (!_helper_wrap_message_set_value(message, pykey, pyvalue))
- return 0;
- }
- } else {
- if (len % 2 != 0) {
- PyErr_SetString(PyExc_TypeError,
- "Even number of arguments expected (name/type pairs)");
- return 0;
- }
-
- for (i = 0; i < len / 2; i++) {
- PyObject *pykey = PyTuple_GetItem(args, i * 2);
- PyObject *pyvalue = PyTuple_GetItem(args, i * 2 + 1);
-
- if (!_helper_wrap_message_set_value(message, pykey, pyvalue))
- return 0;
- }
+ if (PyDict_Check(d))
+ _helper_parse_pairs_dict(d, func, user_data);
}
-
- return 1;
+
+ _helper_parse_pairs_dict(kwargs, func, user_data);
}
-static GeditMessage *
-_helper_wrap_create_message(PyObject *args)
+static void
+_helper_message_set(PyObject *key, PyObject *value, GeditMessage *message)
{
- guint len;
- gint num;
- gchar *domain;
- gchar *name;
- GType *types;
- gchar **keys;
- PyObject *slice;
- GeditMessage *message;
+ _helper_wrap_message_set_value(message, key, value);
+}
- len = PyTuple_Size(args);
+static void
+_helper_message_set_values(GeditMessage *message, PyObject *args, PyObject *kwargs)
+{
+ _helper_parse_pairs(args, kwargs, (ParsePairFunc)_helper_message_set, message);
+}
- if (len < 2) {
- PyErr_SetString(PyExc_TypeError,
- "GeditMessage requires at least two arguments");
+static GeditMessage *
+_helper_wrap_create_message(GeditMessageBus *bus, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "object_path", "method", NULL };
+ PyObject *pypath, *pymethod;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:GeditMessage.create", kwlist, &pypath, &pymethod))
return NULL;
- }
- domain = _helper_wrap_get_string(PyTuple_GetItem(args, 0));
- name = _helper_wrap_get_string(PyTuple_GetItem(args, 1));
+ gchar *object_path = _helper_wrap_get_string(pypath);
+ gchar *method = _helper_wrap_get_string(pymethod);
- if (!domain || !name) {
- PyErr_SetString(PyExc_TypeError,
- "First two arguments need to be strings");
- g_free (domain);
- g_free (name);
- return NULL;
+ GeditMessageType *message_type = gedit_message_bus_lookup (bus, object_path, method);
+ GeditMessage *message;
+
+ if (message_type)
+ {
+ message = gedit_message_type_instantiate(message_type, NULL);
+ _helper_wrap_message_set_value(message, args, kwargs);
}
-
- slice = PyTuple_GetSlice (args, 2, len);
-
- if (!_helper_wrap_message_types (slice, &keys, &types, &num, FALSE)) {
- Py_DECREF(slice);
- return NULL;
+ else
+ {
+ message = NULL;
}
-
- message = g_object_new(GEDIT_TYPE_MESSAGE, "domain", domain, "name", name, NULL);
- gedit_message_set_types (message, (const gchar **)keys, types, num);
-
- g_free(types);
- g_strfreev(keys);
- g_free (name);
- g_free (domain);
- _helper_wrap_message_set_values(message, slice);
- Py_DECREF(slice);
-
+ g_free(object_path);
+ g_free(method);
+
return message;
}
@@ -291,7 +205,9 @@
%%
ignore-glob
*_get_type
- gedit_message_new_valist
+ gedit_message_type_foreach
+ gedit_message_type_instantiate_valist
+ gedit_message_type_new_valist
gedit_message_get_valist
gedit_message_set_valist
gedit_message_set_valuesv
@@ -299,41 +215,59 @@
gedit_message_bus_block_by_func
gedit_message_bus_unblock_by_func
%%
-override gedit_message_new
+override gedit_message_type_new kwargs
+
+typedef struct
+{
+ GeditMessageType *message_type;
+ PyObject *optional;
+} MessageTypeSetInfo;
+
+static void
+_message_type_set(PyObject *key, PyObject *value, MessageTypeSetInfo *info)
+{
+ GType gtype;
+
+ gchar *k = _helper_wrap_get_string(key);
+
+ if (!k)
+ return;
+
+ gtype = _helper_wrap_get_gtype_from_pytype(value);
+
+ gedit_message_type_set(info->message_type, PySequence_Index(info->optional, key) != -1, k, gtype, NULL);
+ g_free(k);
+}
+
static int
-_wrap_gedit_message_new(PyGObject *self, PyObject *args)
+_wrap_gedit_message_type_new(PyGObject *self, PyObject *args, PyObject *kwargs)
{
- self->obj = (GObject *)_helper_wrap_create_message(args);
+ static char *kwlist[] = { "object_path", "method", "optional", NULL };
+ PyObject *pypath, *pymethod, *optional;
+ guint len;
- if (!self->obj) {
- PyErr_SetString(PyExc_RuntimeError,
- "could not create GeditMessage object");
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO:GeditMessageType.new", kwlist, &pypath, &pymethod, &optional))
return -1;
- }
- pygobject_register_wrapper((PyObject *)self);
-
- return 0;
+
+ GeditMessageType *message_type = GEDIT_MESSAGE_TYPE(g_object_new(pyg_type_from_object((PyObject *) self), NULL));
+
+ MessageTypeSetInfo info = {message_type, optional};
+ _helper_parse_pairs (args, kwargs, (ParsePairFunc)_message_type_set, &info);
+
+ self->obj = (GObject *)message_type;
+ pygobject_register_wrapper((PyObject *) self);
}
%%
-override gedit_message_set_types args
+override gedit_message_type_instantiate kwargs
static PyObject *
-_wrap_gedit_message_set_types(PyGObject *self, PyObject *args)
+_wrap_gedit_message_type_instantiate(PyGObject *self, PyObject *args, PyObject *kwargs)
{
- gint num;
- GType *types;
- gchar **keys;
-
- if (!_helper_wrap_message_types (args, &keys, &types, &num, TRUE)) {
- return NULL;
- }
-
- gedit_message_set_types (GEDIT_MESSAGE(self->obj), (const gchar **)keys, types, num);
-
- g_free(types);
- g_strfreev(keys);
-
- Py_INCREF (Py_None);
- return Py_None;
+ GeditMessageType *message_type = GEDIT_MESSAGE_TYPE (self->obj);
+ GeditMessage *message = gedit_message_type_instantiate(message_type, NULL);
+
+ _wrap_helper_message_set_value(message, args, kwargs);
+
+ return pygobject_new((GObject *)message);
}
%%
override gedit_message_get args
@@ -406,41 +340,56 @@
return Py_None;
}
%%
-override gedit_message_set args
+override gedit_message_set kwargs
static PyObject *
-_wrap_gedit_message_set (PyGObject *self, PyObject *args) {
- if (!_helper_wrap_message_set_values(GEDIT_MESSAGE(self->obj), args))
- return NULL;
-
+_wrap_gedit_message_set (PyGObject *self, PyObject *args, PyObject *kwargs) {
+ _helper_wrap_message_set_values(GEDIT_MESSAGE(self->obj), args, kwargs);
+
Py_INCREF(Py_None);
return Py_None;
}
%%
-override gedit_message_get_keys args
-static PyObject *
-_wrap_gedit_message_get_keys (PyGObject *self, PyObject *args) {
- PyObject *py_list;
- gchar **keys;
- gchar **ptr;
+override gedit_message_bus_new
+static int
+_wrap_gedit_message_bus_new(PyGObject *self)
+{
+ pygobject_construct (self, NULL);
- if ((py_list = PyList_New(0)) == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
+ if (!self->obj) {
+ PyErr_SetString (PyExc_RuntimeError, "could not create gedit.MessageBus object");
+ return -1;
}
+
+ return 0;
+}
+%%
+new-constructor GEDIT_TYPE_MESSAGE_BUS
+%%
+override gedit_message_bus_register kwargs
+static PyObject *
+_wrap_gedit_message_bus_register(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "object_path", "method", "optional", NULL };
+ PyObject *pypath, *pymethod, *optional;
+ guint len;
+ GeditMessageBus *bus = GEDIT_MESSAGE_BUS(self->obj);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO:GeditMessageBus.register", kwlist, &pypath, &pymethod, &optional))
+ return NULL;
- keys = gedit_message_get_keys (GEDIT_MESSAGE (self->obj));
- ptr = keys;
+ gchar *object_path = _helper_wrap_get_string(pypath);
+ gchar *method = _helper_wrap_get_string(pymethod);
- if (!keys)
- return py_list;
+ GeditMessageType *message_type = gedit_message_bus_register(bus, object_path, method, 0, NULL);
- while (*ptr)
- PyList_Append(py_list, PyString_FromString (*ptr));
-
- g_strfreev (keys);
- return py_list;
+ g_free(object_path);
+ g_free(method);
+
+ MessageTypeSetInfo info = {message_type, optional};
+ _helper_parse_pairs (args, kwargs, (ParsePairFunc)_message_type_set, &info);
+
+ return pyg_boxed_new(GEDIT_TYPE_MESSAGE_TYPE, message_type, TRUE, TRUE);
}
-
%%
override gedit_message_bus_connect kwargs
static void
@@ -507,19 +456,19 @@
return Py_None;
}
%%
-override gedit_message_bus_send args
+override gedit_message_bus_send kwargs
static PyObject *
-_wrap_gedit_message_bus_send (PyGObject *self, PyObject *args)
+_wrap_gedit_message_bus_send(PyGObject *self, PyObject *args, PyObject *kwargs)
{
/* create a new message object */
GeditMessage *message;
-
- message = _helper_wrap_create_message(args);
+ GeditMessageBus *bus = GEDIT_MESSAGE_BUS(self->obj);
+ message = _helper_wrap_create_message(bus, args, kwargs);
if (!message)
return NULL;
- gedit_message_bus_send_message(GEDIT_MESSAGE_BUS(self->obj), message);
+ gedit_message_bus_send_message(bus, message);
g_object_unref (message);
Py_INCREF(Py_None);
@@ -528,17 +477,18 @@
%%
override gedit_message_bus_send_sync args
static PyObject *
-_wrap_gedit_message_bus_send_sync (PyGObject *self, PyObject *args)
+_wrap_gedit_message_bus_send_sync(PyGObject *self, PyObject *args, PyObject *kwargs)
{
/* create a new message object */
GeditMessage *message;
+ GeditMessageBus *bus = GEDIT_MESSAGE_BUS(self->obj);
- message = _helper_wrap_create_message(args);
+ message = _helper_wrap_create_message(bus, args, kwargs);
if (!message)
return NULL;
- gedit_message_bus_send_message_sync(GEDIT_MESSAGE_BUS(self->obj), message);
+ gedit_message_bus_send_message_sync(bus, message);
return pygobject_new((GObject *)message);
}
%%
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]