1 | /* GLIB - Library of useful routines for C programming |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
3 | * |
4 | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2.1 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | /* |
21 | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
22 | * file for a list of people on the GLib Team. See the ChangeLog |
23 | * files for a list of changes. These files are distributed with |
24 | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
25 | */ |
26 | |
27 | #ifndef __G_HOOK_H__ |
28 | #define __G_HOOK_H__ |
29 | |
30 | #if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) |
31 | #error "Only <glib.h> can be included directly." |
32 | #endif |
33 | |
34 | #include <glib/gmem.h> |
35 | |
36 | G_BEGIN_DECLS |
37 | |
38 | |
39 | /* --- typedefs --- */ |
40 | typedef struct _GHook GHook; |
41 | typedef struct _GHookList GHookList; |
42 | |
43 | typedef gint (*GHookCompareFunc) (GHook *new_hook, |
44 | GHook *sibling); |
45 | typedef gboolean (*GHookFindFunc) (GHook *hook, |
46 | gpointer data); |
47 | typedef void (*GHookMarshaller) (GHook *hook, |
48 | gpointer marshal_data); |
49 | typedef gboolean (*GHookCheckMarshaller) (GHook *hook, |
50 | gpointer marshal_data); |
51 | typedef void (*GHookFunc) (gpointer data); |
52 | typedef gboolean (*GHookCheckFunc) (gpointer data); |
53 | typedef void (*GHookFinalizeFunc) (GHookList *hook_list, |
54 | GHook *hook); |
55 | typedef enum |
56 | { |
57 | G_HOOK_FLAG_ACTIVE = 1 << 0, |
58 | G_HOOK_FLAG_IN_CALL = 1 << 1, |
59 | G_HOOK_FLAG_MASK = 0x0f |
60 | } GHookFlagMask; |
61 | #define G_HOOK_FLAG_USER_SHIFT (4) |
62 | |
63 | |
64 | /* --- structures --- */ |
65 | struct _GHookList |
66 | { |
67 | gulong seq_id; |
68 | guint hook_size : 16; |
69 | guint is_setup : 1; |
70 | GHook *hooks; |
71 | gpointer dummy3; |
72 | GHookFinalizeFunc finalize_hook; |
73 | gpointer dummy[2]; |
74 | }; |
75 | struct _GHook |
76 | { |
77 | gpointer data; |
78 | GHook *next; |
79 | GHook *prev; |
80 | guint ref_count; |
81 | gulong hook_id; |
82 | guint flags; |
83 | gpointer func; |
84 | GDestroyNotify destroy; |
85 | }; |
86 | |
87 | |
88 | /* --- macros --- */ |
89 | #define G_HOOK(hook) ((GHook*) (hook)) |
90 | #define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags) |
91 | #define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \ |
92 | G_HOOK_FLAG_ACTIVE) != 0) |
93 | #define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \ |
94 | G_HOOK_FLAG_IN_CALL) != 0) |
95 | #define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \ |
96 | (G_HOOK_FLAGS (hook) & \ |
97 | G_HOOK_FLAG_ACTIVE)) |
98 | #define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \ |
99 | G_HOOK (hook)->prev == NULL && \ |
100 | G_HOOK (hook)->hook_id == 0 && \ |
101 | G_HOOK (hook)->ref_count == 0) |
102 | |
103 | |
104 | /* --- prototypes --- */ |
105 | /* callback maintenance functions */ |
106 | GLIB_AVAILABLE_IN_ALL |
107 | void g_hook_list_init (GHookList *hook_list, |
108 | guint hook_size); |
109 | GLIB_AVAILABLE_IN_ALL |
110 | void g_hook_list_clear (GHookList *hook_list); |
111 | GLIB_AVAILABLE_IN_ALL |
112 | GHook* g_hook_alloc (GHookList *hook_list); |
113 | GLIB_AVAILABLE_IN_ALL |
114 | void g_hook_free (GHookList *hook_list, |
115 | GHook *hook); |
116 | GLIB_AVAILABLE_IN_ALL |
117 | GHook * g_hook_ref (GHookList *hook_list, |
118 | GHook *hook); |
119 | GLIB_AVAILABLE_IN_ALL |
120 | void g_hook_unref (GHookList *hook_list, |
121 | GHook *hook); |
122 | GLIB_AVAILABLE_IN_ALL |
123 | gboolean g_hook_destroy (GHookList *hook_list, |
124 | gulong hook_id); |
125 | GLIB_AVAILABLE_IN_ALL |
126 | void g_hook_destroy_link (GHookList *hook_list, |
127 | GHook *hook); |
128 | GLIB_AVAILABLE_IN_ALL |
129 | void g_hook_prepend (GHookList *hook_list, |
130 | GHook *hook); |
131 | GLIB_AVAILABLE_IN_ALL |
132 | void g_hook_insert_before (GHookList *hook_list, |
133 | GHook *sibling, |
134 | GHook *hook); |
135 | GLIB_AVAILABLE_IN_ALL |
136 | void g_hook_insert_sorted (GHookList *hook_list, |
137 | GHook *hook, |
138 | GHookCompareFunc func); |
139 | GLIB_AVAILABLE_IN_ALL |
140 | GHook* g_hook_get (GHookList *hook_list, |
141 | gulong hook_id); |
142 | GLIB_AVAILABLE_IN_ALL |
143 | GHook* g_hook_find (GHookList *hook_list, |
144 | gboolean need_valids, |
145 | GHookFindFunc func, |
146 | gpointer data); |
147 | GLIB_AVAILABLE_IN_ALL |
148 | GHook* g_hook_find_data (GHookList *hook_list, |
149 | gboolean need_valids, |
150 | gpointer data); |
151 | GLIB_AVAILABLE_IN_ALL |
152 | GHook* g_hook_find_func (GHookList *hook_list, |
153 | gboolean need_valids, |
154 | gpointer func); |
155 | GLIB_AVAILABLE_IN_ALL |
156 | GHook* g_hook_find_func_data (GHookList *hook_list, |
157 | gboolean need_valids, |
158 | gpointer func, |
159 | gpointer data); |
160 | /* return the first valid hook, and increment its reference count */ |
161 | GLIB_AVAILABLE_IN_ALL |
162 | GHook* g_hook_first_valid (GHookList *hook_list, |
163 | gboolean may_be_in_call); |
164 | /* return the next valid hook with incremented reference count, and |
165 | * decrement the reference count of the original hook |
166 | */ |
167 | GLIB_AVAILABLE_IN_ALL |
168 | GHook* g_hook_next_valid (GHookList *hook_list, |
169 | GHook *hook, |
170 | gboolean may_be_in_call); |
171 | /* GHookCompareFunc implementation to insert hooks sorted by their id */ |
172 | GLIB_AVAILABLE_IN_ALL |
173 | gint g_hook_compare_ids (GHook *new_hook, |
174 | GHook *sibling); |
175 | /* convenience macros */ |
176 | #define g_hook_append( hook_list, hook ) \ |
177 | g_hook_insert_before ((hook_list), NULL, (hook)) |
178 | /* invoke all valid hooks with the (*GHookFunc) signature. |
179 | */ |
180 | GLIB_AVAILABLE_IN_ALL |
181 | void g_hook_list_invoke (GHookList *hook_list, |
182 | gboolean may_recurse); |
183 | /* invoke all valid hooks with the (*GHookCheckFunc) signature, |
184 | * and destroy the hook if FALSE is returned. |
185 | */ |
186 | GLIB_AVAILABLE_IN_ALL |
187 | void g_hook_list_invoke_check (GHookList *hook_list, |
188 | gboolean may_recurse); |
189 | /* invoke a marshaller on all valid hooks. |
190 | */ |
191 | GLIB_AVAILABLE_IN_ALL |
192 | void g_hook_list_marshal (GHookList *hook_list, |
193 | gboolean may_recurse, |
194 | GHookMarshaller marshaller, |
195 | gpointer marshal_data); |
196 | GLIB_AVAILABLE_IN_ALL |
197 | void g_hook_list_marshal_check (GHookList *hook_list, |
198 | gboolean may_recurse, |
199 | GHookCheckMarshaller marshaller, |
200 | gpointer marshal_data); |
201 | |
202 | G_END_DECLS |
203 | |
204 | #endif /* __G_HOOK_H__ */ |
205 | |