Mercurial > kinput2.yaz
comparison lib/asyncerr.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: asyncerr.c,v 1.6 1994/08/08 01:20:52 ishisone Exp $"; | |
3 #endif | |
4 /* | |
5 * Copyright (C) 1992, 1994 Software Research Associates, Inc. | |
6 * | |
7 * Permission to use, copy, modify, and distribute this software and its | |
8 * documentation for any purpose and without fee is hereby granted, provided | |
9 * that the above copyright notice appear in all copies and that both that | |
10 * copyright notice and this permission notice appear in supporting | |
11 * documentation, and that the name of Software Research Associates not be | |
12 * used in advertising or publicity pertaining to distribution of the | |
13 * software without specific, written prior permission. Software Research | |
14 * Associates makes no representations about the suitability of this software | |
15 * for any purpose. It is provided "as is" without express or implied | |
16 * warranty. | |
17 * | |
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan | |
19 */ | |
20 | |
21 /* | |
22 * X asyncronous error handler | |
23 */ | |
24 | |
25 #include <X11/Xlib.h> | |
26 #include <X11/Xfuncproto.h> | |
27 #include "AsyncErr.h" | |
28 | |
29 #ifdef __STDC__ | |
30 #include <stdlib.h> | |
31 #else | |
32 extern char *malloc(); | |
33 #endif | |
34 | |
35 #ifndef NULL | |
36 #define NULL 0 | |
37 #endif | |
38 | |
39 #undef XSetErrorHandler | |
40 | |
41 typedef struct fe_errdesc_ { | |
42 struct fe_errdesc_ *prev; | |
43 struct fe_errdesc_ *next; | |
44 Display *dpy; | |
45 unsigned long from; /* range of the sequence numbers */ | |
46 unsigned long to; /* which this handler covers */ | |
47 int (*handler)(); /* async handler */ | |
48 void (*destroy)(); | |
49 XPointer client_data; | |
50 } ErrDesc; | |
51 | |
52 static ErrDesc esentinel = { | |
53 &esentinel, | |
54 &esentinel, | |
55 }; | |
56 | |
57 #define EHEAD (esentinel.next) | |
58 #define ETAIL (esentinel.prev) | |
59 #define EEND(p) ((p) == &esentinel) | |
60 | |
61 static int (*original_handler)(); | |
62 | |
63 /* | |
64 * Some useful handlers | |
65 */ | |
66 | |
67 /* ARGSUSED */ | |
68 static int | |
69 ignoreErrors(dpy, eev, cldata) | |
70 Display *dpy; | |
71 XErrorEvent *eev; | |
72 XPointer cldata; | |
73 { | |
74 /* | |
75 * Just ignore any errors. | |
76 */ | |
77 return 0; | |
78 } | |
79 | |
80 /* ARGSUSED */ | |
81 static int | |
82 recordErrors(dpy, eev, cldata) | |
83 Display *dpy; | |
84 XErrorEvent *eev; | |
85 XPointer cldata; | |
86 { | |
87 /* | |
88 * Record the type of the error. | |
89 * It assumes that the client data is a pointer to | |
90 * an unsigned long int. If error occurs, it does: | |
91 * + if the error code is less than 32, set the 'error code'th bit. | |
92 * + otherwise (i.e. extension defined error) set the bit 0. | |
93 */ | |
94 unsigned long *errorbitsp = (unsigned long *)cldata; | |
95 | |
96 if (eev->error_code < 32) { | |
97 *errorbitsp |= (1 << eev->error_code); | |
98 } else { | |
99 /* other errors */ | |
100 *errorbitsp |= 1; | |
101 } | |
102 | |
103 /* don't invoke global handler */ | |
104 return 0; | |
105 } | |
106 | |
107 static ErrDesc * | |
108 newErrDesc() | |
109 { | |
110 return (ErrDesc *)malloc(sizeof(ErrDesc)); | |
111 } | |
112 | |
113 static void | |
114 eremove(edp) | |
115 ErrDesc *edp; | |
116 { | |
117 edp->prev->next = edp->next; | |
118 edp->next->prev = edp->prev; | |
119 } | |
120 | |
121 static void | |
122 eappend(edp) | |
123 ErrDesc *edp; | |
124 { | |
125 edp->prev = esentinel.prev; | |
126 edp->next = &esentinel; | |
127 (esentinel.prev)->next = edp; | |
128 esentinel.prev = edp; | |
129 } | |
130 | |
131 static void | |
132 removeHandler(edp) | |
133 ErrDesc *edp; | |
134 { | |
135 if (edp->destroy != NULL) (*edp->destroy)(edp->dpy, edp->client_data); | |
136 eremove(edp); | |
137 (void)free((char *)edp); | |
138 } | |
139 | |
140 static int | |
141 callHandlers(dpy, eev) | |
142 Display *dpy; | |
143 XErrorEvent *eev; | |
144 { | |
145 ErrDesc *edp = EHEAD; | |
146 int found = 0; | |
147 int call_original = 0; | |
148 | |
149 while (!EEND(edp)) { | |
150 if (edp->dpy == dpy && edp->from <= eev->serial && | |
151 (eev->serial < edp->to || edp->from == edp->to)) { | |
152 found = 1; | |
153 if ((*edp->handler)(dpy, eev, edp->client_data)) call_original = 1; | |
154 } | |
155 edp = edp->next; | |
156 } | |
157 return !found || call_original; | |
158 } | |
159 | |
160 static void | |
161 removeHandlers(dpy) | |
162 Display *dpy; | |
163 { | |
164 /* | |
165 * Remove obsolete (out of date) handlers. | |
166 */ | |
167 ErrDesc *edp = EHEAD; | |
168 unsigned long last = LastKnownRequestProcessed(dpy); | |
169 | |
170 while (!EEND(edp)) { | |
171 ErrDesc *next = edp->next; | |
172 | |
173 if (edp->dpy == dpy && edp->to <= last && edp->from != edp->to) { | |
174 removeHandler(edp); | |
175 } | |
176 edp = next; | |
177 } | |
178 } | |
179 | |
180 /* | |
181 * public functions | |
182 */ | |
183 | |
184 int | |
185 XAEHandler(dpy, eev) | |
186 Display *dpy; | |
187 XErrorEvent *eev; | |
188 { | |
189 if (callHandlers(dpy, eev) && original_handler != NULL) { | |
190 (void)original_handler(dpy, eev); | |
191 } | |
192 removeHandlers(dpy); | |
193 return 0; /* for lint */ | |
194 } | |
195 | |
196 void | |
197 XAEInit() | |
198 { | |
199 int (*oldhandler)() = XSetErrorHandler(XAEHandler); | |
200 | |
201 if (oldhandler != XAEHandler) original_handler = oldhandler; | |
202 } | |
203 | |
204 XErrorHandler | |
205 XAESetErrorHandler(handler) | |
206 XErrorHandler handler; | |
207 { | |
208 int (*oldhandler)(); | |
209 | |
210 oldhandler = original_handler; | |
211 original_handler = handler; | |
212 return oldhandler; | |
213 } | |
214 | |
215 XAEHandle | |
216 XAESet(dpy, handler, destroy, client_data) | |
217 Display *dpy; | |
218 int (*handler)(); | |
219 void (*destroy)(); | |
220 XPointer client_data; | |
221 { | |
222 ErrDesc *e; | |
223 | |
224 /* | |
225 * First, remove out-of-date handlers. | |
226 */ | |
227 removeHandlers(dpy); | |
228 | |
229 /* | |
230 * Allocate new ErrDesc structure. | |
231 */ | |
232 e = newErrDesc(); | |
233 if (e == NULL) return NULL; | |
234 | |
235 e->dpy = dpy; | |
236 e->from = NextRequest(dpy); | |
237 e->to = e->from; | |
238 e->handler = handler; | |
239 e->destroy = destroy; | |
240 e->client_data = client_data; | |
241 | |
242 eappend(e); | |
243 | |
244 return e; | |
245 } | |
246 | |
247 void | |
248 XAEUnset(handle) | |
249 XAEHandle handle; | |
250 { | |
251 Display *dpy = handle->dpy; | |
252 | |
253 if (handle != NULL && handle->from == handle->to) { | |
254 handle->to = NextRequest(dpy); | |
255 if (handle->to <= handle->from) removeHandler(handle); | |
256 } | |
257 removeHandlers(dpy); | |
258 } | |
259 | |
260 XAEHandle | |
261 XAESetIgnoreErrors(dpy) | |
262 Display *dpy; | |
263 { | |
264 return XAESet(dpy, ignoreErrors, (void (*)())NULL, (XPointer)NULL); | |
265 } | |
266 | |
267 XAEHandle | |
268 XAESetRecordErrors(dpy, errorbitsp) | |
269 Display *dpy; | |
270 unsigned long *errorbitsp; | |
271 { | |
272 *errorbitsp = 0L; /* clear all bits */ | |
273 return XAESet(dpy, recordErrors, | |
274 (void (*)())NULL, (XPointer)errorbitsp); | |
275 } |