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