Mercurial > kinput2.yaz
comparison lib/dispatch.c @ 0:92745d501b9a
initial import from kinput2-v3.1
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 04:44:30 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:92745d501b9a |
---|---|
1 #ifndef lint | |
2 static char *rcsid = "$Id: dispatch.c,v 1.14 1994/05/31 07:48:42 ishisone Rel $"; | |
3 #endif | |
4 | |
5 /* | |
6 * a very simple event dispatch library for non-widget windows | |
7 * | |
8 * 'non-widget window' means windows that have no associated widget, | |
9 * e.g. windows created by Xlib directly. | |
10 */ | |
11 | |
12 /* | |
13 * Copyright (c) 1990 Software Research Associates, Inc. | |
14 * | |
15 * Permission to use, copy, modify, and distribute this software and its | |
16 * documentation for any purpose and without fee is hereby granted, provided | |
17 * that the above copyright notice appear in all copies and that both that | |
18 * copyright notice and this permission notice appear in supporting | |
19 * documentation, and that the name of Software Research Associates not be | |
20 * used in advertising or publicity pertaining to distribution of the | |
21 * software without specific, written prior permission. Software Research | |
22 * Associates makes no representations about the suitability of this software | |
23 * for any purpose. It is provided "as is" without express or implied | |
24 * warranty. | |
25 * | |
26 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
27 */ | |
28 | |
29 #include <X11/Intrinsic.h> | |
30 #include "MyDispatch.h" | |
31 #include "AsyncErr.h" | |
32 | |
33 #define DEBUG_VAR debug_dispatch | |
34 #include "DebugPrint.h" | |
35 | |
36 typedef struct _handler_ { | |
37 int type; /* event type */ | |
38 unsigned long mask; /* event mask */ | |
39 void (*handler)(); | |
40 XtPointer data; | |
41 struct _handler_ *next; | |
42 } HandlerRec; | |
43 | |
44 typedef struct { | |
45 Boolean dispatching; /* now dispatching */ | |
46 Boolean toberemoved; /* this list is to be removed later */ | |
47 unsigned long mask; /* event mask */ | |
48 HandlerRec *handlers; | |
49 } WindowRec; | |
50 | |
51 static int Initialized = 0; | |
52 static XContext Context; | |
53 | |
54 static void | |
55 initialize() | |
56 { | |
57 Context = XUniqueContext(); | |
58 Initialized = 1; | |
59 } | |
60 | |
61 static void | |
62 resetEventMask(dpy, window, wp) | |
63 Display *dpy; | |
64 Window window; | |
65 WindowRec *wp; | |
66 { | |
67 register HandlerRec *hp = wp->handlers; | |
68 register unsigned long mask = 0L; | |
69 | |
70 while (hp != NULL) { | |
71 mask |= hp->mask; | |
72 hp = hp->next; | |
73 } | |
74 | |
75 if (mask != wp->mask) { | |
76 XAEHandle h = XAESetIgnoreErrors(dpy); /* keep the operation safe */ | |
77 XSelectInput(dpy, window, mask); | |
78 XAEUnset(h); | |
79 wp->mask = mask; | |
80 } | |
81 } | |
82 | |
83 static void | |
84 removeAll(dpy, window, wp) | |
85 Display *dpy; | |
86 Window window; | |
87 WindowRec *wp; | |
88 { | |
89 register HandlerRec *hp = wp->handlers; | |
90 | |
91 while (hp != NULL) { | |
92 register HandlerRec *hp0 = hp; | |
93 hp = hp->next; | |
94 XtFree((char *)hp0); | |
95 } | |
96 | |
97 if (wp->mask != 0L) { | |
98 XAEHandle h = XAESetIgnoreErrors(dpy); | |
99 | |
100 /* keep it safe (because the window might not exist any more) */ | |
101 XSelectInput(dpy, window, 0L); | |
102 XAEUnset(h); | |
103 } | |
104 | |
105 XtFree((char *)wp); | |
106 (void)XDeleteContext(dpy, window, Context); | |
107 } | |
108 | |
109 static void | |
110 doDispatch(event, list) | |
111 XEvent *event; | |
112 register HandlerRec *list; | |
113 { | |
114 void (*handler)(); | |
115 XtPointer data; | |
116 register int type = event->type; | |
117 | |
118 /* | |
119 * we must be careful here. the invoked handler might remove | |
120 * itself, or remove other handler to be invoked next. | |
121 * so we use this somewhat strange recursive call. | |
122 */ | |
123 while (list != NULL) { | |
124 if (list->type == type) { | |
125 handler = list->handler; | |
126 data = list->data; | |
127 doDispatch(event, list->next); | |
128 (*handler)(event, data); | |
129 return; | |
130 } | |
131 list = list->next; | |
132 } | |
133 } | |
134 | |
135 void | |
136 MyDispatchEvent(event) | |
137 XEvent *event; | |
138 { | |
139 caddr_t data; | |
140 | |
141 if (!Initialized) initialize(); | |
142 | |
143 if (!XFindContext(event->xany.display, event->xany.window, | |
144 Context, &data)) { | |
145 WindowRec *wrec = (WindowRec *)data; | |
146 | |
147 wrec->dispatching = True; | |
148 wrec->toberemoved = False; | |
149 | |
150 doDispatch(event, wrec->handlers); | |
151 | |
152 wrec->dispatching = False; | |
153 if (wrec->toberemoved) { | |
154 removeAll(event->xany.display, event->xany.window, wrec); | |
155 } | |
156 } | |
157 } | |
158 | |
159 void | |
160 MyAddEventHandler(dpy, window, type, mask, func, data) | |
161 Display *dpy; | |
162 Window window; | |
163 int type; | |
164 unsigned long mask; | |
165 void (*func)(); | |
166 XtPointer data; | |
167 { | |
168 WindowRec *wp; | |
169 HandlerRec *hp; | |
170 caddr_t cdata; | |
171 | |
172 TRACE(("MyAddEventHandler(window=%08lx,type=%d)\n", window, type)); | |
173 if (!Initialized) initialize(); | |
174 | |
175 hp = XtNew(HandlerRec); | |
176 hp->type = type; | |
177 hp->mask = mask; | |
178 hp->handler = func; | |
179 hp->data = data; | |
180 hp->next = NULL; | |
181 | |
182 if (!XFindContext(dpy, window, Context, &cdata)) { | |
183 wp = (WindowRec *)cdata; | |
184 hp->next = wp->handlers; | |
185 wp->handlers = hp; | |
186 } else { | |
187 wp = XtNew(WindowRec); | |
188 wp->mask = 0L; | |
189 wp->dispatching = False; | |
190 wp->handlers = hp; | |
191 (void)XSaveContext(dpy, window, Context, (caddr_t)wp); | |
192 } | |
193 resetEventMask(dpy, window, wp); | |
194 } | |
195 | |
196 void | |
197 MyRemoveEventHandler(dpy, window, type, func, data) | |
198 Display *dpy; | |
199 Window window; | |
200 int type; | |
201 void (*func)(); | |
202 XtPointer data; | |
203 { | |
204 caddr_t cdata; | |
205 WindowRec *wp; | |
206 HandlerRec *hp, *hp0; | |
207 | |
208 TRACE(("MyRemoveEventHandler(window=%08lx,type=%d)\n", window, type)); | |
209 if (!Initialized) initialize(); | |
210 if (XFindContext(dpy, window, Context, &cdata) || cdata == NULL) return; | |
211 | |
212 wp = (WindowRec *)cdata; | |
213 hp0 = NULL; | |
214 hp = wp->handlers; | |
215 | |
216 while (hp != NULL) { | |
217 if (hp->type == type && hp->handler == func && hp->data == data) { | |
218 HandlerRec *tmp = hp; | |
219 | |
220 hp = hp->next; | |
221 if (hp0 == NULL) { | |
222 wp->handlers = hp; | |
223 } else { | |
224 hp0->next = hp; | |
225 } | |
226 XtFree((char *)tmp); | |
227 } else { | |
228 hp0 = hp; | |
229 hp = hp->next; | |
230 } | |
231 } | |
232 | |
233 resetEventMask(dpy, window, wp); | |
234 | |
235 if (wp->handlers == NULL) { | |
236 if (wp->dispatching) { | |
237 /* now dispatching. we just mark it to be removed later. */ | |
238 wp->toberemoved = True; | |
239 } else { | |
240 XtFree((char *)wp); | |
241 (void)XDeleteContext(dpy, window, Context); | |
242 } | |
243 } | |
244 } | |
245 | |
246 void | |
247 MyRemoveAllEventHandler(dpy, window) | |
248 Display *dpy; | |
249 Window window; | |
250 { | |
251 caddr_t cdata; | |
252 WindowRec *wp; | |
253 | |
254 TRACE(("MyRemoveAllEventHandler(window=%08lx)\n", window)); | |
255 if (!Initialized) initialize(); | |
256 | |
257 if (XFindContext(dpy, window, Context, &cdata) || cdata == NULL) return; | |
258 | |
259 wp = (WindowRec *)cdata; | |
260 | |
261 if (wp->dispatching) { | |
262 /* now dispatching. we just mark it to be removed later. */ | |
263 wp->toberemoved = True; | |
264 return; | |
265 } else { | |
266 removeAll(dpy, window, wp); | |
267 } | |
268 } |