~ubuntu-branches/ubuntu/gutsy/ggz-client-libs/gutsy

« back to all changes in this revision

Viewing changes to ggzcore/hook.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Eisentraut, Josef Spillner, Peter Eisentraut
  • Date: 2006-09-09 13:37:14 UTC
  • mfrom: (2.1.2 edgy)
  • Revision ID: james.westby@ubuntu.com-20060909133714-q49a9kvjfkc0wcc3
Tags: 0.0.13-3
[ Josef Spillner ]
* Change ggzcore-bin dependency from ggzmod to recommends from ggzcore
  (closes: #384671).

[ Peter Eisentraut ]
* Make package dependencies binNMU-safe through use of ${binary:Version}
  (closes: #386126)

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 * Author: Brent Hendricks
4
4
 * Project: GGZ Core Client Lib
5
5
 * Date: 11/01/00
6
 
 * $Id: hook.c,v 1.7 2002/10/17 23:56:16 jdorje Exp $
 
6
 * $Id: hook.c 7939 2006-03-16 14:33:16Z josef $
7
7
 *
8
8
 * This is the code for handling hook functions
9
9
 *
11
11
 *
12
12
 * Copyright (C) 2000 Brent Hendricks.
13
13
 *
14
 
 * This program is free software; you can redistribute it and/or modify
15
 
 * it under the terms of the GNU General Public License as published by
16
 
 * the Free Software Foundation; either version 2 of the License, or
17
 
 * (at your option) any later version.
18
 
 *
19
 
 * This program is distributed in the hope that it will be useful,
 
14
 * This library is free software; you can redistribute it and/or
 
15
 * modify it under the terms of the GNU Lesser General Public
 
16
 * License as published by the Free Software Foundation; either
 
17
 * version 2.1 of the License, or (at your option) any later version.
 
18
 * 
 
19
 * This library is distributed in the hope that it will be useful,
20
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
 * GNU General Public License for more details.
23
 
 *
24
 
 * You should have received a copy of the GNU General Public License
25
 
 * along with this program; if not, write to the Free Software
26
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
22
 * Lesser General Public License for more details.
 
23
 * 
 
24
 * You should have received a copy of the GNU Lesser General Public
 
25
 * License along with this library; if not, write to the Free Software
 
26
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27
27
 */
28
28
 
29
29
#ifdef HAVE_CONFIG_H
30
 
#  include <config.h>           /* Site-specific config */
 
30
#  include <config.h>   /* Site-specific config */
31
31
#endif
32
32
 
33
33
#include <errno.h>
34
 
#include <poll.h>
35
34
#include <stdlib.h>
36
35
#include <unistd.h>
37
36
 
39
38
 
40
39
#include "ggzcore.h"
41
40
#include "hook.h"
42
 
#include "net.h"
43
 
#include "state.h"
 
41
 
 
42
typedef struct _GGZHook GGZHook;
 
43
 
 
44
/* _GGZHook : data type for representing single hook in a list */
 
45
struct _GGZHook {
 
46
 
 
47
        /* Callback ID (unique within this event) */
 
48
        unsigned int id;
 
49
 
 
50
        /* Actual callback function */
 
51
        GGZHookFunc func;
 
52
 
 
53
        /* Pointer to user data */
 
54
        const void *user_data;
 
55
 
 
56
        /* Pointer to next GGZHook */
 
57
        GGZHook *next;
 
58
};
 
59
 
 
60
 
 
61
/* GGZHookList : list of hook functions */
 
62
struct _GGZHookList {
 
63
 
 
64
        /* Object ID unique to this hooklist: gets passed to callbacks */
 
65
        unsigned int id;
 
66
 
 
67
        /* Sequence number for callbacks */
 
68
        int seq_id;
 
69
 
 
70
        /* Linked list of hooks */
 
71
        GGZHook *hooks;
 
72
 
 
73
};
 
74
 
44
75
 
45
76
/* Static functions */
46
 
static void _ggzcore_hook_remove_actual(GGZHookList *list, 
47
 
                                        struct _GGZHook *hook,
48
 
                                        struct _GGZHook *prev);
 
77
static void _ggzcore_hook_remove_actual(GGZHookList * list,
 
78
                                        GGZHook * hook, GGZHook * prev);
49
79
 
50
80
/* No publicly Exported functions */
51
81
 
62
92
 * Returns:
63
93
 * GGZHookList* : pointer to new hooklist structure
64
94
 */
65
 
GGZHookList* _ggzcore_hook_list_init(const unsigned int id)
 
95
GGZHookList *_ggzcore_hook_list_init(const unsigned int id)
66
96
{
67
97
        GGZHookList *hooks;
68
98
 
69
 
        hooks = ggz_malloc(sizeof(GGZHookList));
 
99
        hooks = ggz_malloc(sizeof(*hooks));
70
100
        hooks->id = id;
71
101
 
72
102
        return hooks;
73
103
}
74
 
        
 
104
 
75
105
 
76
106
/* _ggzcore_hook_add() - Add hook function to list
77
107
 *
82
112
 * Returns:
83
113
 * int : id for this callback 
84
114
 */
85
 
int _ggzcore_hook_add(GGZHookList* list, const GGZHookFunc func)
 
115
int _ggzcore_hook_add(GGZHookList * list, const GGZHookFunc func)
86
116
{
87
117
        return _ggzcore_hook_add_full(list, func, NULL);
88
118
}
100
130
 * Returns:
101
131
 * int : id for this callback 
102
132
 */
103
 
int _ggzcore_hook_add_full(GGZHookList* list, 
104
 
                           const GGZHookFunc func,
105
 
                           void* user_data)
 
133
int _ggzcore_hook_add_full(GGZHookList * list,
 
134
                           const GGZHookFunc func, const void *user_data)
106
135
{
107
 
        struct _GGZHook *hook, *cur, *next;
108
 
        
109
 
        hook = ggz_malloc(sizeof(struct _GGZHook));
110
 
        
 
136
        GGZHook *hook, *cur, *next;
 
137
 
 
138
        hook = ggz_malloc(sizeof(*hook));
 
139
 
111
140
        /* Assign unique ID */
112
141
        hook->id = list->seq_id++;
113
142
        hook->func = func;
114
143
        hook->user_data = user_data;
115
144
 
116
145
        /* Append onto list of callbacks */
117
 
        if ( (next = list->hooks) == NULL)
 
146
        if ((next = list->hooks) == NULL)
118
147
                list->hooks = hook;
119
148
        else {
120
149
                while (next) {
123
152
                }
124
153
                cur->next = hook;
125
154
        }
126
 
        
 
155
 
127
156
        return hook->id;
128
157
}
129
158
 
133
162
 * Receives:
134
163
 * GGZHookList* list : Hooklist from which to remove hooks
135
164
 */
136
 
void _ggzcore_hook_remove_all(GGZHookList *list)
 
165
void _ggzcore_hook_remove_all(GGZHookList * list)
137
166
{
138
 
        struct _GGZHook *cur, *next;
 
167
        GGZHook *cur, *next;
139
168
 
140
169
        next = list->hooks;
141
170
        while (next) {
156
185
 * Returns:
157
186
 * int : 0 if successful, -1 on error
158
187
 */
159
 
int _ggzcore_hook_remove_id(GGZHookList *list, const unsigned int id)
 
188
int _ggzcore_hook_remove_id(GGZHookList * list, const unsigned int id)
160
189
{
161
190
        int status = -1;
162
 
        struct _GGZHook *cur, *prev = NULL;
 
191
        GGZHook *cur, *prev = NULL;
163
192
 
164
193
        cur = list->hooks;
165
 
        while (cur && (cur->id != id)) {
 
194
        while (cur && cur->id != id) {
166
195
                prev = cur;
167
196
                cur = cur->next;
168
197
        }
169
 
        
 
198
 
170
199
        if (cur) {
171
200
                _ggzcore_hook_remove_actual(list, cur, prev);
172
201
                status = 0;
173
202
        }
174
 
        
 
203
 
175
204
        return status;
176
205
}
177
206
 
185
214
 * Returns:
186
215
 * int : 0 if successful, -1 on error
187
216
 */
188
 
int _ggzcore_hook_remove(GGZHookList *list, const GGZHookFunc func)
 
217
int _ggzcore_hook_remove(GGZHookList * list, const GGZHookFunc func)
189
218
{
190
219
        int status = -1;
191
 
        struct _GGZHook *cur, *prev = NULL;
 
220
        GGZHook *cur, *prev = NULL;
192
221
 
193
222
        cur = list->hooks;
194
223
        while (cur && (cur->func != func)) {
200
229
                _ggzcore_hook_remove_actual(list, cur, prev);
201
230
                status = 0;
202
231
        }
203
 
        
 
232
 
204
233
        return status;
205
234
}
206
235
 
216
245
 * GGZ_HOOK_ERROR  if at least one hook returned an error message
217
246
 * GGZ_HOOK_CRISIS if a hook terminated the sequence with a crisis
218
247
 */
219
 
GGZHookReturn _ggzcore_hook_list_invoke(GGZHookList *list, void *event_data)
 
248
GGZHookReturn _ggzcore_hook_list_invoke(GGZHookList * list,
 
249
                                        const void *event_data)
220
250
{
221
251
        GGZHookReturn status, retval = GGZ_HOOK_OK;
222
 
        struct _GGZHook *cur, *next, *prev = NULL;
 
252
        GGZHook *cur, *next, *prev = NULL;
 
253
 
 
254
        if (!list) {
 
255
                /* This should never happen ?! */
 
256
                return GGZ_HOOK_CRISIS;
 
257
        }
223
258
 
224
259
        cur = list->hooks;
225
260
        while (cur != NULL) {
226
261
                next = cur->next;
227
 
                status = (cur->func)(list->id, event_data, cur->user_data);
228
 
                
 
262
                status =
 
263
                    (cur->func) (list->id, event_data, cur->user_data);
 
264
 
229
265
                if (status == GGZ_HOOK_ERROR)
230
266
                        retval = GGZ_HOOK_ERROR;
231
267
                else if (status == GGZ_HOOK_REMOVE) {
 
268
                        /* Remove this hook, then back up one so when we
 
269
                           continue we go straight to the next hook.  This
 
270
                           isn't an error so the return value isn't
 
271
                           changed. */
232
272
                        _ggzcore_hook_remove_actual(list, cur, prev);
233
273
                        cur = prev;
234
 
                }
235
 
                else if (status == GGZ_HOOK_CRISIS) {
 
274
                } else if (status == GGZ_HOOK_CRISIS) {
236
275
                        retval = GGZ_HOOK_CRISIS;
237
276
                        break;
238
277
                }
239
 
                
 
278
 
240
279
                prev = cur;
241
280
                cur = next;
242
281
        }
243
 
        
 
282
 
244
283
        return retval;
245
284
}
246
285
 
250
289
 * Receives:
251
290
 * GGZHookList *list : hooklist to destroy
252
291
 */
253
 
void _ggzcore_hook_list_destroy(GGZHookList *list)
 
292
void _ggzcore_hook_list_destroy(GGZHookList * list)
254
293
{
255
294
        _ggzcore_hook_remove_all(list);
256
295
        ggz_free(list);
262
301
 * Receives:
263
302
 * GGZHookList *list : hooklist to destroy
264
303
 */
265
 
void _ggzcore_hook_list_dump(GGZHookList *list)
 
304
void _ggzcore_hook_list_dump(GGZHookList * list)
266
305
{
267
 
        struct _GGZHook *cur;
268
 
        
 
306
        GGZHook *cur;
 
307
 
269
308
        for (cur = list->hooks; cur != NULL; cur = cur->next)
270
309
                ggz_debug(GGZCORE_DBG_HOOK, "  Hook id %d", cur->id);
271
310
}
274
313
/* Static functions internal to this file */
275
314
 
276
315
/* Remove a particular hook node (prev should be NULL for first node) */
277
 
static void _ggzcore_hook_remove_actual(GGZHookList *list, 
278
 
                                        struct _GGZHook *hook,
279
 
                                        struct _GGZHook *prev)
 
316
static void _ggzcore_hook_remove_actual(GGZHookList * list,
 
317
                                        GGZHook * hook, GGZHook * prev)
280
318
{
281
319
        /* Special case if it was first in the list */
282
320
        if (!prev)
283
321
                list->hooks = hook->next;
284
322
        else
285
323
                prev->next = hook->next;
286
 
        
 
324
 
287
325
        ggz_free(hook);
288
326
}
289