1706f2543Smrg/* x-hook.c
2706f2543Smrg
3706f2543Smrg   Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4706f2543Smrg
5706f2543Smrg   Permission is hereby granted, free of charge, to any person
6706f2543Smrg   obtaining a copy of this software and associated documentation files
7706f2543Smrg   (the "Software"), to deal in the Software without restriction,
8706f2543Smrg   including without limitation the rights to use, copy, modify, merge,
9706f2543Smrg   publish, distribute, sublicense, and/or sell copies of the Software,
10706f2543Smrg   and to permit persons to whom the Software is furnished to do so,
11706f2543Smrg   subject to the following conditions:
12706f2543Smrg
13706f2543Smrg   The above copyright notice and this permission notice shall be
14706f2543Smrg   included in all copies or substantial portions of the Software.
15706f2543Smrg
16706f2543Smrg   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17706f2543Smrg   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18706f2543Smrg   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19706f2543Smrg   NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
20706f2543Smrg   HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21706f2543Smrg   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22706f2543Smrg   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23706f2543Smrg   DEALINGS IN THE SOFTWARE.
24706f2543Smrg
25706f2543Smrg   Except as contained in this notice, the name(s) of the above
26706f2543Smrg   copyright holders shall not be used in advertising or otherwise to
27706f2543Smrg   promote the sale, use or other dealings in this Software without
28706f2543Smrg   prior written authorization. */
29706f2543Smrg
30706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
31706f2543Smrg#include <dix-config.h>
32706f2543Smrg#endif
33706f2543Smrg
34706f2543Smrg#include "x-hook.h"
35706f2543Smrg#include <stdlib.h>
36706f2543Smrg#include <assert.h>
37706f2543Smrg#include "os.h"
38706f2543Smrg
39706f2543Smrg#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d))
40706f2543Smrg#define CELL_FREE(c)  X_PFX (list_free_1) (c)
41706f2543Smrg#define CELL_FUN(c)   ((x_hook_function *) ((c)->next))
42706f2543Smrg#define CELL_DATA(c)  ((c)->data)
43706f2543Smrg
44706f2543SmrgX_EXTERN x_list *
45706f2543SmrgX_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data)
46706f2543Smrg{
47706f2543Smrg    return X_PFX (list_prepend) (lst, CELL_NEW (fun, data));
48706f2543Smrg}
49706f2543Smrg
50706f2543SmrgX_EXTERN x_list *
51706f2543SmrgX_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data)
52706f2543Smrg{
53706f2543Smrg    x_list *node, *cell;
54706f2543Smrg    x_list *to_delete = NULL;
55706f2543Smrg
56706f2543Smrg    for (node = lst; node != NULL; node = node->next)
57706f2543Smrg    {
58706f2543Smrg	cell = node->data;
59706f2543Smrg	if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data)
60706f2543Smrg	    to_delete = X_PFX (list_prepend) (to_delete, cell);
61706f2543Smrg    }
62706f2543Smrg
63706f2543Smrg    for (node = to_delete; node != NULL; node = node->next)
64706f2543Smrg    {
65706f2543Smrg	cell = node->data;
66706f2543Smrg	lst = X_PFX (list_remove) (lst, cell);
67706f2543Smrg	CELL_FREE (cell);
68706f2543Smrg    }
69706f2543Smrg
70706f2543Smrg    X_PFX (list_free) (to_delete);
71706f2543Smrg    return lst;
72706f2543Smrg}
73706f2543Smrg
74706f2543SmrgX_EXTERN void
75706f2543SmrgX_PFX (hook_run) (x_list *lst, void *arg)
76706f2543Smrg{
77706f2543Smrg    x_list *node, *cell;
78706f2543Smrg    x_hook_function **fun;
79706f2543Smrg    void **data;
80706f2543Smrg    int length, i;
81706f2543Smrg
82706f2543Smrg    if(!lst)
83706f2543Smrg        return;
84706f2543Smrg
85706f2543Smrg    length = X_PFX (list_length) (lst);
86706f2543Smrg    fun = malloc(sizeof (x_hook_function *) * length);
87706f2543Smrg    data = malloc(sizeof (void *) * length);
88706f2543Smrg
89706f2543Smrg    if(!fun || !data) {
90706f2543Smrg        FatalError("Failed to allocate memory in %s\n", __func__);
91706f2543Smrg    }
92706f2543Smrg
93706f2543Smrg    for (i = 0, node = lst; node != NULL; node = node->next, i++)
94706f2543Smrg    {
95706f2543Smrg	cell = node->data;
96706f2543Smrg	fun[i] = CELL_FUN (cell);
97706f2543Smrg	data[i] = CELL_DATA (cell);
98706f2543Smrg    }
99706f2543Smrg
100706f2543Smrg    for (i = 0; i < length; i++)
101706f2543Smrg    {
102706f2543Smrg	(*fun[i]) (arg, data[i]);
103706f2543Smrg    }
104706f2543Smrg
105706f2543Smrg    free(fun);
106706f2543Smrg    free(data);
107706f2543Smrg}
108706f2543Smrg
109706f2543SmrgX_EXTERN void
110706f2543SmrgX_PFX (hook_free) (x_list *lst)
111706f2543Smrg{
112706f2543Smrg    x_list *node;
113706f2543Smrg
114706f2543Smrg    for (node = lst; node != NULL; node = node->next)
115706f2543Smrg    {
116706f2543Smrg	CELL_FREE (node->data);
117706f2543Smrg    }
118706f2543Smrg
119706f2543Smrg    X_PFX (list_free) (lst);
120706f2543Smrg}
121