aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend/pas
diff options
context:
space:
mode:
authorNat Friedman <nat@src.gnome.org>2000-01-25 13:28:18 +0800
committerNat Friedman <nat@src.gnome.org>2000-01-25 13:28:18 +0800
commitfd4379ff20fe9c9e3b4f4028095b9659687002ff (patch)
tree78af76526262d746417a1e2007fd712f8d4ce584 /addressbook/backend/pas
parenta315f0321395423c3c52adb4bb3063c433948dd5 (diff)
downloadgsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar.gz
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar.bz2
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar.lz
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar.xz
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.tar.zst
gsoc2013-evolution-fd4379ff20fe9c9e3b4f4028095b9659687002ff.zip
More work.
svn path=/trunk/; revision=1626
Diffstat (limited to 'addressbook/backend/pas')
-rw-r--r--addressbook/backend/pas/Makefile.am29
-rw-r--r--addressbook/backend/pas/pas-backend-file.c272
-rw-r--r--addressbook/backend/pas/pas-backend-file.h32
-rw-r--r--addressbook/backend/pas/pas-backend.c96
-rw-r--r--addressbook/backend/pas/pas-backend.h41
-rw-r--r--addressbook/backend/pas/pas-book-factory.c248
-rw-r--r--addressbook/backend/pas/pas-book-factory.h7
-rw-r--r--addressbook/backend/pas/pas-book.c573
-rw-r--r--addressbook/backend/pas/pas-book.h84
-rw-r--r--addressbook/backend/pas/pas.c54
10 files changed, 1203 insertions, 233 deletions
diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am
index 220888f431..36eeab0782 100644
--- a/addressbook/backend/pas/Makefile.am
+++ b/addressbook/backend/pas/Makefile.am
@@ -1,3 +1,6 @@
+bin_PROGRAMS = wombat
+lib_LTLIBRARIES = libpas.la
+
corbadir = $(sysconfdir)/CORBA/servers
CORBA_SOURCE = \
@@ -34,16 +37,36 @@ pas_libs = \
libpas.la \
$(gnome_libs)
-lib_LTLIBRARIES = libpas.la
libpas_la_SOURCES = \
$(CORBA_SOURCE) \
- pas-book-factory.c
+ pas-book.c \
+ pas-book-factory.c \
+ pas-backend.c \
+ pas-backend-file.c
libpasincludedir = $(includedir)/backend
libpasinclude_HEADERS = \
- pas-book-factory.h
+ pas-book.h \
+ pas-book-factory.h \
+ pas-backend.h \
+ pas-backend-file.h
+
+wombat_SOURCES = \
+ pas.c
+
+wombat_LDADD = \
+ $(GTK_LIBS) \
+ $(GNOME_LIBDIR) \
+ $(GNOMEGNORBA_LIBS) \
+ $(INTLLIBS) \
+ -lbonobo \
+ $(pas_libs)
+
+gnorbadir = $(sysconfdir)/CORBA/servers
+gnorba_DATA = wombat.gnorba
BUILT_SOURCES = $(CORBA_SOURCE)
CLEANFILES += $(BUILT_SOURCES)
+EXTRA_DIST = $(gnorba_DATA) \ No newline at end of file
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
new file mode 100644
index 0000000000..f23b607efe
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -0,0 +1,272 @@
+/*
+ * Author:
+ * Nat Friedman (nat@helixcode.com)
+ *
+ * Copyright 2000, Helix Code, Inc.
+ */
+
+#include <gtk/gtksignal.h>
+#include <db.h>
+
+#include <pas-backend-file.h>
+#include <pas-book.h>
+
+static PASBackendClass *pas_backend_file_parent_class;
+
+struct _PASBackendFilePrivate {
+ GList *clients;
+ gboolean loaded;
+};
+
+static void
+pas_backend_file_process_create_card (PASBackend *backend,
+ PASBook *book,
+ PASRequest *req)
+{
+ pas_book_respond_create (
+ book, Evolution_BookListener_Success);
+
+ g_free (req->vcard);
+}
+
+static void
+pas_backend_file_process_remove_card (PASBackend *backend,
+ PASBook *book,
+ PASRequest *req)
+{
+ pas_book_respond_remove (
+ book, Evolution_BookListener_Success);
+
+ g_free (req->id);
+}
+
+static void
+pas_backend_file_process_modify_card (PASBackend *backend,
+ PASBook *book,
+ PASRequest *req)
+{
+ pas_book_respond_modify (
+ book, Evolution_BookListener_Success);
+
+ g_free (req->vcard);
+}
+
+static void
+pas_backend_file_process_check_connection (PASBackend *backend,
+ PASBook *book,
+ PASRequest *req)
+{
+ pas_book_report_connection (book, TRUE);
+}
+
+static void
+pas_backend_file_process_client_requests (PASBook *book)
+{
+ PASBackend *backend;
+ PASRequest *req;
+
+ backend = pas_book_get_backend (book);
+
+ req = pas_book_pop_request (book);
+ if (req == NULL)
+ return;
+
+ switch (req->op) {
+ case CreateCard:
+ pas_backend_file_process_create_card (backend, book, req);
+ break;
+
+ case RemoveCard:
+ pas_backend_file_process_remove_card (backend, book, req);
+ break;
+
+ case ModifyCard:
+ pas_backend_file_process_modify_card (backend, book, req);
+
+ case CheckConnection:
+ pas_backend_file_process_check_connection (backend, book, req);
+ break;
+ }
+
+ g_free (req);
+}
+
+static void
+pas_backend_file_book_destroy_cb (PASBook *book)
+{
+ PASBackendFile *backend;
+
+ backend = PAS_BACKEND_FILE (pas_book_get_backend (book));
+
+ pas_backend_remove_client (PAS_BACKEND (backend), book);
+}
+
+static char *
+pas_backend_file_get_vcard (PASBook *book, const char *id)
+{
+ return g_strdup ("blah blah blah");
+}
+
+static char *
+pas_backend_file_extract_path_from_uri (const char *uri)
+{
+ g_assert (strncasecmp (uri, "file:", 5) == 0);
+
+ return g_strdup (uri + 5);
+}
+
+static void
+pas_backend_file_load_uri (PASBackend *backend,
+ const char *uri)
+{
+ PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ char *filename;
+
+ g_assert (PAS_BACKEND_FILE (backend)->priv->loaded == FALSE);
+
+ filename = pas_backend_file_extract_path_from_uri (uri);
+}
+
+static void
+pas_backend_file_add_client (PASBackend *backend,
+ Evolution_BookListener listener)
+{
+ PASBackendFile *bf;
+ PASBook *book;
+
+ g_assert (backend != NULL);
+ g_assert (PAS_IS_BACKEND_FILE (backend));
+
+ bf = PAS_BACKEND_FILE (backend);
+
+ book = pas_book_new (
+ backend, listener,
+ pas_backend_file_get_vcard);
+
+ g_assert (book != NULL);
+
+ gtk_signal_connect (GTK_OBJECT (book), "destroy",
+ pas_backend_file_book_destroy_cb, NULL);
+
+ gtk_signal_connect (GTK_OBJECT (book), "requests_queued",
+ pas_backend_file_process_client_requests, NULL);
+
+ bf->priv->clients = g_list_prepend (
+ bf->priv->clients, book);
+
+ if (bf->priv->loaded) {
+ pas_book_respond_open (
+ book, Evolution_BookListener_Success);
+ } else {
+ /* Open the book. */
+ pas_book_respond_open (
+ book, Evolution_BookListener_Success);
+ }
+}
+
+static void
+pas_backend_file_remove_client (PASBackend *backend,
+ PASBook *book)
+{
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (book != NULL);
+ g_return_if_fail (PAS_IS_BOOK (book));
+
+ g_warning ("pas_backend_file_remove_client: Unimplemented!\n");
+}
+
+static gboolean
+pas_backend_file_construct (PASBackendFile *backend)
+{
+ g_assert (backend != NULL);
+ g_assert (PAS_IS_BACKEND_FILE (backend));
+
+ if (! pas_backend_construct (PAS_BACKEND (backend)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * pas_backend_file_new:
+ */
+PASBackend *
+pas_backend_file_new (void)
+{
+ PASBackendFile *backend;
+
+ backend = gtk_type_new (pas_backend_file_get_type ());
+
+ if (! pas_backend_file_construct (backend)) {
+ gtk_object_unref (GTK_OBJECT (backend));
+
+ return NULL;
+ }
+
+ return PAS_BACKEND (backend);
+}
+
+static void
+pas_backend_file_destroy (GtkObject *object)
+{
+ PASBackendFile *backend = PAS_BACKEND_FILE (object);
+
+ GTK_OBJECT_CLASS (pas_backend_file_parent_class)->destroy (object);
+}
+
+static void
+pas_backend_file_class_init (PASBackendFileClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+ PASBackendClass *parent_class;
+
+ pas_backend_file_parent_class = gtk_type_class (pas_backend_get_type ());
+
+ parent_class = PAS_BACKEND_CLASS (klass);
+
+ /* Set the virtual methods. */
+ parent_class->load_uri = pas_backend_file_load_uri;
+ parent_class->add_client = pas_backend_file_add_client;
+ parent_class->remove_client = pas_backend_file_remove_client;
+
+ object_class->destroy = pas_backend_file_destroy;
+}
+
+static void
+pas_backend_file_init (PASBackendFile *backend)
+{
+ PASBackendFilePrivate *priv;
+
+ priv = g_new0 (PASBackendFilePrivate, 1);
+ priv->loaded = FALSE;
+ priv->clients = NULL;
+
+ backend->priv = priv;
+}
+
+/**
+ * pas_backend_file_get_type:
+ */
+GtkType
+pas_backend_file_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (! type) {
+ GtkTypeInfo info = {
+ "PASBackendFile",
+ sizeof (PASBackendFile),
+ sizeof (PASBackendFileClass),
+ (GtkClassInitFunc) pas_backend_file_class_init,
+ (GtkObjectInitFunc) pas_backend_file_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (pas_backend_get_type (), &info);
+ }
+
+ return type;
+}
diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h
new file mode 100644
index 0000000000..a56626014b
--- /dev/null
+++ b/addressbook/backend/pas/pas-backend-file.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000, Helix Code, Inc.
+ */
+
+#ifndef __PAS_BACKEND_FILE_H__
+#define __PAS_BACKEND_FILE_H__
+
+#include <libgnome/gnome-defs.h>
+#include <pas-backend.h>
+
+typedef struct _PASBackendFilePrivate PASBackendFilePrivate;
+
+typedef struct {
+ PASBackend parent_object;
+ PASBackendFilePrivate *priv;
+} PASBackendFile;
+
+typedef struct {
+ PASBackendClass parent_class;
+} PASBackendFileClass;
+
+PASBackend *pas_backend_file_new (void);
+GtkType pas_backend_file_get_type (void);
+
+#define PAS_BACKEND_FILE_TYPE (pas_backend_file_get_type ())
+#define PAS_BACKEND_FILE(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_FILE_TYPE, PASBackendFile))
+#define PAS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendFileClass))
+#define PAS_IS_BACKEND_FILE(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_FILE_TYPE))
+#define PAS_IS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_FILE_TYPE))
+
+#endif /* ! __PAS_BACKEND_FILE_H__ */
+
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index 291b101ce6..364204c3c2 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -1,37 +1,32 @@
/*
+ * Author:
+ * Nat Friedman (nat@helixcode.com)
+ *
* Copyright 2000, Helix Code, Inc.
*/
#include <gtk/gtkobject.h>
#include <pas-backend.h>
-typedef struct {
- Evolution_BookListener listener;
-} PASClient;
+#define CLASS(o) PAS_BACKEND_CLASS (GTK_OBJECT (o)->klass)
-struct _PASBackendPrivate {
- gboolean book_loaded;
- GList *clients;
- GList *response_queue;
-};
-
-PASBackend *
-pas_backend_new (void)
+gboolean
+pas_backend_construct (PASBackend *backend)
{
- PASBackend *backend;
-
- backend = gtk_type_new (pas_backend_get_type ());
-
- return backend;
+ return TRUE;
}
void
pas_backend_load_uri (PASBackend *backend,
- char *uri)
+ const char *uri)
{
g_return_if_fail (backend != NULL);
g_return_if_fail (PAS_IS_BACKEND (backend));
g_return_if_fail (uri != NULL);
+
+ g_assert (CLASS (backend)->load_uri != NULL);
+
+ CLASS (backend)->load_uri (backend, uri);
}
/**
@@ -43,77 +38,32 @@ void
pas_backend_add_client (PASBackend *backend,
Evolution_BookListener listener)
{
- PASClient *client;
-
g_return_if_fail (backend != NULL);
g_return_if_fail (PAS_IS_BACKEND (backend));
g_return_if_fail (listener != CORBA_OBJECT_NIL);
- client = g_new0 (PASClient, 1);
-
- client->listener = listener;
-
- if (backend->priv->book_loaded) {
-
- }
-}
-
-
-void
-pas_backend_remove_client (PASBackend *backend,
- Evolution_BookListener listener)
-{
-}
-
-/* Synchronous operations. */
-char *
-pas_backend_get_vcard (PASBackend *backend,
- PASBook *book,
- char *id)
-{
-}
-
-/* Asynchronous operations. */
+ g_assert (CLASS (backend)->add_client != NULL);
-/**
- * pas_backend_queue_remove_card:
- */
-void
-pas_backend_queue_create_card (PASBackend *backend,
- PASBook *book,
- char *vcard)
-{
+ CLASS (backend)->add_client (backend, listener);
}
-/**
- * pas_backend_queue_remove_card:
- */
void
-pas_backend_queue_remove_card (PASBackend *backend,
- PASBook *book,
- char *id)
+pas_backend_remove_client (PASBackend *backend,
+ PASBook *book)
{
-}
+ g_return_if_fail (backend != NULL);
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (book != NULL);
+ g_return_if_fail (PAS_IS_BOOK (book));
+
+ g_assert (CLASS (backend)->remove_client != NULL);
-/**
- * pas_backend_queue_modify_card:
- */
-void
-pas_backend_queue_modify_card (PASBackend *backend,
- PASBook *book,
- char *id,
- char *vcard)
-{
+ CLASS (backend)->remove_client (backend, book);
}
static void
pas_backend_init (PASBackend *backend)
{
- PASBackendPrivate *priv;
-
- priv = g_new0 (PASBackendPrivate, 1);
- priv->book_loaded = FALSE;
- priv->clients = NULL;
}
static void
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index fca4ef7d8d..62822619ac 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -21,41 +21,38 @@
#ifndef __PAS_BACKEND_H__
#define __PAS_BACKEND_H__
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkobject.h>
+#include <addressbook.h>
+
+typedef struct _PASBackend PASBackend;
typedef struct _PASBackendPrivate PASBackendPrivate;
-typedef struct {
+#include <pas-book.h>
+
+struct _PASBackend {
GtkObject parent_object;
PASBackendPrivate *priv;
-} PASBackend;
+};
typedef struct {
GtkObjectClass parent_class;
+
+ /* Virtual methods */
+ void (*load_uri) (PASBackend *backend, const char *uri);
+ void (*add_client) (PASBackend *backend, Evolution_BookListener listener);
+ void (*remove_client) (PASBackend *backend, PASBook *book);
} PASBackendClass;
-PASBackend *pas_backend_new (void);
+typedef PASBackend * (*PASBackendFactoryFn) (void);
+
+gboolean pas_backend_construct (PASBackend *backend);
void pas_backend_load_uri (PASBackend *backend,
- char *uri);
+ const char *uri);
void pas_backend_add_client (PASBackend *backend,
Evolution_BookListener listener);
void pas_backend_remove_client (PASBackend *backend,
- Evolution_BookListener listener);
-
-/* Synchronous operations. */
-char *pas_backend_get_vcard (PASBackend *backend,
- PASBook *book,
- char *id);
-
-/* Asynchronous operations. */
-void pas_backend_queue_create_card (PASBackend *backend,
- PASBook *book,
- char *vcard);
-void pas_backend_queue_remove_card (PASBackend *backend,
- PASBook *book,
- char *id);
-void pas_backend_queue_modify_card (PASBackend *backend,
- PASBook *book,
- char *id,
- char *vcard);
+ PASBook *book);
GtkType pas_backend_get_type (void);
diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c
index 55b67f4e7e..6f01ed8053 100644
--- a/addressbook/backend/pas/pas-book-factory.c
+++ b/addressbook/backend/pas/pas-book-factory.c
@@ -6,43 +6,34 @@
* Copyright 2000, Helix Code, Inc.
*/
+#include <ctype.h>
+#include <libgnorba/gnorba.h>
#include <addressbook.h>
#include <pas-book-factory.h>
+#define PAS_BOOK_FACTORY_GOAD_ID "evolution:card-server"
+
static GnomeObjectClass *pas_book_factory_parent_class;
POA_Evolution_BookFactory__vepv pas_book_factory_vepv;
typedef struct {
- Evolution_BookListener listener;
- Evolution_BookListener_CallStatus status;
-} PASBookFactoryQueuedResponse;
-
-typedef struct {
char *uri;
Evolution_BookListener listener;
} PASBookFactoryQueuedRequest;
struct _PASBookFactoryPrivate {
+ gint idle_id;
GHashTable *backends;
GHashTable *active_server_map;
- GList *queued_responses;
GList *queued_requests;
};
static char *
pas_book_factory_canonicalize_uri (const char *uri)
{
- char *canon;
- char *p;
-
/* FIXME: What do I do here? */
- canon = g_strdup (uri);
-
- for (p = canon; *p != '\0'; p ++)
- *p = toupper (*p);
-
- return canon;
+ return g_strdup (uri);
}
static char *
@@ -70,15 +61,17 @@ pas_book_factory_extract_proto_from_uri (const char *uri)
* @backend:
*/
void
-pas_book_factory_register_backend (PASBookFactory *factory,
- const char *proto,
- PASBookFactoryBackendFactory backend)
+pas_book_factory_register_backend (PASBookFactory *factory,
+ const char *proto,
+ PASBackendFactoryFn backend)
{
g_return_if_fail (factory != NULL);
g_return_if_fail (PAS_IS_BOOK_FACTORY (factory));
g_return_if_fail (proto != NULL);
g_return_if_fail (backend != NULL);
+
+
if (g_hash_table_lookup (factory->priv->backends, proto) != NULL) {
g_warning ("pas_book_factory_register_backend: "
"Proto \"%s\" already registered!\n", proto);
@@ -88,13 +81,13 @@ pas_book_factory_register_backend (PASBookFactory *factory,
g_strdup (proto), backend);
}
-static PASBookFactoryBackendFactory
+static PASBackendFactoryFn
pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
const char *uri)
{
- PASBookFactoryBackendFactory backend;
- char *proto;
- char *canonical_uri;
+ PASBackendFactoryFn backend;
+ char *proto;
+ char *canonical_uri;
g_assert (factory != NULL);
g_assert (PAS_IS_BOOK_FACTORY (factory));
@@ -118,64 +111,61 @@ pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
return backend;
}
-static void
-pas_book_factory_process_request (PASBookFactory *factory,
- PASBookFactoryQueuedRequest *request)
+static PASBackend *
+pas_book_factory_launch_backend (PASBookFactory *factory,
+ PASBookFactoryQueuedRequest *request)
{
- request = factory->priv->queued_requests->data;
+ PASBackendFactoryFn backend_factory;
+ PASBackend *backend;
- /*
- * Check to see if there is already a running backend for this
- * URI.
- */
-
-
- backend = pas_book_factory_lookup_backend_factory (
+ backend_factory = pas_book_factory_lookup_backend_factory (
factory, request->uri);
+ g_assert (backend_factory != NULL);
+
+ backend = (backend_factory) ();
g_assert (backend != NULL);
- (backend) (factory, request->uri, request->listener);
-}
+ g_hash_table_insert (factory->priv->active_server_map,
+ g_strdup (request->uri),
+ backend);
+ return backend;
+}
static void
-pas_book_factory_process_response (PASBookFactory *factory,
- PASBookFactoryQueuedResponse *response)
+pas_book_factory_process_request (PASBookFactory *factory,
+ PASBookFactoryQueuedRequest *request)
{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
+ PASBackend *backend;
- Evolution_BookListener_respond_open_book (
- response->listener, response->status,
- CORBA_OBJECT_NIL, &ev);
+ request = factory->priv->queued_requests->data;
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("PASBookFactory: Exception while sending "
- "response to BookListener!\n");
+ backend = g_hash_table_lookup (factory->priv->active_server_map, request->uri);
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
- }
+ if (backend == NULL) {
- CORBA_Object_release (response->listener, &ev);
+ backend = pas_book_factory_launch_backend (factory, request);
+ pas_backend_add_client (backend, request->listener);
+ pas_backend_load_uri (backend, request->uri);
+ g_free (request->uri);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("PASBookFactory: Exception releasing "
- "BookListener!\n");
+ return;
}
- CORBA_exception_free (&ev);
-}
+ g_free (request->uri);
+ pas_backend_add_client (backend, request->listener);
+}
static gboolean
-pas_book_factory_process_queues (PASBookFactory *factory)
+pas_book_factory_process_queue (PASBookFactory *factory)
{
/* Process pending Book-creation requests. */
- while (factory->priv->queued_requests != NULL) {
+ if (factory->priv->queued_requests != NULL) {
PASBookFactoryQueuedRequest *request;
+ request = factory->priv->queued_requests->data;
+
pas_book_factory_process_request (factory, request);
factory->priv->queued_requests = g_list_remove (
@@ -184,52 +174,16 @@ pas_book_factory_process_queues (PASBookFactory *factory)
g_free (request);
}
- /* Flush the outgoing error queue. */
- while (factory->priv->queued_responses != NULL) {
- PASBookFactoryQueuedResponse *response;
-
- response = factory->priv->queued_responses->data;
-
- pas_book_factory_process_response (factory, response);
- factory->priv->queued_responses = g_list_remove (
- factory->priv->queued_responses, response);
+ if (factory->priv->queued_requests == NULL) {
- g_free (response);
+ factory->priv->idle_id = 0;
+ return FALSE;
}
return TRUE;
}
static void
-pas_book_factory_queue_response (PASBookFactory *factory,
- const Evolution_BookListener listener,
- Evolution_BookListener_CallStatus status)
-{
- PASBookFactoryQueuedResponse *response;
- Evolution_BookListener listener_copy;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- listener_copy = CORBA_Object_duplicate (listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("PASBookFactory: Could not duplicate BookListener!\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-
- response = g_new0 (PASBookFactoryQueuedResponse, 1);
- response->listener = listener_copy;
- response->status = status;
-
- factory->priv->queued_responses =
- g_list_prepend (factory->priv->queued_responses, response);
-}
-
-static void
pas_book_factory_queue_request (PASBookFactory *factory,
const char *uri,
const Evolution_BookListener listener)
@@ -256,27 +210,32 @@ pas_book_factory_queue_request (PASBookFactory *factory,
factory->priv->queued_requests =
g_list_prepend (factory->priv->queued_requests, request);
+
+ if (! factory->priv->idle_id) {
+ factory->priv->idle_id =
+ g_idle_add ((GSourceFunc) pas_book_factory_process_queue, factory);
+ }
}
+
static void
impl_Evolution_BookFactory_open_book (PortableServer_Servant servant,
const CORBA_char *uri,
const Evolution_BookListener listener,
CORBA_Environment *ev)
{
- PASBookFactory *factory =
+ PASBookFactory *factory =
PAS_BOOK_FACTORY (gnome_object_from_servant (servant));
+ PASBackendFactoryFn backend_factory;
- PASBookFactoryBackendFactory backend;
-
- backend = pas_book_factory_lookup_backend_factory (factory, uri);
+ backend_factory = pas_book_factory_lookup_backend_factory (factory, uri);
- if (backend == NULL) {
+ if (backend_factory == NULL) {
g_warning ("PASBookFactory: No backend found for uri: %s\n", uri);
- pas_book_factory_queue_response (
- factory, listener,
- Evolution_BookListener_ProtocolNotSupported);
+ CORBA_exception_set (
+ ev, CORBA_USER_EXCEPTION,
+ ex_Evolution_BookFactory_ProtocolNotSupported, NULL);
return;
}
@@ -284,7 +243,7 @@ impl_Evolution_BookFactory_open_book (PortableServer_Servant servant,
pas_book_factory_queue_request (factory, uri, listener);
}
-static PASBookFactory *
+static gboolean
pas_book_factory_construct (PASBookFactory *factory)
{
POA_Evolution_BookFactory *servant;
@@ -304,7 +263,7 @@ pas_book_factory_construct (PASBookFactory *factory)
g_free (servant);
CORBA_exception_free (&ev);
- return NULL;
+ return FALSE;
}
CORBA_exception_free (&ev);
@@ -313,12 +272,12 @@ pas_book_factory_construct (PASBookFactory *factory)
if (obj == CORBA_OBJECT_NIL) {
g_free (servant);
- return NULL;
+ return FALSE;
}
gnome_object_construct (GNOME_OBJECT (factory), obj);
- return factory;
+ return TRUE;
}
/**
@@ -328,22 +287,65 @@ PASBookFactory *
pas_book_factory_new (void)
{
PASBookFactory *factory;
- PASBookFactory *retval;
- factory = gtk_type_new (PAS_BOOK_FACTORY_TYPE);
+ factory = gtk_type_new (pas_book_factory_get_type ());
- retval = pas_book_factory_construct (factory);
-
- if (retval == NULL) {
- g_warning ("pas_book_factoy_new: Could not construct PASBookFactory!\n");
+ if (! pas_book_factory_construct (factory)) {
+ g_warning ("pas_book_factory_new: Could not construct PASBookFactory!\n");
gtk_object_unref (GTK_OBJECT (factory));
return NULL;
}
- return retval;
+ return factory;
+}
+
+/**
+ * pas_book_factory_activate:
+ */
+void
+pas_book_factory_activate (PASBookFactory *factory)
+{
+ CORBA_Environment ev;
+ int ret;
+
+ g_return_if_fail (factory != NULL);
+ g_return_if_fail (PAS_IS_BOOK_FACTORY (factory));
+
+ CORBA_exception_init (&ev);
+
+ ret = goad_server_register (
+ NULL,
+ gnome_object_corba_objref (GNOME_OBJECT (factory)),
+ PAS_BOOK_FACTORY_GOAD_ID, "server",
+ &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_message ("pas_book_factory_construct: Exception "
+ "registering PASBookFactory!\n");
+ CORBA_exception_free (&ev);
+ return;
+ }
+
+ CORBA_exception_free (&ev);
+
+ if (ret == -1) {
+ g_message ("pas_book_factory_construct: Error "
+ "registering PASBookFactory!\n");
+ return;
+ }
+
+ if (ret == -2) {
+ g_message ("pas_book_factory_construct: Another "
+ "PASBookFactory is already running.\n");
+ return;
+
+ }
+
+ return;
}
+
static void
pas_book_factory_init (PASBookFactory *factory)
{
@@ -352,9 +354,6 @@ pas_book_factory_init (PASBookFactory *factory)
factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal);
factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal);
factory->priv->queued_requests = NULL;
- factory->priv->queued_responses = NULL;
-
- g_idle_add ((GSourceFunc) pas_book_factory_process_queues, factory);
}
static gboolean
@@ -401,19 +400,6 @@ pas_book_factory_destroy (GtkObject *object)
g_list_free (factory->priv->queued_requests);
factory->priv->queued_requests = NULL;
- for (l = factory->priv->queued_responses; l != NULL; l = l->next) {
- PASBookFactoryQueuedResponse *response = l->data;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (response->listener, &ev);
- CORBA_exception_free (&ev);
-
- g_free (response);
- }
- g_list_free (factory->priv->queued_responses);
- factory->priv->queued_responses = NULL;
-
g_hash_table_foreach_remove (factory->priv->active_server_map,
pas_book_factory_remove_asm_entry,
NULL);
diff --git a/addressbook/backend/pas/pas-book-factory.h b/addressbook/backend/pas/pas-book-factory.h
index f10444e48c..6e72b90062 100644
--- a/addressbook/backend/pas/pas-book-factory.h
+++ b/addressbook/backend/pas/pas-book-factory.h
@@ -5,6 +5,8 @@
#include <bonobo/gnome-object.h>
#include <libgnome/gnome-defs.h>
+#include <pas-backend.h>
+
#ifndef __PAS_BOOK_FACTORY_H__
#define __PAS_BOOK_FACTORY_H__
@@ -21,14 +23,11 @@ typedef struct {
GnomeObjectClass parent_class;
} PASBookFactoryClass;
-typedef void (*PASBookFactoryBackendFactory) (
- PASBookFactory *factory, char *uri, Evolution_BookListener listener);
-
PASBookFactory *pas_book_factory_new (void);
void pas_book_factory_register_backend (PASBookFactory *factory,
const char *proto,
- PASBookFactoryBackendFactory backend);
+ PASBackendFactoryFn backend_factory);
void pas_book_factory_activate (PASBookFactory *factory);
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
new file mode 100644
index 0000000000..adac2fd806
--- /dev/null
+++ b/addressbook/backend/pas/pas-book.c
@@ -0,0 +1,573 @@
+/*
+ * pas-book.c
+ *
+ * Copyright 2000, Helix Code, Inc.
+ */
+
+#include <gtk/gtksignal.h>
+#include <pas-book.h>
+
+static GnomeObjectClass *pas_book_parent_class;
+POA_Evolution_Book__vepv pas_book_vepv;
+
+enum {
+ REQUESTS_QUEUED,
+ LAST_SIGNAL
+};
+
+static guint pas_book_signals [LAST_SIGNAL];
+
+struct _PASBookPrivate {
+ PASBackend *backend;
+ Evolution_BookListener listener;
+ PASBookGetVCardFn get_vcard;
+
+ GList *request_queue;
+ gint idle_id;
+};
+
+static gboolean
+pas_book_check_queue (PASBook *book)
+{
+ if (book->priv->request_queue != NULL) {
+ gtk_signal_emit (GTK_OBJECT (book),
+ pas_book_signals [REQUESTS_QUEUED]);
+ }
+
+ if (book->priv->request_queue == NULL) {
+ book->priv->idle_id = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+pas_book_queue_request (PASBook *book, PASRequest *req)
+{
+ book->priv->request_queue =
+ g_list_append (book->priv->request_queue, req);
+
+ if (book->priv->idle_id == 0) {
+ book->priv->idle_id = g_idle_add ((GSourceFunc) pas_book_check_queue, book);
+ }
+}
+
+static void
+pas_book_queue_create_card (PASBook *book, const char *vcard)
+{
+ PASRequest *req;
+
+ req = g_new0 (PASRequest, 1);
+ req->op = CreateCard;
+ req->vcard = g_strdup (vcard);
+
+ pas_book_queue_request (book, req);
+}
+
+static void
+pas_book_queue_remove_card (PASBook *book, const char *id)
+{
+ PASRequest *req;
+
+ req = g_new0 (PASRequest, 1);
+ req->op = RemoveCard;
+ req->id = g_strdup (id);
+
+ pas_book_queue_request (book, req);
+}
+
+static void
+pas_book_queue_modify_card (PASBook *book, const char *vcard)
+{
+ PASRequest *req;
+
+ req = g_new0 (PASRequest, 1);
+ req->op = ModifyCard;
+ req->vcard = g_strdup (vcard);
+
+ pas_book_queue_request (book, req);
+}
+
+static void
+pas_book_queue_check_connection (PASBook *book)
+{
+ PASRequest *req;
+
+ req = g_new0 (PASRequest, 1);
+ req->op = CheckConnection;
+
+ pas_book_queue_request (book, req);
+}
+
+static CORBA_char *
+impl_Evolution_Book_get_vcard (PortableServer_Servant servant,
+ const Evolution_CardId id,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (gnome_object_from_servant (servant));
+ char *vcard;
+ CORBA_char *retval;
+
+ vcard = (book->priv->get_vcard) (book, (const char *) id);
+ retval = CORBA_string_dup (vcard);
+ g_free (vcard);
+
+ return retval;
+}
+
+static void
+impl_Evolution_Book_create_card (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (gnome_object_from_servant (servant));
+
+ pas_book_queue_create_card (book, vcard);
+}
+
+static void
+impl_Evolution_Book_remove_card (PortableServer_Servant servant,
+ const Evolution_CardId id,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (gnome_object_from_servant (servant));
+
+ pas_book_queue_remove_card (book, (const char *) id);
+}
+
+static void
+impl_Evolution_Book_modify_card (PortableServer_Servant servant,
+ const CORBA_char *vcard,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (gnome_object_from_servant (servant));
+
+ pas_book_queue_modify_card (book, vcard);
+}
+
+static void
+impl_Evolution_Book_check_connection (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBook *book = PAS_BOOK (gnome_object_from_servant (servant));
+
+ pas_book_queue_check_connection (book);
+}
+
+/**
+ * pas_book_get_backend:
+ */
+PASBackend *
+pas_book_get_backend (PASBook *book)
+{
+ g_return_val_if_fail (book != NULL, NULL);
+ g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
+
+ return book->priv->backend;
+}
+
+/**
+ * pas_book_get_listener:
+ */
+Evolution_BookListener
+pas_book_get_listener (PASBook *book)
+{
+ g_return_val_if_fail (book != NULL, CORBA_OBJECT_NIL);
+ g_return_val_if_fail (PAS_IS_BOOK (book), CORBA_OBJECT_NIL);
+
+ return book->priv->listener;
+}
+
+/**
+ * pas_book_check_pending
+ */
+gint
+pas_book_check_pending (PASBook *book)
+{
+ g_return_val_if_fail (book != NULL, -1);
+ g_return_val_if_fail (PAS_IS_BOOK (book), -1);
+
+ return g_list_length (book->priv->request_queue);
+}
+
+/**
+ * pas_book_pop_request:
+ */
+PASRequest *
+pas_book_pop_request (PASBook *book)
+{
+ GList *popped;
+ PASRequest *req;
+
+ g_return_val_if_fail (book != NULL, NULL);
+ g_return_val_if_fail (PAS_IS_BOOK (book), NULL);
+
+ if (book->priv->request_queue == NULL)
+ return NULL;
+
+ req = book->priv->request_queue->data;
+
+ popped = book->priv->request_queue;
+ book->priv->request_queue =
+ g_list_remove_link (book->priv->request_queue, popped);
+
+ g_list_free_1 (popped);
+
+ return req;
+}
+
+/**
+ * pas_book_respond_open:
+ */
+void
+pas_book_respond_open (PASBook *book,
+ Evolution_BookListener_CallStatus status)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ if (status == Evolution_BookListener_Success) {
+ Evolution_BookListener_respond_open_book (
+ book->priv->listener, status,
+ gnome_object_corba_objref (GNOME_OBJECT (book)),
+ &ev);
+ } else {
+ Evolution_BookListener_respond_open_book (
+ book->priv->listener, status,
+ CORBA_OBJECT_NIL, &ev);
+ }
+
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_open: Exception "
+ "responding to BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_respond_create:
+ */
+void
+pas_book_respond_create (PASBook *book,
+ Evolution_BookListener_CallStatus status)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_respond_create_card (
+ book->priv->listener, status, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_create: Exception "
+ "responding to BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_respond_remove:
+ */
+void
+pas_book_respond_remove (PASBook *book,
+ Evolution_BookListener_CallStatus status)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_respond_remove_card (
+ book->priv->listener, status, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_remove: Exception "
+ "responding to BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_respond_modify:
+ */
+void
+pas_book_respond_modify (PASBook *book,
+ Evolution_BookListener_CallStatus status)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_respond_modify_card (
+ book->priv->listener, status, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_respond_modify: Exception "
+ "responding to BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_report_connection:
+ */
+void
+pas_book_report_connection (PASBook *book,
+ gboolean connected)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_report_connection_status (
+ book->priv->listener, (CORBA_boolean) connected, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_report_connection: Exception "
+ "responding to BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+
+/**
+ * pas_book_notify_change:
+ */
+void
+pas_book_notify_change (PASBook *book,
+ const char *id)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_signal_card_changed (
+ book->priv->listener, (Evolution_CardId) id, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_notify_change: Exception signaling BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_notify_remove:
+ */
+void
+pas_book_notify_remove (PASBook *book,
+ const char *id)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_signal_card_removed (
+ book->priv->listener, (Evolution_CardId) id, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_notify_remove: Exception signaling BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+/**
+ * pas_book_notify_add:
+ */
+void
+pas_book_notify_add (PASBook *book,
+ const char *id)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ Evolution_BookListener_signal_card_added (
+ book->priv->listener, (Evolution_CardId) id, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("pas_book_notify_add: Exception signaling BookListener!\n");
+ }
+
+ CORBA_exception_free (&ev);
+}
+
+static gboolean
+pas_book_construct (PASBook *book,
+ PASBackend *backend,
+ Evolution_BookListener listener,
+ PASBookGetVCardFn get_vcard)
+{
+ POA_Evolution_Book *servant;
+ CORBA_Environment ev;
+ CORBA_Object obj;
+
+ g_assert (book != NULL);
+ g_assert (PAS_IS_BOOK (book));
+ g_assert (listener != CORBA_OBJECT_NIL);
+ g_assert (get_vcard != NULL);
+
+ servant = (POA_Evolution_Book *) g_new0 (GnomeObjectServant, 1);
+ servant->vepv = &pas_book_vepv;
+
+ CORBA_exception_init (&ev);
+
+ POA_Evolution_Book__init ((PortableServer_Servant) servant, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_free (servant);
+ CORBA_exception_free (&ev);
+
+ return FALSE;
+ }
+
+ CORBA_exception_free (&ev);
+
+ obj = gnome_object_activate_servant (GNOME_OBJECT (book), servant);
+ if (obj == CORBA_OBJECT_NIL) {
+ g_free (servant);
+
+ return FALSE;
+ }
+
+ gnome_object_construct (GNOME_OBJECT (book), obj);
+
+ book->priv->listener = listener;
+ book->priv->get_vcard = get_vcard;
+ book->priv->backend = backend;
+
+ return TRUE;
+}
+
+/**
+ * pas_book_new:
+ */
+PASBook *
+pas_book_new (PASBackend *backend,
+ Evolution_BookListener listener,
+ PASBookGetVCardFn get_vcard)
+{
+ PASBook *book;
+ PASBook *retval;
+
+ g_return_val_if_fail (listener != CORBA_OBJECT_NIL, NULL);
+ g_return_val_if_fail (get_vcard != NULL, NULL);
+
+ book = gtk_type_new (pas_book_get_type ());
+
+ if (! pas_book_construct (book, backend, listener, get_vcard)) {
+ gtk_object_unref (GTK_OBJECT (book));
+
+ return NULL;
+ }
+
+ return book;
+}
+
+static void
+pas_book_destroy (GtkObject *object)
+{
+ PASBook *book = PAS_BOOK (object);
+ GList *l;
+
+ for (l = book->priv->request_queue; l != NULL; l = l->next) {
+ PASRequest *req = l->data;
+
+ g_free (req->id);
+ g_free (req->vcard);
+ g_free (req);
+ }
+ g_list_free (book->priv->request_queue);
+
+ g_free (book->priv);
+
+ GTK_OBJECT_CLASS (pas_book_parent_class)->destroy (object);
+}
+
+static POA_Evolution_Book__epv *
+pas_book_get_epv (void)
+{
+ POA_Evolution_Book__epv *epv;
+
+ epv = g_new0 (POA_Evolution_Book__epv, 1);
+
+ epv->get_vcard = impl_Evolution_Book_get_vcard;
+ epv->create_card = impl_Evolution_Book_create_card;
+ epv->remove_card = impl_Evolution_Book_remove_card;
+ epv->modify_card = impl_Evolution_Book_modify_card;
+ epv->check_connection = impl_Evolution_Book_check_connection;
+
+ return epv;
+
+}
+
+static void
+pas_book_corba_class_init (void)
+{
+ pas_book_vepv.GNOME_Unknown_epv = gnome_object_get_epv ();
+ pas_book_vepv.Evolution_Book_epv = pas_book_get_epv ();
+}
+
+static void
+pas_book_class_init (PASBookClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+
+ pas_book_parent_class = gtk_type_class (gnome_object_get_type ());
+
+ pas_book_signals [REQUESTS_QUEUED] =
+ gtk_signal_new ("requests_queued",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (PASBookClass, requests_queued),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, pas_book_signals, LAST_SIGNAL);
+
+ object_class->destroy = pas_book_destroy;
+
+ pas_book_corba_class_init ();
+}
+
+static void
+pas_book_init (PASBook *book)
+{
+ book->priv = g_new0 (PASBookPrivate, 1);
+ book->priv->idle_id = 0;
+ book->priv->request_queue = NULL;
+}
+
+/**
+ * pas_book_get_type:
+ */
+GtkType
+pas_book_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (! type) {
+ GtkTypeInfo info = {
+ "PASBook",
+ sizeof (PASBook),
+ sizeof (PASBookClass),
+ (GtkClassInitFunc) pas_book_class_init,
+ (GtkObjectInitFunc) pas_book_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (gnome_object_get_type (), &info);
+ }
+
+ return type;
+}
+
diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h
new file mode 100644
index 0000000000..e929916ceb
--- /dev/null
+++ b/addressbook/backend/pas/pas-book.h
@@ -0,0 +1,84 @@
+/*
+ * A wrapper object which exports the Evolution_Book CORBA interface
+ * and which maintains a request queue.
+ *
+ * Author:
+ * Nat Friedman (nat@helixcode.com)
+ *
+ * Copyright 2000, Helix Code, Inc.
+ */
+
+#ifndef __PAS_BOOK_H__
+#define __PAS_BOOK_H__
+
+#include <bonobo/gnome-object.h>
+#include <libgnome/gnome-defs.h>
+#include <addressbook.h>
+
+typedef struct _PASBook PASBook;
+typedef struct _PASBookPrivate PASBookPrivate;
+
+#include <pas-backend.h>
+
+typedef enum {
+ CreateCard,
+ RemoveCard,
+ ModifyCard,
+ CheckConnection
+} PASOperation;
+
+typedef struct {
+ PASOperation op;
+ char *id;
+ char *vcard;
+} PASRequest;
+
+struct _PASBook {
+ GnomeObject parent_object;
+ PASBookPrivate *priv;
+};
+
+typedef struct {
+ GnomeObjectClass parent_class;
+
+ /* Signals */
+ void (*requests_queued) (void);
+} PASBookClass;
+
+typedef char * (*PASBookGetVCardFn) (PASBook *book, const char *id);
+
+PASBook *pas_book_new (PASBackend *backend,
+ Evolution_BookListener listener,
+ PASBookGetVCardFn get_vcard);
+PASBackend *pas_book_get_backend (PASBook *book);
+Evolution_BookListener pas_book_get_listener (PASBook *book);
+int pas_book_check_pending (PASBook *book);
+PASRequest *pas_book_pop_request (PASBook *book);
+
+void pas_book_respond_open (PASBook *book,
+ Evolution_BookListener_CallStatus status);
+void pas_book_respond_create (PASBook *book,
+ Evolution_BookListener_CallStatus status);
+void pas_book_respond_remove (PASBook *book,
+ Evolution_BookListener_CallStatus status);
+void pas_book_respond_modify (PASBook *book,
+ Evolution_BookListener_CallStatus status);
+void pas_book_report_connection (PASBook *book,
+ gboolean connected);
+
+void pas_book_notify_change (PASBook *book,
+ const char *id);
+void pas_book_notify_remove (PASBook *book,
+ const char *id);
+void pas_book_notify_add (PASBook *book,
+ const char *id);
+
+GtkType pas_book_get_type (void);
+
+#define PAS_BOOK_TYPE (pas_book_get_type ())
+#define PAS_BOOK(o) (GTK_CHECK_CAST ((o), PAS_BOOK_TYPE, PASBook))
+#define PAS_BOOK_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookClass))
+#define PAS_IS_BOOK(o) (GTK_CHECK_TYPE ((o), PAS_BOOK_TYPE))
+#define PAS_IS_BOOK_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BOOK_TYPE))
+
+#endif /* ! __PAS_BOOK_H__ */
diff --git a/addressbook/backend/pas/pas.c b/addressbook/backend/pas/pas.c
new file mode 100644
index 0000000000..07d6d5c757
--- /dev/null
+++ b/addressbook/backend/pas/pas.c
@@ -0,0 +1,54 @@
+/*
+ * Author:
+ * Nat Friedman (nat@helixcode.com)
+ *
+ * Copyright 2000, Helix Code, Inc.
+ */
+#include <config.h>
+#include <bonobo/gnome-bonobo.h>
+
+#include <pas-book-factory.h>
+#include <pas-backend-file.h>
+
+CORBA_Environment ev;
+CORBA_ORB orb;
+
+static void
+init_bonobo (int argc, char **argv)
+{
+
+ gnome_CORBA_init_with_popt_table (
+ "Personal Addressbook Server", "0.0",
+ &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
+
+ orb = gnome_CORBA_ORB ();
+
+ if (bonobo_init (orb, NULL, NULL) == FALSE)
+ g_error (_("Could not initialize Bonobo"));
+}
+
+int
+main (int argc, char **argv)
+{
+ PASBookFactory *factory;
+
+ CORBA_exception_init (&ev);
+
+
+ init_bonobo (argc, argv);
+
+ /*
+ * Create the factory and register the local-file backend with
+ * it.
+ */
+ factory = pas_book_factory_new ();
+
+ pas_book_factory_register_backend (
+ factory, "file", pas_backend_file_new);
+
+ pas_book_factory_activate (factory);
+
+ bonobo_main ();
+
+ return 0;
+}