Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-events.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  GMime
3  *  Copyright (C) 2000-2012 Jeffrey Stedfast
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18  *  02110-1301, USA.
19  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "gmime-events.h"
27 #include "list.h"
28
29 typedef struct _EventListener {
30         struct _EventListener *next;
31         struct _EventListener *prev;
32         GMimeEventCallback callback;
33         gpointer user_data;
34         int blocked;
35 } EventListener;
36
37 static EventListener *
38 event_listener_new (GMimeEventCallback callback, gpointer user_data)
39 {
40         EventListener *listener;
41         
42         listener = g_slice_new (EventListener);
43         listener->user_data = user_data;
44         listener->callback = callback;
45         listener->prev = NULL;
46         listener->next = NULL;
47         listener->blocked = 0;
48         
49         return listener;
50 }
51
52 static void
53 event_listener_free (EventListener *listener)
54 {
55         g_slice_free (EventListener, listener);
56 }
57
58
59 struct _GMimeEvent {
60         gpointer owner;
61         List list;
62 };
63
64
65 /**
66  * g_mime_event_new:
67  * @owner: a pointer to the object owning this event
68  *
69  * Creates a new #GMimeEvent context.
70  *
71  * Returns: a newly allocated #GMimeEvent context.
72  **/
73 GMimeEvent *
74 g_mime_event_new (gpointer owner)
75 {
76         GMimeEvent *event;
77         
78         event = g_slice_new (GMimeEvent);
79         list_init (&event->list);
80         event->owner = owner;
81         
82         return event;
83 }
84
85
86 /**
87  * g_mime_event_destroy:
88  * @event: a #GMimeEvent
89  *
90  * Destroys an event context.
91  **/
92 void
93 g_mime_event_destroy (GMimeEvent *event)
94 {
95         EventListener *node, *next;
96         
97         node = (EventListener *) event->list.head;
98         while (node->next) {
99                 next = node->next;
100                 event_listener_free (node);
101                 node = next;
102         }
103         
104         g_slice_free (GMimeEvent, event);
105 }
106
107
108 static EventListener *
109 g_mime_event_find_listener (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
110 {
111         EventListener *node;
112         
113         node = (EventListener *) event->list.head;
114         while (node->next) {
115                 if (node->callback == callback && node->user_data == user_data)
116                         return node;
117                 node = node->next;
118         }
119         
120         return NULL;
121 }
122
123
124 /**
125  * g_mime_event_block:
126  * @event: a #GMimeEvent
127  * @callback: a #GMimeEventCallback
128  * @user_data: user context data
129  *
130  * Blocks the specified callback from being called when @event is emitted.
131  **/
132 void
133 g_mime_event_block (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
134 {
135         EventListener *listener;
136         
137         if ((listener = g_mime_event_find_listener (event, callback, user_data)))
138                 listener->blocked++;
139 }
140
141
142 /**
143  * g_mime_event_unblock:
144  * @event: a #GMimeEvent
145  * @callback: a #GMimeEventCallback
146  * @user_data: user context data
147  *
148  * Unblocks the specified callback from being called when @event is
149  * emitted.
150  **/
151 void
152 g_mime_event_unblock (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
153 {
154         EventListener *listener;
155         
156         if ((listener = g_mime_event_find_listener (event, callback, user_data)))
157                 listener->blocked--;
158 }
159
160
161 /**
162  * g_mime_event_add:
163  * @event: a #GMimeEvent
164  * @callback: a #GMimeEventCallback
165  * @user_data: user context data
166  *
167  * Adds a callback function that will get called with the specified
168  * @user_data whenever @event is emitted.
169  **/
170 void
171 g_mime_event_add (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
172 {
173         EventListener *listener;
174         
175         listener = event_listener_new (callback, user_data);
176         list_append (&event->list, (ListNode *) listener);
177 }
178
179
180 /**
181  * g_mime_event_remove:
182  * @event: a #GMimeEvent
183  * @callback: a #GMimeEventCallback
184  * @user_data: user context data
185  *
186  * Removes the specified callback function from the list of callbacks
187  * that will be called when the @event is emitted.
188  **/
189 void
190 g_mime_event_remove (GMimeEvent *event, GMimeEventCallback callback, gpointer user_data)
191 {
192         EventListener *listener;
193         
194         if ((listener = g_mime_event_find_listener (event, callback, user_data))) {
195                 list_unlink ((ListNode *) listener);
196                 event_listener_free (listener);
197         }
198 }
199
200
201 /**
202  * g_mime_event_emit:
203  * @event: a #GMimeEvent
204  * @args: an argument pointer
205  *
206  * Calls each callback registered with this @event with the specified
207  * @args.
208  **/
209 void
210 g_mime_event_emit (GMimeEvent *event, gpointer args)
211 {
212         EventListener *node;
213         
214         node = (EventListener *) event->list.head;
215         while (node->next) {
216                 if (node->blocked <= 0)
217                         node->callback (event->owner, args, node->user_data);
218                 node = node->next;
219         }
220 }