[gmime] use a custom event API
- From: Jeffrey Stedfast <fejj src gnome org>
- To: svn-commits-list gnome org
- Subject: [gmime] use a custom event API
- Date: Sat, 25 Apr 2009 18:16:55 -0400 (EDT)
commit 8cb015a0a4cd4a54fc2ce55114966ae335ea75a0
Author: Jeffrey Stedfast <fejj gnome org>
Date: Sat Apr 25 18:15:17 2009 -0400
use a custom event API
2009-04-25 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-parse-utils.h: Marked APIs as internal linkage only.
* gmime/gmime-common.h: Same.
* gmime/gmime-content-type.c: Use the new GMimeEvent API instead
of libgobject's g_signal API which is more than we need.
* gmime/gmime-disposition.c: Same.
* gmime/gmime-object.c: Updated to use the GMimeEvent API for
content-type and content-disposition.
* gmime/internet-address.c: Use the new GMimeEvent API instead of
our own.
* gmime/gmime-events.[c,h]: New source files implementing a simple
and performant event system needed internally within GMime. Based
on the event system that used to be in internet-address.c
---
ChangeLog | 17 +++
TODO | 2 +-
build/vs2008/gmime.vcproj | 8 ++
docs/reference/Makefile.am | 4 +-
docs/reference/gmime-sections.txt | 4 +-
gmime/Makefile.am | 8 +-
gmime/gmime-common.h | 4 +-
gmime/gmime-content-type.c | 29 +----
gmime/gmime-content-type.h | 3 +
gmime/gmime-disposition.c | 27 +----
gmime/gmime-disposition.h | 3 +
gmime/gmime-events.c | 220 +++++++++++++++++++++++++++++++++++++
gmime/gmime-events.h | 47 ++++++++
gmime/gmime-message.c | 26 ++---
gmime/gmime-object.c | 37 +++----
gmime/gmime-parse-utils.h | 8 +-
gmime/internet-address.c | 216 ++++++-------------------------------
17 files changed, 384 insertions(+), 279 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4a275f9..4f5ce1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2009-04-25 Jeffrey Stedfast <fejj novell com>
+
+ * gmime/gmime-content-type.c: Use the new GMimeEvent API instead
+ of libgobject's g_signal API which is more than we need.
+
+ * gmime/gmime-disposition.c: Same.
+
+ * gmime/gmime-object.c: Updated to use the GMimeEvent API for
+ content-type and content-disposition.
+
+ * gmime/internet-address.c: Use the new GMimeEvent API instead of
+ our own.
+
+ * gmime/gmime-events.[c,h]: New source files implementing a simple
+ and performant event system needed internally within GMime. Based
+ on the event system that used to be in internet-address.c
+
2009-04-24 Jeffrey Stedfast <fejj novell com>
* gmime/gmime-parser.c (struct _GMimeParserPrivate): Added
diff --git a/TODO b/TODO
index c50a4b5..6eb9445 100644
--- a/TODO
+++ b/TODO
@@ -8,7 +8,7 @@ GMime 2.6 Planning:
===================
- Replace all uses of g_signals with my own event stuff. None of this
- needs to be public and my events are a lot more performant.
+ needs to be public and my events are a lot more performant. [ DONE ]
- Need to add a Changed event to GMimeHeaderList so that GMimeMessage
can listen to changes in the toplevel mime_part's headers. When they
diff --git a/build/vs2008/gmime.vcproj b/build/vs2008/gmime.vcproj
index 4d87f84..063121f 100644
--- a/build/vs2008/gmime.vcproj
+++ b/build/vs2008/gmime.vcproj
@@ -205,6 +205,10 @@
>
</File>
<File
+ RelativePath="..\..\gmime\gmime-events.h"
+ >
+ </File>
+ <File
RelativePath="..\..\gmime\gmime-filter-basic.h"
>
</File>
@@ -429,6 +433,10 @@
>
</File>
<File
+ RelativePath="..\..\gmime\gmime-events.c"
+ >
+ </File>
+ <File
RelativePath="..\..\gmime\gmime-filter-basic.c"
>
</File>
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 5628403..0e71d49 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -59,7 +59,9 @@ CFILE_GLOB=$(top_srcdir)/gmime/*.c
IGNORE_HFILES = \
gmime-charset-map-private.h \
gmime-table-private.h \
- gmime-type-utils.h
+ gmime-parse-utils.h \
+ gmime-common.h \
+ gmime-events.h
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS =
diff --git a/docs/reference/gmime-sections.txt b/docs/reference/gmime-sections.txt
index 137f7e7..c2db0f2 100644
--- a/docs/reference/gmime-sections.txt
+++ b/docs/reference/gmime-sections.txt
@@ -602,8 +602,8 @@ g_mime_header_list_foreach
g_mime_header_list_register_writer
g_mime_header_list_write_to_stream
g_mime_header_list_to_string
-g_mime_header_list_has_raw
-g_mime_header_list_set_raw
+g_mime_header_list_get_stream
+g_mime_header_list_set_stream
</SECTION>
<SECTION>
diff --git a/gmime/Makefile.am b/gmime/Makefile.am
index 9c4295e..f8037dd 100644
--- a/gmime/Makefile.am
+++ b/gmime/Makefile.am
@@ -25,6 +25,7 @@ libgmime_2_6_la_SOURCES = \
gmime-data-wrapper.c \
gmime-disposition.c \
gmime-encodings.c \
+ gmime-events.c \
gmime-filter.c \
gmime-filter-basic.c \
gmime-filter-best.c \
@@ -101,7 +102,6 @@ gmimeinclude_HEADERS = \
gmime-multipart-signed.h \
gmime-object.h \
gmime-param.h \
- gmime-parse-utils.h \
gmime-parser.h \
gmime-part.h \
gmime-session.h \
@@ -119,9 +119,11 @@ gmimeinclude_HEADERS = \
internet-address.h
noinst_HEADERS = \
- gmime-common.h \
+ gmime-charset-map-private.h \
gmime-table-private.h \
- gmime-charset-map-private.h
+ gmime-parse-utils.h \
+ gmime-common.h \
+ gmime-events.h
install-data-local: install-libtool-import-lib
diff --git a/gmime/gmime-common.h b/gmime/gmime-common.h
index 5465cd2..26590eb 100644
--- a/gmime/gmime-common.h
+++ b/gmime/gmime-common.h
@@ -26,9 +26,9 @@
G_BEGIN_DECLS
-int g_mime_strcase_equal (gconstpointer v, gconstpointer v2);
+G_GNUC_INTERNAL int g_mime_strcase_equal (gconstpointer v, gconstpointer v2);
-guint g_mime_strcase_hash (gconstpointer key);
+G_GNUC_INTERNAL guint g_mime_strcase_hash (gconstpointer key);
G_END_DECLS
diff --git a/gmime/gmime-content-type.c b/gmime/gmime-content-type.c
index 86bf3fd..987c63e 100644
--- a/gmime/gmime-content-type.c
+++ b/gmime/gmime-content-type.c
@@ -30,6 +30,7 @@
#include "gmime-common.h"
#include "gmime-content-type.h"
#include "gmime-parse-utils.h"
+#include "gmime-events.h"
#ifdef ENABLE_WARNINGS
@@ -52,13 +53,6 @@
**/
-enum {
- CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
static void g_mime_content_type_class_init (GMimeContentTypeClass *klass);
static void g_mime_content_type_init (GMimeContentType *content_type, GMimeContentTypeClass *klass);
static void g_mime_content_type_finalize (GObject *object);
@@ -100,23 +94,13 @@ g_mime_content_type_class_init (GMimeContentTypeClass *klass)
parent_class = g_type_class_ref (G_TYPE_OBJECT);
object_class->finalize = g_mime_content_type_finalize;
-
- /* signals */
- signals[CHANGED] =
- g_signal_new ("changed",
- GMIME_TYPE_CONTENT_TYPE,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
g_mime_content_type_init (GMimeContentType *content_type, GMimeContentTypeClass *klass)
{
content_type->param_hash = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
+ content_type->priv = g_mime_event_new ((GObject *) content_type);
content_type->params = NULL;
content_type->subtype = NULL;
content_type->type = NULL;
@@ -129,6 +113,7 @@ g_mime_content_type_finalize (GObject *object)
g_hash_table_destroy (content_type->param_hash);
g_mime_param_destroy (content_type->params);
+ g_mime_event_destroy (content_type->priv);
g_free (content_type->subtype);
g_free (content_type->type);
@@ -303,7 +288,7 @@ g_mime_content_type_set_media_type (GMimeContentType *mime_type, const char *typ
g_free (mime_type->type);
mime_type->type = buf;
- g_signal_emit (mime_type, signals[CHANGED], 0);
+ g_mime_event_emit (mime_type->priv, NULL);
}
@@ -343,7 +328,7 @@ g_mime_content_type_set_media_subtype (GMimeContentType *mime_type, const char *
g_free (mime_type->subtype);
mime_type->subtype = buf;
- g_signal_emit (mime_type, signals[CHANGED], 0);
+ g_mime_event_emit (mime_type->priv, NULL);
}
@@ -386,7 +371,7 @@ g_mime_content_type_set_params (GMimeContentType *mime_type, GMimeParam *params)
params = params->next;
}
- g_signal_emit (mime_type, signals[CHANGED], 0);
+ g_mime_event_emit (mime_type->priv, NULL);
}
@@ -433,7 +418,7 @@ g_mime_content_type_set_parameter (GMimeContentType *mime_type, const char *attr
g_hash_table_insert (mime_type->param_hash, param->name, param);
}
- g_signal_emit (mime_type, signals[CHANGED], 0);
+ g_mime_event_emit (mime_type->priv, NULL);
}
diff --git a/gmime/gmime-content-type.h b/gmime/gmime-content-type.h
index 42950a2..d29e730 100644
--- a/gmime/gmime-content-type.h
+++ b/gmime/gmime-content-type.h
@@ -54,6 +54,9 @@ struct _GMimeContentType {
GHashTable *param_hash;
GMimeParam *params;
+
+ gpointer priv;
+
char *type;
char *subtype;
};
diff --git a/gmime/gmime-disposition.c b/gmime/gmime-disposition.c
index a24e2b9..9710c45 100644
--- a/gmime/gmime-disposition.c
+++ b/gmime/gmime-disposition.c
@@ -28,6 +28,7 @@
#include "gmime-common.h"
#include "gmime-disposition.h"
+#include "gmime-events.h"
/**
@@ -41,13 +42,6 @@
**/
-enum {
- CHANGED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
static void g_mime_content_disposition_class_init (GMimeContentDispositionClass *klass);
static void g_mime_content_disposition_init (GMimeContentDisposition *disposition, GMimeContentDispositionClass *klass);
static void g_mime_content_disposition_finalize (GObject *object);
@@ -89,23 +83,13 @@ g_mime_content_disposition_class_init (GMimeContentDispositionClass *klass)
parent_class = g_type_class_ref (G_TYPE_OBJECT);
object_class->finalize = g_mime_content_disposition_finalize;
-
- /* signals */
- signals[CHANGED] =
- g_signal_new ("changed",
- GMIME_TYPE_CONTENT_DISPOSITION,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
}
static void
g_mime_content_disposition_init (GMimeContentDisposition *disposition, GMimeContentDispositionClass *klass)
{
disposition->param_hash = g_hash_table_new (g_mime_strcase_hash, g_mime_strcase_equal);
+ disposition->priv = g_mime_event_new ((GObject *) disposition);
disposition->disposition = NULL;
disposition->params = NULL;
}
@@ -117,6 +101,7 @@ g_mime_content_disposition_finalize (GObject *object)
g_hash_table_destroy (disposition->param_hash);
g_mime_param_destroy (disposition->params);
+ g_mime_event_destroy (disposition->priv);
g_free (disposition->disposition);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -208,7 +193,7 @@ g_mime_content_disposition_set_disposition (GMimeContentDisposition *disposition
g_free (disposition->disposition);
disposition->disposition = buf;
- g_signal_emit (disposition, signals[CHANGED], 0);
+ g_mime_event_emit (disposition->priv, NULL);
}
@@ -252,7 +237,7 @@ g_mime_content_disposition_set_params (GMimeContentDisposition *disposition, GMi
params = params->next;
}
- g_signal_emit (disposition, signals[CHANGED], 0);
+ g_mime_event_emit (disposition->priv, NULL);
}
@@ -299,7 +284,7 @@ g_mime_content_disposition_set_parameter (GMimeContentDisposition *disposition,
g_hash_table_insert (disposition->param_hash, param->name, param);
}
- g_signal_emit (disposition, signals[CHANGED], 0);
+ g_mime_event_emit (disposition->priv, NULL);
}
diff --git a/gmime/gmime-disposition.h b/gmime/gmime-disposition.h
index 32a84dd..728821f 100644
--- a/gmime/gmime-disposition.h
+++ b/gmime/gmime-disposition.h
@@ -69,6 +69,9 @@ struct _GMimeContentDisposition {
GHashTable *param_hash;
GMimeParam *params;
+
+ gpointer priv;
+
char *disposition;
};
diff --git a/gmime/gmime-events.c b/gmime/gmime-events.c
new file mode 100644
index 0000000..305079c
--- /dev/null
+++ b/gmime/gmime-events.c
@@ -0,0 +1,220 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2009 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gmime-events.h"
+#include "list.h"
+
+typedef struct _EventListener {
+ struct _EventListener *next;
+ struct _EventListener *prev;
+ GMimeEventCallback callback;
+ gpointer user_data;
+ int blocked;
+} EventListener;
+
+static EventListener *
+event_listener_new (GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ listener = g_slice_new (EventListener);
+ listener->user_data = user_data;
+ listener->callback = callback;
+ listener->prev = NULL;
+ listener->next = NULL;
+ listener->blocked = 0;
+
+ return listener;
+}
+
+static void
+event_listener_free (EventListener *listener)
+{
+ g_slice_free (EventListener, listener);
+}
+
+
+struct _GMimeEvent {
+ GObject *owner;
+ List list;
+};
+
+
+/**
+ * g_mime_event_new:
+ * @owner: a #GObject; typically the one that will own this event
+ *
+ * Creates a new #GMimeEvent context.
+ *
+ * Returns: a newly allocated #GMimeEvent context.
+ **/
+GMimeEvent *
+g_mime_event_new (GObject *owner)
+{
+ GMimeEvent *event;
+
+ event = g_slice_new (GMimeEvent);
+ list_init (&event->list);
+ event->owner = owner;
+
+ return event;
+}
+
+
+/**
+ * g_mime_event_destroy:
+ * @event: a #GMimeEvent
+ *
+ * Destroys an event context.
+ **/
+void
+g_mime_event_destroy (GMimeEvent *event)
+{
+ EventListener *node, *next;
+
+ node = (EventListener *) &event->list.head;
+ while (node->next) {
+ next = node->next;
+ event_listener_free (node);
+ node = next;
+ }
+
+ g_slice_free (GMimeEvent, event);
+}
+
+
+static EventListener *
+g_mime_event_find_listener (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *node;
+
+ node = (EventListener *) &event->list.head;
+ while (node->next) {
+ if (node->callback == callback && node->user_data == user_data)
+ return node;
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * g_mime_event_block:
+ * @event: a #GMimeEvent
+ * @callback: a #GMimeEventCallback
+ * @user_data: user context data
+ *
+ * Blocks the specified callback from being called when @event is emitted.
+ **/
+void
+g_mime_event_block (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = g_mime_event_find_listener (event, callback, user_data)))
+ listener->blocked++;
+}
+
+
+/**
+ * g_mime_event_unblock:
+ * @event: a #GMimeEvent
+ * @callback: a #GMimeEventCallback
+ * @user_data: user context data
+ *
+ * Unblocks the specified callback from being called when @event is
+ * emitted.
+ **/
+void
+g_mime_event_unblock (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = g_mime_event_find_listener (event, callback, user_data)))
+ listener->blocked--;
+}
+
+
+/**
+ * g_mime_event_add:
+ * @event: a #GMimeEvent
+ * @callback: a #GMimeEventCallback
+ * @user_data: user context data
+ *
+ * Adds a callback function that will get called with the specified
+ * @user_data whenever @event is emitted.
+ **/
+void
+g_mime_event_add (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ listener = event_listener_new (callback, user_data);
+ list_append (&event->list, (ListNode *) listener);
+}
+
+
+/**
+ * g_mime_event_remove:
+ * @event: a #GMimeEvent
+ * @callback: a #GMimeEventCallback
+ * @user_data: user context data
+ *
+ * Removes the specified callback function from the list of callbacks
+ * that will be called when the @event is emitted.
+ **/
+void
+g_mime_event_remove (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
+{
+ EventListener *listener;
+
+ if ((listener = g_mime_event_find_listener (event, callback, user_data))) {
+ list_unlink ((ListNode *) listener);
+ event_listener_free (listener);
+ }
+}
+
+
+/**
+ * g_mime_event_emit:
+ * @event: a #GMimeEvent
+ * @args: an argument pointer
+ *
+ * Calls each callback registered with this @event with the specified
+ * @args.
+ **/
+void
+g_mime_event_emit (GMimeEvent *event, gpointer args)
+{
+ EventListener *node;
+
+ node = (EventListener *) &event->list.head;
+ while (node->next) {
+ if (node->blocked <= 0)
+ node->callback (event->owner, args, node->user_data);
+ node = node->next;
+ }
+}
diff --git a/gmime/gmime-events.h b/gmime/gmime-events.h
new file mode 100644
index 0000000..1755075
--- /dev/null
+++ b/gmime/gmime-events.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2009 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifndef __GMIME_EVENTS_H__
+#define __GMIME_EVENTS_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef void (* GMimeEventCallback) (GObject *sender, gpointer args, gpointer user_data);
+
+typedef struct _GMimeEvent GMimeEvent;
+
+G_GNUC_INTERNAL GMimeEvent *g_mime_event_new (GObject *owner);
+G_GNUC_INTERNAL void g_mime_event_destroy (GMimeEvent *event);
+
+G_GNUC_INTERNAL void g_mime_event_add (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data);
+G_GNUC_INTERNAL void g_mime_event_remove (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data);
+
+G_GNUC_INTERNAL void g_mime_event_block (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data);
+G_GNUC_INTERNAL void g_mime_event_unblock (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data);
+
+G_GNUC_INTERNAL void g_mime_event_emit (GMimeEvent *event, gpointer args);
+
+G_END_DECLS
+
+#endif /* __GMIME_EVENTS_H__ */
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index b9ab70b..3db85f4 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -34,6 +34,7 @@
#include "gmime-stream-mem.h"
#include "gmime-table-private.h"
#include "gmime-parse-utils.h"
+#include "gmime-events.h"
/**
@@ -46,14 +47,6 @@
**/
-typedef void (* EventCallback) (gpointer sender, gpointer args);
-
-extern void _internet_address_list_block_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
-extern void _internet_address_list_unblock_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
-extern void _internet_address_list_add_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
-extern void _internet_address_list_remove_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data);
-
-
static void g_mime_message_class_init (GMimeMessageClass *klass);
static void g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass);
static void g_mime_message_finalize (GObject *object);
@@ -80,13 +73,14 @@ static void bcc_list_changed (InternetAddressList *list, GMimeMessage *message);
static GMimeObjectClass *parent_class = NULL;
+
static struct {
const char *name;
- EventCallback changed_cb;
+ GMimeEventCallback changed_cb;
} recipient_types[] = {
- { "To", (EventCallback) to_list_changed },
- { "Cc", (EventCallback) cc_list_changed },
- { "Bcc", (EventCallback) bcc_list_changed }
+ { "To", (GMimeEventCallback) to_list_changed },
+ { "Cc", (GMimeEventCallback) cc_list_changed },
+ { "Bcc", (GMimeEventCallback) bcc_list_changed }
};
#define N_RECIPIENT_TYPES G_N_ELEMENTS (recipient_types)
@@ -155,7 +149,7 @@ connect_changed_event (GMimeMessage *message, GMimeRecipientType type)
list = message->recipients[type];
- _internet_address_list_add_event_handler (list, recipient_types[type].changed_cb, message);
+ g_mime_event_add (list->priv, recipient_types[type].changed_cb, message);
}
static void
@@ -165,7 +159,7 @@ disconnect_changed_event (GMimeMessage *message, GMimeRecipientType type)
list = message->recipients[type];
- _internet_address_list_remove_event_handler (list, recipient_types[type].changed_cb, message);
+ g_mime_event_remove (list->priv, recipient_types[type].changed_cb, message);
}
static void
@@ -175,7 +169,7 @@ block_changed_event (GMimeMessage *message, GMimeRecipientType type)
list = message->recipients[type];
- _internet_address_list_block_event_handler (list, recipient_types[type].changed_cb, message);
+ g_mime_event_block (list->priv, recipient_types[type].changed_cb, message);
}
static void
@@ -185,7 +179,7 @@ unblock_changed_event (GMimeMessage *message, GMimeRecipientType type)
list = message->recipients[type];
- _internet_address_list_block_event_handler (list, recipient_types[type].changed_cb, message);
+ g_mime_event_unblock (list->priv, recipient_types[type].changed_cb, message);
}
static void
diff --git a/gmime/gmime-object.c b/gmime/gmime-object.c
index 6b32093..44a5381 100644
--- a/gmime/gmime-object.c
+++ b/gmime/gmime-object.c
@@ -29,6 +29,7 @@
#include "gmime-common.h"
#include "gmime-object.h"
#include "gmime-stream-mem.h"
+#include "gmime-events.h"
#include "gmime-utils.h"
@@ -73,8 +74,8 @@ static ssize_t write_to_stream (GMimeObject *object, GMimeStream *stream);
static ssize_t write_content_type (GMimeStream *stream, const char *name, const char *value);
static ssize_t write_disposition (GMimeStream *stream, const char *name, const char *value);
-static void content_type_changed (GMimeContentType *content_type, GMimeObject *object);
-static void content_disposition_changed (GMimeContentDisposition *disposition, GMimeObject *object);
+static void content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject *object);
+static void content_disposition_changed (GMimeContentDisposition *disposition, gpointer args, GMimeObject *object);
static void type_registry_init (void);
@@ -149,16 +150,12 @@ g_mime_object_finalize (GObject *object)
GMimeObject *mime = (GMimeObject *) object;
if (mime->content_type) {
- g_signal_handlers_disconnect_matched (mime->content_type,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_type_changed, object);
+ g_mime_event_remove (mime->content_type->priv, (GMimeEventCallback) content_type_changed, object);
g_object_unref (mime->content_type);
}
if (mime->disposition) {
- g_signal_handlers_disconnect_matched (mime->disposition,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_disposition_changed, object);
+ g_mime_event_remove (mime->disposition->priv, (GMimeEventCallback) content_disposition_changed, object);
g_object_unref (mime->disposition);
}
@@ -198,7 +195,7 @@ write_content_type (GMimeStream *stream, const char *name, const char *value)
}
static void
-content_type_changed (GMimeContentType *content_type, GMimeObject *object)
+content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject *object)
{
GMimeParam *params;
GString *string;
@@ -244,7 +241,7 @@ write_disposition (GMimeStream *stream, const char *name, const char *value)
}
static void
-content_disposition_changed (GMimeContentDisposition *disposition, GMimeObject *object)
+content_disposition_changed (GMimeContentDisposition *disposition, gpointer args, GMimeObject *object)
{
char *str;
@@ -408,13 +405,11 @@ static void
set_content_type (GMimeObject *object, GMimeContentType *content_type)
{
if (object->content_type) {
- g_signal_handlers_disconnect_matched (object->content_type,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_type_changed, object);
+ g_mime_event_remove (object->content_type->priv, (GMimeEventCallback) content_type_changed, object);
g_object_unref (object->content_type);
}
- g_signal_connect (content_type, "changed", G_CALLBACK (content_type_changed), object);
+ g_mime_event_add (content_type->priv, (GMimeEventCallback) content_type_changed, object);
object->content_type = content_type;
g_object_ref (content_type);
}
@@ -456,7 +451,7 @@ g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_t
GMIME_OBJECT_GET_CLASS (object)->set_content_type (object, content_type);
- content_type_changed (content_type, object);
+ content_type_changed (content_type, NULL, object);
}
@@ -548,13 +543,11 @@ static void
_g_mime_object_set_content_disposition (GMimeObject *object, GMimeContentDisposition *disposition)
{
if (object->disposition) {
- g_signal_handlers_disconnect_matched (object->disposition,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_disposition_changed, object);
+ g_mime_event_remove (object->disposition->priv, (GMimeEventCallback) content_disposition_changed, object);
g_object_unref (object->disposition);
}
- g_signal_connect (disposition, "changed", G_CALLBACK (content_disposition_changed), object);
+ g_mime_event_add (disposition->priv, (GMimeEventCallback) content_disposition_changed, object);
object->disposition = disposition;
g_object_ref (disposition);
}
@@ -579,7 +572,7 @@ g_mime_object_set_content_disposition (GMimeObject *object, GMimeContentDisposit
_g_mime_object_set_content_disposition (object, disposition);
- content_disposition_changed (disposition, object);
+ content_disposition_changed (disposition, NULL, object);
}
@@ -893,9 +886,7 @@ remove_header (GMimeObject *object, const char *header)
switch (i) {
case HEADER_CONTENT_DISPOSITION:
if (object->disposition) {
- g_signal_handlers_disconnect_matched (object->disposition,
- G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, content_disposition_changed, object);
+ g_mime_event_remove (object->disposition->priv, (GMimeEventCallback) content_disposition_changed, object);
g_object_unref (object->disposition);
object->disposition = NULL;
}
diff --git a/gmime/gmime-parse-utils.h b/gmime/gmime-parse-utils.h
index 96e361f..9ecbef3 100644
--- a/gmime/gmime-parse-utils.h
+++ b/gmime/gmime-parse-utils.h
@@ -24,15 +24,15 @@
G_BEGIN_DECLS
-gboolean g_mime_parse_content_type (const char **in, char **type, char **subtype);
+G_GNUC_INTERNAL gboolean g_mime_parse_content_type (const char **in, char **type, char **subtype);
-void g_mime_decode_lwsp (const char **in);
+G_GNUC_INTERNAL void g_mime_decode_lwsp (const char **in);
#define decode_lwsp(in) g_mime_decode_lwsp (in)
-const char *g_mime_decode_word (const char **in);
+G_GNUC_INTERNAL const char *g_mime_decode_word (const char **in);
#define decode_word(in) g_mime_decode_word (in)
-gboolean g_mime_decode_domain (const char **in, GString *domain);
+G_GNUC_INTERNAL gboolean g_mime_decode_domain (const char **in, GString *domain);
#define decode_domain(in, domain) g_mime_decode_domain (in, domain)
G_END_DECLS
diff --git a/gmime/internet-address.c b/gmime/internet-address.c
index 7dbba42..6309447 100644
--- a/gmime/internet-address.c
+++ b/gmime/internet-address.c
@@ -32,6 +32,7 @@
#include "gmime-table-private.h"
#include "gmime-parse-utils.h"
#include "gmime-iconv-utils.h"
+#include "gmime-events.h"
#include "gmime-utils.h"
#include "list.h"
@@ -91,131 +92,6 @@ enum {
};
-typedef void (* EventCallback) (gpointer sender, gpointer args);
-
-typedef struct _EventListener {
- struct _EventListener *next;
- struct _EventListener *prev;
- EventCallback callback;
- gpointer user_data;
- int blocked;
-} EventListener;
-
-static EventListener *
-event_listener_new (EventCallback callback, gpointer user_data)
-{
- EventListener *listener;
-
- listener = g_slice_new (EventListener);
- listener->user_data = user_data;
- listener->callback = callback;
- listener->prev = NULL;
- listener->next = NULL;
- listener->blocked = 0;
-
- return listener;
-}
-
-static void
-event_listener_free (EventListener *listener)
-{
- g_slice_free (EventListener, listener);
-}
-
-
-static List *
-event_list_new (void)
-{
- List *list;
-
- list = g_slice_new (List);
- list_init (list);
-
- return list;
-}
-
-static void
-event_list_free (List *list)
-{
- EventListener *node, *next;
-
- node = (EventListener *) list->head;
- while (node->next) {
- next = node->next;
- event_listener_free (node);
- node = next;
- }
-
- g_slice_free (List, list);
-}
-
-static EventListener *
-event_list_find_listener (List *list, EventCallback callback, gpointer user_data)
-{
- EventListener *node;
-
- node = (EventListener *) list->head;
- while (node->next) {
- if (node->callback == callback && node->user_data == user_data)
- return node;
- node = node->next;
- }
-
- return NULL;
-}
-
-static void
-event_list_block (List *list, EventCallback callback, gpointer user_data)
-{
- EventListener *listener;
-
- if ((listener = event_list_find_listener (list, callback, user_data)))
- listener->blocked++;
-}
-
-static void
-event_list_unblock (List *list, EventCallback callback, gpointer user_data)
-{
- EventListener *listener;
-
- if ((listener = event_list_find_listener (list, callback, user_data)))
- listener->blocked--;
-}
-
-static void
-event_list_add (List *list, EventCallback callback, gpointer user_data)
-{
- EventListener *listener;
-
- listener = event_listener_new (callback, user_data);
- list_append (list, (ListNode *) listener);
-}
-
-static void
-event_list_remove (List *list, EventCallback callback, gpointer user_data)
-{
- EventListener *listener;
-
- if ((listener = event_list_find_listener (list, callback, user_data))) {
- list_unlink ((ListNode *) listener);
- event_listener_free (listener);
- }
-}
-
-static void
-event_list_emit (List *list, gpointer sender)
-{
- EventListener *node;
-
- node = (EventListener *) list->head;
- while (node->next) {
- if (node->blocked <= 0)
- node->callback (sender, node->user_data);
- node = node->next;
- }
-}
-
-
static void internet_address_class_init (InternetAddressClass *klass);
static void internet_address_init (InternetAddress *ia, InternetAddressClass *klass);
static void internet_address_finalize (GObject *object);
@@ -265,7 +141,7 @@ internet_address_class_init (InternetAddressClass *klass)
static void
internet_address_init (InternetAddress *ia, InternetAddressClass *klass)
{
- ia->priv = event_list_new ();
+ ia->priv = g_mime_event_new ((GObject *) ia);
ia->name = NULL;
}
@@ -274,7 +150,7 @@ internet_address_finalize (GObject *object)
{
InternetAddress *ia = (InternetAddress *) object;
- event_list_free (ia->priv);
+ g_mime_event_destroy (ia->priv);
g_free (ia->name);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -311,7 +187,7 @@ internet_address_set_name (InternetAddress *ia, const char *name)
_internet_address_set_name (ia, name);
- event_list_emit (ia->priv, ia);
+ g_mime_event_emit (ia->priv, NULL);
}
@@ -471,7 +347,7 @@ internet_address_mailbox_set_addr (InternetAddressMailbox *mailbox, const char *
g_free (mailbox->addr);
mailbox->addr = g_strdup (addr);
- event_list_emit (((InternetAddress *) mailbox)->priv, mailbox);
+ g_mime_event_emit (((InternetAddress *) mailbox)->priv, NULL);
}
@@ -541,9 +417,9 @@ internet_address_group_class_init (InternetAddressGroupClass *klass)
}
static void
-members_changed (InternetAddressList *members, InternetAddress *group)
+members_changed (InternetAddressList *members, gpointer args, InternetAddress *group)
{
- event_list_emit (((InternetAddress *) group)->priv, group);
+ g_mime_event_emit (((InternetAddress *) group)->priv, NULL);
}
static void
@@ -551,7 +427,7 @@ internet_address_group_init (InternetAddressGroup *group, InternetAddressGroupCl
{
group->members = internet_address_list_new ();
- event_list_add (group->members->priv, (EventCallback) members_changed, group);
+ g_mime_event_add (group->members->priv, (GMimeEventCallback) members_changed, group);
}
static void
@@ -559,7 +435,7 @@ internet_address_group_finalize (GObject *object)
{
InternetAddressGroup *group = (InternetAddressGroup *) object;
- event_list_remove (group->members->priv, (EventCallback) members_changed, group);
+ g_mime_event_remove (group->members->priv, (GMimeEventCallback) members_changed, group);
g_object_unref (group->members);
@@ -605,18 +481,18 @@ internet_address_group_set_members (InternetAddressGroup *group, InternetAddress
return;
if (group->members) {
- event_list_remove (group->members->priv, (EventCallback) members_changed, group);
+ g_mime_event_remove (group->members->priv, (GMimeEventCallback) members_changed, group);
g_object_unref (group->members);
}
if (members) {
- event_list_add (members->priv, (EventCallback) members_changed, group);
+ g_mime_event_add (members->priv, (GMimeEventCallback) members_changed, group);
g_object_ref (members);
}
group->members = members;
- event_list_emit (((InternetAddress *) group)->priv, group);
+ g_mime_event_emit (((InternetAddress *) group)->priv, NULL);
}
@@ -705,14 +581,14 @@ internet_address_list_class_init (InternetAddressListClass *klass)
static void
internet_address_list_init (InternetAddressList *list, InternetAddressListClass *klass)
{
- list->priv = event_list_new ();
+ list->priv = g_mime_event_new ((GObject *) list);
list->array = g_ptr_array_new ();
}
static void
-address_changed (InternetAddress *ia, InternetAddressList *list)
+address_changed (InternetAddress *ia, gpointer args, InternetAddressList *list)
{
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
static void
@@ -724,11 +600,11 @@ internet_address_list_finalize (GObject *object)
for (i = 0; i < list->array->len; i++) {
ia = (InternetAddress *) list->array->pdata[i];
- event_list_remove (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_remove (ia->priv, (GMimeEventCallback) address_changed, list);
g_object_unref (ia);
}
- event_list_free (list->priv);
+ g_mime_event_destroy (list->priv);
g_ptr_array_free (list->array, TRUE);
@@ -783,13 +659,13 @@ internet_address_list_clear (InternetAddressList *list)
for (i = 0; i < list->array->len; i++) {
ia = (InternetAddress *) list->array->pdata[i];
- event_list_remove (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_remove (ia->priv, (GMimeEventCallback) address_changed, list);
g_object_unref (ia);
}
g_ptr_array_set_size (list->array, 0);
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
@@ -798,7 +674,7 @@ _internet_address_list_add (InternetAddressList *list, InternetAddress *ia)
{
int index;
- event_list_add (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_add (ia->priv, (GMimeEventCallback) address_changed, list);
index = list->array->len;
g_ptr_array_add (list->array, ia);
@@ -827,7 +703,7 @@ internet_address_list_add (InternetAddressList *list, InternetAddress *ia)
index = _internet_address_list_add (list, ia);
g_object_ref (ia);
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
return index;
}
@@ -863,12 +739,12 @@ internet_address_list_prepend (InternetAddressList *list, InternetAddressList *p
for (i = 0; i < prepend->array->len; i++) {
ia = (InternetAddress *) prepend->array->pdata[i];
- event_list_add (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_add (ia->priv, (GMimeEventCallback) address_changed, list);
list->array->pdata[i] = ia;
g_object_ref (ia);
}
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
@@ -893,12 +769,12 @@ internet_address_list_append (InternetAddressList *list, InternetAddressList *ap
for (i = 0; i < append->array->len; i++) {
ia = (InternetAddress *) append->array->pdata[i];
- event_list_add (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_add (ia->priv, (GMimeEventCallback) address_changed, list);
list->array->pdata[len + i] = ia;
g_object_ref (ia);
}
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
@@ -921,7 +797,7 @@ internet_address_list_insert (InternetAddressList *list, int index, InternetAddr
g_return_if_fail (IS_INTERNET_ADDRESS (ia));
g_return_if_fail (index >= 0);
- event_list_add (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_add (ia->priv, (GMimeEventCallback) address_changed, list);
g_object_ref (ia);
if ((guint) index < list->array->len) {
@@ -938,7 +814,7 @@ internet_address_list_insert (InternetAddressList *list, int index, InternetAddr
g_ptr_array_add (list->array, ia);
}
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
@@ -992,12 +868,12 @@ internet_address_list_remove_at (InternetAddressList *list, int index)
return FALSE;
ia = list->array->pdata[index];
- event_list_remove (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_remove (ia->priv, (GMimeEventCallback) address_changed, list);
g_object_unref (ia);
g_ptr_array_remove_index (list->array, index);
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
return TRUE;
}
@@ -1101,14 +977,14 @@ internet_address_list_set_address (InternetAddressList *list, int index, Interne
if ((old = list->array->pdata[index]) == ia)
return;
- event_list_remove (old->priv, (EventCallback) address_changed, list);
+ g_mime_event_remove (old->priv, (GMimeEventCallback) address_changed, list);
g_object_unref (old);
- event_list_add (ia->priv, (EventCallback) address_changed, list);
+ g_mime_event_add (ia->priv, (GMimeEventCallback) address_changed, list);
list->array->pdata[index] = ia;
g_object_ref (ia);
- event_list_emit (list->priv, list);
+ g_mime_event_emit (list->priv, NULL);
}
@@ -1636,31 +1512,3 @@ internet_address_list_parse_string (const char *str)
return addrlist;
}
-
-
-void
-_internet_address_list_block_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
-{
- event_list_block (list->priv, callback, user_data);
-}
-
-
-void
-_internet_address_list_unblock_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
-{
- event_list_unblock (list->priv, callback, user_data);
-}
-
-
-void
-_internet_address_list_add_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
-{
- event_list_add (list->priv, callback, user_data);
-}
-
-
-void
-_internet_address_list_remove_event_handler (InternetAddressList *list, EventCallback callback, gpointer user_data)
-{
- event_list_remove (list->priv, callback, user_data);
-}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]