1 /* GLib Extra - Tentative GLib code and GLib supplements
2 * Copyright (C) 1997-2002 Tim Janik
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19 // FIXME: #define _GNU_SOURCE
20 #include <string.h>
21 #include "glib-extra.h"
22
23 /* --- GLib main loop reentrant signal queue --- */
24
25 static gboolean g_usignal_prepare (GSource *source,
26 gint *timeout);
27 static gboolean g_usignal_check (GSource *source);
28 static gboolean g_usignal_dispatch (GSource *source,
29 GSourceFunc callback,
30 gpointer user_data);
31
32 static GSourceFuncs usignal_funcs = {
33 g_usignal_prepare,
34 g_usignal_check,
35 g_usignal_dispatch,
36 0, // g_free, ?
37 0,
38 0
39 };
40 static guint32 usignals_notified[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
41
42 typedef struct _GUSignalSource
43 {
44 GSource source;
45 guint8 index;
46 guint8 shift;
47 GUSignalFunc callback;
48 gpointer data;
49 } GUSignalSource;
50
51 static gboolean
g_usignal_prepare(GSource * source,gint * timeout)52 g_usignal_prepare (GSource *source,
53 gint *timeout)
54 {
55 GUSignalSource *usignal_source = (GUSignalSource *)source;
56
57 return usignals_notified[usignal_source->index] & (1 << usignal_source->shift);
58 }
59
60 static gboolean
g_usignal_check(GSource * source)61 g_usignal_check (GSource *source)
62 {
63 GUSignalSource *usignal_source = (GUSignalSource *)source;
64
65 return usignals_notified[usignal_source->index] & (1 << usignal_source->shift);
66 }
67
68 static gboolean
g_usignal_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)69 g_usignal_dispatch (GSource *source,
70 GSourceFunc callback,
71 gpointer user_data)
72 {
73 GUSignalSource *usignal_source = (GUSignalSource *)source;
74
75 usignals_notified[usignal_source->index] &= ~(1 << usignal_source->shift);
76
77 //return usignal_data->callback (-128 + usignal_data->index * 32 + usignal_data->shift, user_data);
78 return usignal_source->callback (-128 + usignal_source->index * 32 + usignal_source->shift, usignal_source->data);
79 }
80
81 guint
g_usignal_add(gint8 usignal,GUSignalFunc function,gpointer data)82 g_usignal_add (gint8 usignal,
83 GUSignalFunc function,
84 gpointer data)
85 {
86 return g_usignal_add_full (G_PRIORITY_DEFAULT, usignal, function, data, NULL);
87 }
88
89 guint
g_usignal_add_full(gint priority,gint8 usignal,GUSignalFunc function,gpointer data,GDestroyNotify destroy)90 g_usignal_add_full (gint priority,
91 gint8 usignal,
92 GUSignalFunc function,
93 gpointer data,
94 GDestroyNotify destroy)
95 {
96 guint s = 128 + usignal;
97
98 g_return_val_if_fail (function != NULL, 0);
99
100
101 GSource *source = g_source_new (&usignal_funcs, sizeof (GUSignalSource));
102 GUSignalSource *usignal_source = (GUSignalSource *) source;
103 usignal_source->index = s / 32;
104 usignal_source->shift = s % 32;
105 usignal_source->callback = function;
106 usignal_source->data = data;
107 /*
108 g_source_set_callback (source, GSourceFunc func,
109 gpointer data,
110 GDestroyNotify notify);
111 */
112 return g_source_attach (source, NULL);
113 //return g_source_add (priority, TRUE, &usignal_funcs, usignal_data, data, destroy);
114 }
115
116 void
g_usignal_notify(gint8 usignal)117 g_usignal_notify (gint8 usignal)
118 {
119 guint index, shift;
120 guint s = 128 + usignal;
121
122 index = s / 32;
123 shift = s % 32;
124
125 usignals_notified[index] |= 1 << shift;
126 }
127