3
3
* Author: Brent Hendricks
4
4
* Project: GGZ Core Client Lib
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 $
8
8
* This is the code for handling hook functions
12
12
* Copyright (C) 2000 Brent Hendricks.
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.
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.
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.
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.
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
29
29
#ifdef HAVE_CONFIG_H
30
# include <config.h> /* Site-specific config */
30
# include <config.h> /* Site-specific config */
35
34
#include <stdlib.h>
36
35
#include <unistd.h>
40
39
#include "ggzcore.h"
42
typedef struct _GGZHook GGZHook;
44
/* _GGZHook : data type for representing single hook in a list */
47
/* Callback ID (unique within this event) */
50
/* Actual callback function */
53
/* Pointer to user data */
54
const void *user_data;
56
/* Pointer to next GGZHook */
61
/* GGZHookList : list of hook functions */
64
/* Object ID unique to this hooklist: gets passed to callbacks */
67
/* Sequence number for callbacks */
70
/* Linked list of hooks */
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);
50
80
/* No publicly Exported functions */
63
93
* GGZHookList* : pointer to new hooklist structure
65
GGZHookList* _ggzcore_hook_list_init(const unsigned int id)
95
GGZHookList *_ggzcore_hook_list_init(const unsigned int id)
67
97
GGZHookList *hooks;
69
hooks = ggz_malloc(sizeof(GGZHookList));
99
hooks = ggz_malloc(sizeof(*hooks));
76
106
/* _ggzcore_hook_add() - Add hook function to list
83
113
* int : id for this callback
85
int _ggzcore_hook_add(GGZHookList* list, const GGZHookFunc func)
115
int _ggzcore_hook_add(GGZHookList * list, const GGZHookFunc func)
87
117
return _ggzcore_hook_add_full(list, func, NULL);
101
131
* int : id for this callback
103
int _ggzcore_hook_add_full(GGZHookList* list,
104
const GGZHookFunc func,
133
int _ggzcore_hook_add_full(GGZHookList * list,
134
const GGZHookFunc func, const void *user_data)
107
struct _GGZHook *hook, *cur, *next;
109
hook = ggz_malloc(sizeof(struct _GGZHook));
136
GGZHook *hook, *cur, *next;
138
hook = ggz_malloc(sizeof(*hook));
111
140
/* Assign unique ID */
112
141
hook->id = list->seq_id++;
113
142
hook->func = func;
114
143
hook->user_data = user_data;
116
145
/* Append onto list of callbacks */
117
if ( (next = list->hooks) == NULL)
146
if ((next = list->hooks) == NULL)
118
147
list->hooks = hook;
134
163
* GGZHookList* list : Hooklist from which to remove hooks
136
void _ggzcore_hook_remove_all(GGZHookList *list)
165
void _ggzcore_hook_remove_all(GGZHookList * list)
138
struct _GGZHook *cur, *next;
140
169
next = list->hooks;
157
186
* int : 0 if successful, -1 on error
159
int _ggzcore_hook_remove_id(GGZHookList *list, const unsigned int id)
188
int _ggzcore_hook_remove_id(GGZHookList * list, const unsigned int id)
162
struct _GGZHook *cur, *prev = NULL;
191
GGZHook *cur, *prev = NULL;
164
193
cur = list->hooks;
165
while (cur && (cur->id != id)) {
194
while (cur && cur->id != id) {
171
200
_ggzcore_hook_remove_actual(list, cur, prev);
186
215
* int : 0 if successful, -1 on error
188
int _ggzcore_hook_remove(GGZHookList *list, const GGZHookFunc func)
217
int _ggzcore_hook_remove(GGZHookList * list, const GGZHookFunc func)
191
struct _GGZHook *cur, *prev = NULL;
220
GGZHook *cur, *prev = NULL;
193
222
cur = list->hooks;
194
223
while (cur && (cur->func != func)) {
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
219
GGZHookReturn _ggzcore_hook_list_invoke(GGZHookList *list, void *event_data)
248
GGZHookReturn _ggzcore_hook_list_invoke(GGZHookList * list,
249
const void *event_data)
221
251
GGZHookReturn status, retval = GGZ_HOOK_OK;
222
struct _GGZHook *cur, *next, *prev = NULL;
252
GGZHook *cur, *next, *prev = NULL;
255
/* This should never happen ?! */
256
return GGZ_HOOK_CRISIS;
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);
263
(cur->func) (list->id, event_data, cur->user_data);
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
232
272
_ggzcore_hook_remove_actual(list, cur, prev);
235
else if (status == GGZ_HOOK_CRISIS) {
274
} else if (status == GGZ_HOOK_CRISIS) {
236
275
retval = GGZ_HOOK_CRISIS;
263
302
* GGZHookList *list : hooklist to destroy
265
void _ggzcore_hook_list_dump(GGZHookList *list)
304
void _ggzcore_hook_list_dump(GGZHookList * list)
267
struct _GGZHook *cur;
269
308
for (cur = list->hooks; cur != NULL; cur = cur->next)
270
309
ggz_debug(GGZCORE_DBG_HOOK, " Hook id %d", cur->id);
274
313
/* Static functions internal to this file */
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)
281
319
/* Special case if it was first in the list */
283
321
list->hooks = hook->next;
285
323
prev->next = hook->next;