Groan.

On Tue, 2004-11-02 at 13:19 -0500, Jeffrey Stedfast wrote:
sounds cool, but where's the patch? :)

Jeff

On Tue, 2004-11-02 at 17:38 +0800, Not Zed wrote:
> 
> Well, work in progress patch below, as seen on the blog.
> 
> The idea is to add interfaces to camel objects, this would let us do
> some things we currently have to extend every class for.
> 
> It might make it easier to support e.g. public folders, and so on.  We
> can just add an IPublicFolder interface to the store class rather than
> having to put in dummy callbacks for all stores.  Interfaces fix a lot
> of the locking issues too, by forcing each implementation to do all
> the work rather than try to inherit some stuff which just interferes
> with it.
> 
> I have an example 'interface' in camel-store in the patch, for
> subscriptions, although nothing is hooked up (nor is any of it tested
> yet apart from compiling).
> 
> (another one of the 'big things' i'm trying to get out the way before
> the eventual shift to a separate camel, in eds or otherwise).
> 
> -- 
> 
> Michael Zucchi <[EMAIL PROTECTED]>
> "I'm stuck in a reality I can't
> imagine could be real."
> Novell's Evolution and Free
> Software Developer
--
Michael Zucchi <[EMAIL PROTECTED]>
"I'm stuck in a reality I can't imagine could be real."
Novell's Evolution and Free Software Developer

<<attachment: zed-48.small.jpg>>

Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.2285
diff -u -3 -r1.2285 ChangeLog
--- camel/ChangeLog     28 Oct 2004 16:54:44 -0000      1.2285
+++ camel/ChangeLog     2 Nov 2004 09:28:40 -0000
@@ -1,3 +1,14 @@
+2004-11-02  Not Zed  <[EMAIL PROTECTED]>
+
+       * camel-object.c (camel_object_hook_event): check interfaces for
+       events too.
+       (camel_object_trigger_event): check interfaces for events too.
+       (camel_object_class_add_event): more checks for interfaces vs
+       normal object classes.
+       (camel_object_class_add_interface): add an interface to a class.
+       (camel_object_get_interface): query for interfaces on an object.
+       (camel_object_get_type): register the interface type.
+
 2004-10-28  Jeffrey Stedfast  <[EMAIL PROTECTED]>
 
        * providers/imap4/camel-imap4-summary.c (envelope_decode_nstring):
Index: camel/camel-object.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-object.c,v
retrieving revision 1.49
diff -u -3 -r1.49 camel-object.c
--- camel/camel-object.c        20 Sep 2004 05:59:53 -0000      1.49
+++ camel/camel-object.c        2 Nov 2004 09:28:40 -0000
@@ -43,8 +43,10 @@
 /* I just mashed the keyboard for these... */
 #define CAMEL_OBJECT_MAGIC              0x77A344ED
 #define CAMEL_OBJECT_CLASS_MAGIC        0xEE26A997
+#define CAMEL_INTERFACE_MAGIC           0xBCE137A7
 #define CAMEL_OBJECT_FINALISED_MAGIC       0x84AC365F
 #define CAMEL_OBJECT_CLASS_FINALISED_MAGIC 0x7621ABCD
+#define CAMEL_INTERFACE_FINALISED_MAGIC    0x7CB2FE71
 
 /* ** Quickie type system ************************************************* */
 
@@ -113,6 +115,9 @@
 static const char *meta_name = "object:meta";
 #define CAMEL_OBJECT_STATE_FILE_MAGIC "CLMD"
 
+/* interface stuff */
+static const char *interface_name = "object:interface";
+
 /* ********************************************************************** */
 
 static CamelHookList *camel_object_get_hooks(CamelObject *o);
@@ -135,7 +140,9 @@
 static GHashTable *type_table;
 static EMemChunk *type_chunks;
 
+/* fundamental types are accessed via global */
 CamelType camel_object_type;
+CamelType camel_interface_type;
 
 #define P_LOCK(l) (pthread_mutex_lock(&l))
 #define P_UNLOCK(l) (pthread_mutex_unlock(&l))
@@ -144,7 +151,6 @@
 #define CLASS_LOCK(k) (g_mutex_lock((((CamelObjectClass *)k)->lock)))
 #define CLASS_UNLOCK(k) (g_mutex_unlock((((CamelObjectClass *)k)->lock)))
 
-
 static struct _CamelHookPair *
 pair_alloc(void)
 {
@@ -211,6 +217,8 @@
 
 /* ************************************************************************ */
 
+/* CamelObject base methods */
+
 /* Should this return the object to the caller? */
 static void
 cobject_init(CamelObject *o, CamelObjectClass *klass)
@@ -610,6 +618,59 @@
        g_free(klass);
 }
 
+
+/* CamelInterface base methods */
+
+static void
+cinterface_init(CamelObject *o, CamelObjectClass *klass)
+{
+       g_error("Cannot instantiate interfaces, trying to instantiate '%s'", 
klass->name);
+       abort();
+}
+
+static int
+cinterface_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args)
+{
+       return 0;
+}
+
+static int
+cinterface_setv(CamelObject *o, CamelException *ex, CamelArgV *args)
+{
+       return 0;
+}
+
+static void
+cinterface_free(CamelObject *o, guint32 tag, void *value)
+{
+       /* NOOP */
+}
+
+static void
+cinterface_class_init(CamelObjectClass *klass)
+{
+       klass->magic = CAMEL_INTERFACE_MAGIC;
+
+       /* just setup dummy callbacks, properties could be part of the interface but 
we support none */
+       klass->getv = cinterface_getv;
+       klass->setv = cinterface_setv;
+       klass->free = cinterface_free;
+
+       /* TODO: ok, these are cruft hanging around an interface, but it saves having 
to define two different class bases */
+       klass->meta_get = NULL;
+       klass->meta_set = NULL;
+       klass->state_read = NULL;
+       klass->state_write = NULL;
+}
+
+static void
+cinterface_class_finalise(CamelObjectClass * klass)
+{
+       klass->magic = CAMEL_INTERFACE_FINALISED_MAGIC;
+       g_free(klass);
+}
+
+/* this function must be called for any other in the object system */
 CamelType
 camel_object_get_type(void)
 {
@@ -620,6 +681,12 @@
                                                        sizeof(CamelObject), 
sizeof(CamelObjectClass),
                                                        cobject_class_init, 
cobject_class_finalise,
                                                        cobject_init, 
cobject_finalise);
+
+               camel_interface_type = camel_type_register(NULL, "CamelInterface",
+                                                          0, sizeof(CamelInterface),
+                                                          cinterface_class_init, 
cinterface_class_finalise,
+                                                          cinterface_init, NULL);
+                                                          
        }
 
        return camel_object_type;
@@ -635,24 +702,19 @@
                type->klass_init(klass);
 }
 
-CamelType
-camel_type_register(CamelType parent, const char * name,
-                   /*unsigned int ver, unsigned int rev,*/
-                   size_t object_size, size_t klass_size,
-                   CamelObjectClassInitFunc class_init,
-                   CamelObjectClassFinalizeFunc class_finalise,
-                   CamelObjectInitFunc object_init,
-                   CamelObjectFinalizeFunc object_finalise)
+static CamelType
+co_type_register(CamelType parent, const char * name,
+                /*unsigned int ver, unsigned int rev,*/
+                size_t object_size, size_t klass_size,
+                CamelObjectClassInitFunc class_init,
+                CamelObjectClassFinalizeFunc class_finalise,
+                CamelObjectInitFunc object_init,
+                CamelObjectFinalizeFunc object_finalise)
 {
        CamelObjectClass *klass;
        /*int offset;
          size_t size;*/
 
-       if (parent != NULL && parent->magic != CAMEL_OBJECT_CLASS_MAGIC) {
-               g_warning("camel_type_register: invalid junk parent class for '%s'", 
name);
-               return NULL;
-       }
-
        E_LOCK(type_lock);
 
        /* Have to check creation, it might've happened in another thread before we 
got here */
@@ -724,6 +786,37 @@
        return klass;
 }
 
+CamelType
+camel_type_register(CamelType parent, const char * name,
+                   /*unsigned int ver, unsigned int rev,*/
+                   size_t object_size, size_t klass_size,
+                   CamelObjectClassInitFunc class_init,
+                   CamelObjectClassFinalizeFunc class_finalise,
+                   CamelObjectInitFunc object_init,
+                   CamelObjectFinalizeFunc object_finalise)
+{
+       if (parent != NULL && parent->magic != CAMEL_OBJECT_CLASS_MAGIC) {
+               g_warning("camel_type_register: invalid junk parent class for '%s'", 
name);
+               return NULL;
+       }
+
+       return co_type_register(parent, name, object_size, klass_size, class_init, 
class_finalise, object_init, object_finalise);
+}
+
+CamelType
+camel_interface_register(CamelType parent, const char *name,
+                        size_t class_size,
+                        CamelObjectClassInitFunc class_init,
+                        CamelObjectClassFinalizeFunc class_finalise)
+{
+       if (parent != NULL && parent->magic != CAMEL_INTERFACE_MAGIC) {
+               g_warning("camel_interface_register: invalid junk parent class for 
'%s'", name);
+               return NULL;
+       }
+
+       return camel_type_register(parent, name, 0, class_size, class_init, 
class_finalise, NULL, NULL);
+}
+
 static void
 camel_object_init(CamelObject *o, CamelObjectClass *klass, CamelType type)
 {
@@ -852,6 +945,9 @@
        if (type->magic == CAMEL_OBJECT_CLASS_MAGIC)
                return type->name;
 
+       if (type->magic == CAMEL_INTERFACE_MAGIC)
+               return type->name;
+
        return "(Junk class)";
 }
 
@@ -875,10 +971,14 @@
                what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name);
        else if (o->magic == CAMEL_OBJECT_CLASS_MAGIC)
                what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name);
+       else if (o->magic == CAMEL_INTERFACE_MAGIC)
+               what = g_strdup_printf("INTERFACE '%s'", ((CamelObjectClass 
*)o)->name);
        else if (o->magic == CAMEL_OBJECT_FINALISED_MAGIC)
                what = g_strdup_printf("finalised OBJECT");
        else if (o->magic == CAMEL_OBJECT_CLASS_FINALISED_MAGIC)
                what = g_strdup_printf("finalised CLASS");
+       else if (o->magic == CAMEL_INTERFACE_FINALISED_MAGIC)
+               what = g_strdup_printf("finalised INTERFACE");
        else 
                what = g_strdup_printf("junk data");
 
@@ -948,6 +1048,20 @@
        return FALSE;
 }
 
+gboolean
+camel_interface_is(CamelObjectClass *k, CamelType ctype)
+{
+       g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), FALSE);
+
+       while (k) {
+               if (k == ctype)
+                       return TRUE;
+               k = k->parent;
+       }
+
+       return FALSE;
+}
+
 CamelObject *
 camel_object_cast(CamelObject *o, CamelType ctype)
 {
@@ -985,6 +1099,55 @@
        return NULL;
 }
 
+CamelObjectClass *
+camel_interface_cast(CamelObjectClass *k, CamelType ctype)
+{
+       CamelObjectClass *r = k;
+
+       g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), NULL);
+
+       while (k) {
+               if (k == ctype)
+                       return r;
+               k = k->parent;
+       }
+
+       g_warning("Interface '%s' doesn't have '%s' in its hierarchy", r->name, 
ctype->name);
+
+       return NULL;
+}
+
+static CamelHookPair *
+co_find_pair(CamelObjectClass *klass, const char *name)
+{
+       CamelHookPair *hook;
+
+       hook = klass->hooks;
+       while (hook) {
+               if (strcmp(hook->name, name) == 0)
+                       return hook;
+               hook = hook->next;
+       }
+
+       return NULL;
+}
+
+static CamelHookPair *
+co_find_pair_ptr(CamelObjectClass *klass, const char *name)
+{
+       CamelHookPair *hook;
+
+       hook = klass->hooks;
+       while (hook) {
+               if (hook->name == name)
+                       return hook;
+               hook = hook->next;
+       }
+
+       return NULL;
+}
+
+/* class functions */
 void
 camel_object_class_add_event(CamelObjectClass *klass, const char *name, 
CamelObjectEventPrepFunc prep)
 {
@@ -992,14 +1155,17 @@
 
        g_return_if_fail (name);
 
-       pair = klass->hooks;
-       while (pair) {
-               if (strcmp(pair->name, name) == 0) {
-                       g_warning("camel_object_class_add_event: `%s' is already 
declared for '%s'\n",
-                                 name, klass->name);
-                       return;
-               }
-               pair = pair->next;
+       pair = co_find_pair(klass, name);
+       if (pair) {
+               g_warning("camel_object_class_add_event: `%s' is already declared for 
'%s'",
+                         name, klass->name);
+               return;
+       }
+
+       if (klass->magic == CAMEL_INTERFACE_MAGIC && prep != NULL) {
+               g_warning("camel_object_class_add_event: `%s', CamelInterface '%s' may 
not have an event prep function - ignored",
+                         name, klass->name);
+               prep = NULL;
        }
 
        pair = pair_alloc();
@@ -1011,6 +1177,50 @@
        klass->hooks = pair;
 }
 
+void
+camel_object_class_add_interface(CamelObjectClass *klass, CamelType itype)
+{
+       CamelHookPair *pair;
+       CamelType iscan;
+       GPtrArray *interfaces;
+       int i;
+
+       if (!camel_interface_is(itype, camel_interface_type)) {
+               g_warning("Cannot add an interface not derived from CamelInterface on 
class '%s'", klass->name);
+               return;
+       }
+
+       if (camel_object_class_is(klass, camel_interface_type)) {
+               g_warning("Cannot add an interface onto a class derived from 
CamelInterface");
+               return;
+       }
+
+       /* we store it on the class hooks so we don't have to add any extra space to 
the class */
+       pair = co_find_pair_ptr(klass, interface_name);
+       if (pair == NULL) {
+               pair = pair_alloc();
+               pair->data = g_ptr_array_new();
+               pair->next = klass->hooks;
+               klass->hooks = pair;
+       }
+
+       /* We just check that this type isn't added/derived anywhere else */
+       interfaces = pair->data;
+       iscan = itype;
+       while (iscan && iscan != camel_interface_type) {
+               for (i=0;i<interfaces->len;i++) {
+                       if (camel_interface_is((CamelType)interfaces->pdata[i], 
iscan)) {
+                               g_warning("Cannot add an interface twice '%s' on class 
'%s'\n", itype->name, klass->name);
+                               return;
+                       }
+               }
+               iscan = iscan->parent;
+       }
+
+       if (iscan == camel_interface_type)
+               g_ptr_array_add(interfaces, itype);
+}
+
 /* free hook data */
 static void
 camel_object_free_hooks(CamelObject *o)
@@ -1079,18 +1289,27 @@
        g_return_val_if_fail(name != NULL, 0);
        g_return_val_if_fail(func != NULL, 0);
 
-       hook = obj->klass->hooks;
-       while (hook) {
-               if (strcmp(hook->name, name) == 0)
-                       goto setup;
-               hook = hook->next;
-       }
+       hook = co_find_pair(obj->klass, name);
 
-       g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' 
with no defined events.",
-                 name, obj->klass->name);
+       /* Check all interfaces on this object for events defined on them */
+       if (hook == NULL) {
+               pair = co_find_pair_ptr(obj->klass, interface_name);
+               if (pair) {
+                       GPtrArray *interfaces = pair->data;
+                       int i;
+
+                       for (i=0;i<interfaces->len;i++) {
+                               hook = co_find_pair(interfaces->pdata[i], name);
+                               if (hook)
+                                       goto setup;
+                       }
+               }
 
-       return 0;
+               g_warning("camel_object_hook_event: trying to hook event `%s' in class 
`%s' with no defined events.",
+                         name, obj->klass->name);
 
+               return 0;
+       }
 setup:
        /* setup hook pair */
        pair = pair_alloc();
@@ -1217,11 +1436,24 @@
        g_return_if_fail (CAMEL_IS_OBJECT (obj));
        g_return_if_fail (name);
 
-       hook = obj->klass->hooks;
-       while (hook) {
-               if (strcmp(hook->name, name) == 0)
-                       goto trigger;
-               hook = hook->next;
+       hook = co_find_pair(obj->klass, name);
+       if (hook)
+               goto trigger;
+
+       if (obj->hooks == NULL)
+               return;
+
+       /* interface events can't have prep functions */
+       pair = co_find_pair_ptr(obj->klass, interface_name);
+       if (pair) {
+               GPtrArray *interfaces = pair->data;
+               int i;
+
+               for (i=0;i<interfaces->len;i++) {
+                       hook = co_find_pair(interfaces->pdata[i], name);
+                       if (hook)
+                               goto trigger_interface;
+               }
        }
 
        g_warning("camel_object_trigger_event: trying to trigger unknown event `%s' in 
class `%s'",
@@ -1237,7 +1469,7 @@
        /* also, no hooks, dont bother going further */
        if (obj->hooks == NULL)
                return;
-
+trigger_interface:
        /* lock the object for hook emission */
        camel_object_ref(obj);
        hooks = camel_object_get_hooks(obj);
@@ -1283,6 +1515,31 @@
 
        camel_object_unget_hooks(obj);
        camel_object_unref(obj);
+}
+
+void *
+camel_object_get_interface(void *vo, CamelType itype)
+{
+       CamelObject *obj = vo;
+       CamelHookPair *pair;
+
+       g_return_val_if_fail(CAMEL_IS_OBJECT (obj), NULL);
+       g_return_val_if_fail(camel_interface_is(itype, camel_interface_type), NULL);
+
+       pair = co_find_pair_ptr(obj->klass, interface_name);
+       if (pair) {
+               GPtrArray *interfaces = pair->data;
+               int i;
+
+               for (i=0;i<interfaces->len;i++) {
+                       if (camel_interface_is((CamelType)interfaces->pdata[i], itype))
+                               return (CamelType)interfaces->pdata[i];
+               }
+       }
+
+       g_warning("Object %p class %s doesn't contain interface %s\n", vo, 
obj->klass->name, itype->name);
+
+       return NULL;
 }
 
 /* get/set arg methods */
Index: camel/camel-object.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-object.h,v
retrieving revision 1.31
diff -u -3 -r1.31 camel-object.h
--- camel/camel-object.h        20 Sep 2004 05:59:53 -0000      1.31
+++ camel/camel-object.h        2 Nov 2004 09:28:40 -0000
@@ -72,6 +72,10 @@
 typedef unsigned int CamelObjectHookID;
 typedef struct _CamelObjectMeta CamelObjectMeta;
 
+extern CamelType camel_interface_type;
+#define CAMEL_INTERFACE_TYPE (camel_interface_type)
+typedef struct _CamelInterface CamelInterface;
+
 typedef void (*CamelObjectClassInitFunc) (CamelObjectClass *);
 typedef void (*CamelObjectClassFinalizeFunc) (CamelObjectClass *);
 typedef void (*CamelObjectInitFunc) (CamelObject *, CamelObjectClass *);
@@ -165,6 +169,8 @@
        void (*init)(struct _CamelObject *, struct _CamelObjectClass *);
        void (*finalise)(struct _CamelObject *);
 
+       /* root-class fields follow, type system above */
+
        /* get/set interface */
        int (*setv)(struct _CamelObject *, struct _CamelException *ex, CamelArgV 
*args);
        int (*getv)(struct _CamelObject *, struct _CamelException *ex, CamelArgGetV 
*args);
@@ -180,6 +186,11 @@
        int (*state_write)(struct _CamelObject *, FILE *fp);
 };
 
+/* an interface is just a class with no instance data */
+struct _CamelInterface {
+       struct _CamelObjectClass type;
+};
+
 /* The type system .... it's pretty simple..... */
 void camel_type_init (void);
 CamelType camel_type_register(CamelType parent, const char * name, /*unsigned int 
ver, unsigned int rev,*/
@@ -190,6 +201,11 @@
                              CamelObjectInitFunc instance_init,
                              CamelObjectFinalizeFunc instance_finalize);
 
+CamelType camel_interface_register(CamelType parent, const char *name,
+                                  size_t classfuncs_size,
+                                  CamelObjectClassInitFunc class_init,
+                                  CamelObjectClassFinalizeFunc class_finalize);
+
 /* deprecated interface */
 #define camel_type_get_global_classfuncs(x) ((CamelObjectClass *)(x))
 
@@ -197,6 +213,7 @@
 const char *camel_type_to_name (CamelType type);
 CamelType camel_name_to_type (const char *name);
 void camel_object_class_add_event (CamelObjectClass *klass, const char *name, 
CamelObjectEventPrepFunc prep);
+void camel_object_class_add_interface(CamelObjectClass *klass, CamelType itype);
 
 void camel_object_class_dump_tree (CamelType root);
 
@@ -207,6 +224,9 @@
 CamelObjectClass *camel_object_class_cast (CamelObjectClass *klass, CamelType ctype);
 gboolean camel_object_class_is (CamelObjectClass *klass, CamelType ctype);
 
+CamelObjectClass *camel_interface_cast(CamelObjectClass *klass, CamelType ctype);
+gboolean camel_interface_is(CamelObjectClass *k, CamelType ctype);
+
 CamelType camel_object_get_type (void);
 
 CamelObject *camel_object_new (CamelType type);
@@ -225,6 +245,9 @@
 void camel_object_remove_event(void *obj, CamelObjectHookID id);
 void camel_object_unhook_event(void *obj, const char *name, CamelObjectEventHookFunc 
hook, void *data);
 void camel_object_trigger_event(void *obj, const char *name, void *event_data);
+
+/* interfaces */
+void *camel_object_get_interface(void *vo, CamelType itype);
 
 /* get/set methods */
 int camel_object_set(void *obj, struct _CamelException *ex, ...);
Index: camel/camel-store.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-store.c,v
retrieving revision 1.154
diff -u -3 -r1.154 camel-store.c
--- camel/camel-store.c 20 Sep 2004 05:59:53 -0000      1.154
+++ camel/camel-store.c 2 Nov 2004 09:28:40 -0000
@@ -1204,3 +1204,58 @@
        
        return equal;
 }
+
+/* subscriptions interface */
+
+static void
+cis_interface_init (CamelISubscribe *cis)
+{
+       camel_object_class_add_event((CamelType)cis, "subscribed", NULL);
+       camel_object_class_add_event((CamelType)cis, "unsubscribed", NULL);
+}
+
+CamelType camel_isubscribe_get_type (void)
+{
+       static CamelType camel_isubscribe_type = CAMEL_INVALID_TYPE;
+
+       if (camel_isubscribe_type == CAMEL_INVALID_TYPE) {
+               camel_isubscribe_type = camel_interface_register 
(CAMEL_INTERFACE_TYPE, "CamelISubscribe",
+                                                                 sizeof 
(CamelISubscribe),
+                                                                 
(CamelObjectClassInitFunc) cis_interface_init,
+                                                                 NULL);
+       }
+
+       return camel_isubscribe_type;
+}
+
+gboolean camel_isubscribe_subscribed(CamelStore *store, const char *name)
+{
+       CamelISubscribe *iface = camel_object_get_interface(store, 
camel_isubscribe_get_type());
+
+       if (iface && iface->subscribed)
+               return iface->subscribed(store, name);
+
+       g_warning("Trying to invoke unimplemented subscribed method on a store");
+       return FALSE;
+}
+
+void camel_isubscribe_subscribe(CamelStore *store, const char *folder_name, 
CamelException *ex)
+{
+       CamelISubscribe *iface = camel_object_get_interface(store, 
camel_isubscribe_get_type());
+
+       if (iface && iface->subscribe)
+               return iface->subscribe(store, folder_name, ex);
+
+       g_warning("Trying to invoke unimplemented subscribe method on a store");
+}
+
+void camel_isubscribe_unsubscribe(CamelStore *store, const char *folder_name, 
CamelException *ex)
+{
+       CamelISubscribe *iface = camel_object_get_interface(store, 
camel_isubscribe_get_type());
+
+       if (iface && iface->unsubscribe)
+               return iface->unsubscribe(store, folder_name, ex);
+
+       g_warning("Trying to invoke unimplemented unsubscribe method on a store");
+}
+
Index: camel/camel-store.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-store.h,v
retrieving revision 1.69
diff -u -3 -r1.69 camel-store.h
--- camel/camel-store.h 26 May 2004 04:24:01 -0000      1.69
+++ camel/camel-store.h 2 Nov 2004 09:28:40 -0000
@@ -164,7 +164,6 @@
                                                     CamelException *ex);
 } CamelStoreClass;
 
-
 /* Standard Camel function */
 CamelType camel_store_get_type (void);
 
@@ -230,6 +229,20 @@
 int              camel_store_folder_uri_equal         (CamelStore *store,
                                                       const char *uri0,
                                                       const char *uri1);
+
+typedef struct _CamelISubscribe CamelISubscribe;
+struct _CamelISubscribe {
+       CamelInterface iface;
+
+       gboolean (*subscribed)(CamelStore *store, const char *folder_name);
+       void (*subscribe)(CamelStore *store, const char *folder_name, CamelException 
*ex);
+       void (*unsubscribe)(CamelStore *store, const char *folder_name, CamelException 
*ex);
+};
+
+CamelType camel_isubscribe_get_type (void);
+gboolean camel_isubscribe_subscribed(CamelStore *store, const char *name);
+void camel_isubscribe_subscribe(CamelStore *store, const char *folder_name, 
CamelException *ex);
+void camel_isubscribe_unsubscribe(CamelStore *store, const char *folder_name, 
CamelException *ex);
 
 #ifdef __cplusplus
 }

Reply via email to