InitExt.c revision 7d2c738b
1/* 2 3Copyright 1987, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <X11/Xlibint.h> 33#include <X11/Xos.h> 34#include <stdio.h> 35 36/* The X11 protocol spec reserves events 64 through 127 for extensions */ 37#ifndef LastExtensionEvent 38#define LastExtensionEvent 127 39#endif 40 41/* The X11 protocol spec reserves requests 128 through 255 for extensions */ 42#ifndef LastExtensionRequest 43#define FirstExtensionRequest 128 44#define LastExtensionRequest 255 45#endif 46 47 48/* 49 * This routine is used to link a extension in so it will be called 50 * at appropriate times. 51 */ 52 53XExtCodes *XInitExtension ( 54 Display *dpy, 55 _Xconst char *name) 56{ 57 XExtCodes codes; /* temp. place for extension information. */ 58 register _XExtension *ext;/* need a place to build it all */ 59 if (!XQueryExtension(dpy, name, 60 &codes.major_opcode, &codes.first_event, 61 &codes.first_error)) return (NULL); 62 63 LockDisplay (dpy); 64 if (! (ext = Xcalloc (1, sizeof (_XExtension))) || 65 ! (ext->name = strdup(name))) { 66 Xfree(ext); 67 UnlockDisplay(dpy); 68 return (XExtCodes *) NULL; 69 } 70 codes.extension = dpy->ext_number++; 71 ext->codes = codes; 72 73 /* chain it onto the display list */ 74 ext->next = dpy->ext_procs; 75 dpy->ext_procs = ext; 76 UnlockDisplay (dpy); 77 78 return (&ext->codes); /* tell him which extension */ 79} 80 81XExtCodes *XAddExtension (Display *dpy) 82{ 83 register _XExtension *ext; 84 85 LockDisplay (dpy); 86 if (! (ext = Xcalloc (1, sizeof (_XExtension)))) { 87 UnlockDisplay(dpy); 88 return (XExtCodes *) NULL; 89 } 90 ext->codes.extension = dpy->ext_number++; 91 92 /* chain it onto the display list */ 93 ext->next = dpy->ext_procs; 94 dpy->ext_procs = ext; 95 UnlockDisplay (dpy); 96 97 return (&ext->codes); /* tell him which extension */ 98} 99 100static _XExtension *XLookupExtension ( 101 register Display *dpy, /* display */ 102 register int extension) /* extension number */ 103{ 104 register _XExtension *ext; 105 for (ext = dpy->ext_procs; ext; ext = ext->next) 106 if (ext->codes.extension == extension) return (ext); 107 return (NULL); 108} 109 110XExtData **XEHeadOfExtensionList(XEDataObject object) 111{ 112 return *(XExtData ***)&object; 113} 114 115int 116XAddToExtensionList( 117 XExtData **structure, 118 XExtData *ext_data) 119{ 120 ext_data->next = *structure; 121 *structure = ext_data; 122 return 1; 123} 124 125XExtData *XFindOnExtensionList( 126 XExtData **structure, 127 int number) 128{ 129 XExtData *ext; 130 131 ext = *structure; 132 while (ext && (ext->number != number)) 133 ext = ext->next; 134 return ext; 135} 136 137/* 138 * Routines to hang procs on the extension structure. 139 */ 140CreateGCType XESetCreateGC( 141 Display *dpy, /* display */ 142 int extension, /* extension number */ 143 CreateGCType proc) /* routine to call when GC created */ 144{ 145 register _XExtension *e; /* for lookup of extension */ 146 register CreateGCType oldproc; 147 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 148 LockDisplay(dpy); 149 oldproc = e->create_GC; 150 e->create_GC = proc; 151 UnlockDisplay(dpy); 152 return (CreateGCType)oldproc; 153} 154 155CopyGCType XESetCopyGC( 156 Display *dpy, /* display */ 157 int extension, /* extension number */ 158 CopyGCType proc) /* routine to call when GC copied */ 159{ 160 register _XExtension *e; /* for lookup of extension */ 161 register CopyGCType oldproc; 162 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 163 LockDisplay(dpy); 164 oldproc = e->copy_GC; 165 e->copy_GC = proc; 166 UnlockDisplay(dpy); 167 return (CopyGCType)oldproc; 168} 169 170FlushGCType XESetFlushGC( 171 Display *dpy, /* display */ 172 int extension, /* extension number */ 173 FlushGCType proc) /* routine to call when GC copied */ 174{ 175 register _XExtension *e; /* for lookup of extension */ 176 register FlushGCType oldproc; 177 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 178 LockDisplay(dpy); 179 oldproc = e->flush_GC; 180 e->flush_GC = proc; 181 UnlockDisplay(dpy); 182 return (FlushGCType)oldproc; 183} 184 185FreeGCType XESetFreeGC( 186 Display *dpy, /* display */ 187 int extension, /* extension number */ 188 FreeGCType proc) /* routine to call when GC freed */ 189{ 190 register _XExtension *e; /* for lookup of extension */ 191 register FreeGCType oldproc; 192 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 193 LockDisplay(dpy); 194 oldproc = e->free_GC; 195 e->free_GC = proc; 196 UnlockDisplay(dpy); 197 return (FreeGCType)oldproc; 198} 199 200CreateFontType XESetCreateFont( 201 Display *dpy, /* display */ 202 int extension, /* extension number */ 203 CreateFontType proc) /* routine to call when font created */ 204{ 205 register _XExtension *e; /* for lookup of extension */ 206 register CreateFontType oldproc; 207 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 208 LockDisplay(dpy); 209 oldproc = e->create_Font; 210 e->create_Font = proc; 211 UnlockDisplay(dpy); 212 return (CreateFontType)oldproc; 213} 214 215FreeFontType XESetFreeFont( 216 Display *dpy, /* display */ 217 int extension, /* extension number */ 218 FreeFontType proc) /* routine to call when font freed */ 219{ 220 register _XExtension *e; /* for lookup of extension */ 221 register FreeFontType oldproc; 222 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 223 LockDisplay(dpy); 224 oldproc = e->free_Font; 225 e->free_Font = proc; 226 UnlockDisplay(dpy); 227 return (FreeFontType)oldproc; 228} 229 230CloseDisplayType XESetCloseDisplay( 231 Display *dpy, /* display */ 232 int extension, /* extension number */ 233 CloseDisplayType proc) /* routine to call when display closed */ 234{ 235 register _XExtension *e; /* for lookup of extension */ 236 register CloseDisplayType oldproc; 237 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 238 LockDisplay(dpy); 239 oldproc = e->close_display; 240 e->close_display = proc; 241 UnlockDisplay(dpy); 242 return (CloseDisplayType)oldproc; 243} 244 245typedef Bool (*WireToEventType) ( 246 Display* /* display */, 247 XEvent* /* re */, 248 xEvent* /* event */ 249); 250 251WireToEventType XESetWireToEvent( 252 Display *dpy, /* display */ 253 int event_number, /* event routine to replace */ 254 WireToEventType proc) /* routine to call when converting event */ 255{ 256 register WireToEventType oldproc; 257 if (event_number < 0 || 258 event_number > LastExtensionEvent) { 259 fprintf(stderr, "Xlib: ignoring invalid extension event %d\n", 260 event_number); 261 return (WireToEventType)_XUnknownWireEvent; 262 } 263 if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent; 264 LockDisplay (dpy); 265 oldproc = dpy->event_vec[event_number]; 266 dpy->event_vec[event_number] = proc; 267 UnlockDisplay (dpy); 268 return (WireToEventType)oldproc; 269} 270 271typedef Bool (*WireToEventCookieType) ( 272 Display* /* display */, 273 XGenericEventCookie* /* re */, 274 xEvent* /* event */ 275); 276 277WireToEventCookieType XESetWireToEventCookie( 278 Display *dpy, /* display */ 279 int extension, /* extension major opcode */ 280 WireToEventCookieType proc /* routine to call for generic events */ 281 ) 282{ 283 WireToEventCookieType oldproc; 284 if (extension < FirstExtensionRequest || 285 extension > LastExtensionRequest) { 286 fprintf(stderr, "Xlib: ignoring invalid extension opcode %d\n", 287 extension); 288 return (WireToEventCookieType)_XUnknownWireEventCookie; 289 } 290 if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie; 291 LockDisplay (dpy); 292 oldproc = dpy->generic_event_vec[extension & 0x7F]; 293 dpy->generic_event_vec[extension & 0x7F] = proc; 294 UnlockDisplay (dpy); 295 return (WireToEventCookieType)oldproc; 296} 297 298typedef Bool (*CopyEventCookieType) ( 299 Display* /* display */, 300 XGenericEventCookie* /* in */, 301 XGenericEventCookie* /* out */ 302); 303 304CopyEventCookieType XESetCopyEventCookie( 305 Display *dpy, /* display */ 306 int extension, /* extension major opcode */ 307 CopyEventCookieType proc /* routine to copy generic events */ 308 ) 309{ 310 CopyEventCookieType oldproc; 311 if (extension < FirstExtensionRequest || 312 extension > LastExtensionRequest) { 313 fprintf(stderr, "Xlib: ignoring invalid extension opcode %d\n", 314 extension); 315 return (CopyEventCookieType)_XUnknownCopyEventCookie; 316 } 317 if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie; 318 LockDisplay (dpy); 319 oldproc = dpy->generic_event_copy_vec[extension & 0x7F]; 320 dpy->generic_event_copy_vec[extension & 0x7F] = proc; 321 UnlockDisplay (dpy); 322 return (CopyEventCookieType)oldproc; 323} 324 325 326typedef Status (*EventToWireType) ( 327 Display* /* display */, 328 XEvent* /* re */, 329 xEvent* /* event */ 330); 331 332EventToWireType XESetEventToWire( 333 Display *dpy, /* display */ 334 int event_number, /* event routine to replace */ 335 EventToWireType proc) /* routine to call when converting event */ 336{ 337 register EventToWireType oldproc; 338 if (event_number < 0 || 339 event_number > LastExtensionEvent) { 340 fprintf(stderr, "Xlib: ignoring invalid extension event %d\n", 341 event_number); 342 return (EventToWireType)_XUnknownNativeEvent; 343 } 344 if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent; 345 LockDisplay (dpy); 346 oldproc = dpy->wire_vec[event_number]; 347 dpy->wire_vec[event_number] = proc; 348 UnlockDisplay(dpy); 349 return (EventToWireType)oldproc; 350} 351 352typedef Bool (*WireToErrorType) ( 353 Display* /* display */, 354 XErrorEvent* /* he */, 355 xError* /* we */ 356); 357 358WireToErrorType XESetWireToError( 359 Display *dpy, /* display */ 360 int error_number, /* error routine to replace */ 361 WireToErrorType proc) /* routine to call when converting error */ 362{ 363 register WireToErrorType oldproc = NULL; 364 if (error_number < 0 || 365 error_number > LastExtensionError) { 366 fprintf(stderr, "Xlib: ignoring invalid extension error %d\n", 367 error_number); 368 return (WireToErrorType)_XDefaultWireError; 369 } 370 if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError; 371 LockDisplay (dpy); 372 if (!dpy->error_vec) { 373 int i; 374 dpy->error_vec = Xmalloc(256 * sizeof(oldproc)); 375 for (i = 1; i < 256; i++) 376 dpy->error_vec[i] = _XDefaultWireError; 377 } 378 if (dpy->error_vec) { 379 oldproc = dpy->error_vec[error_number]; 380 dpy->error_vec[error_number] = proc; 381 } 382 UnlockDisplay (dpy); 383 return (WireToErrorType)oldproc; 384} 385 386ErrorType XESetError( 387 Display *dpy, /* display */ 388 int extension, /* extension number */ 389 ErrorType proc) /* routine to call when X error happens */ 390{ 391 register _XExtension *e; /* for lookup of extension */ 392 register ErrorType oldproc; 393 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 394 LockDisplay(dpy); 395 oldproc = e->error; 396 e->error = proc; 397 UnlockDisplay(dpy); 398 return (ErrorType)oldproc; 399} 400 401ErrorStringType XESetErrorString( 402 Display *dpy, /* display */ 403 int extension, /* extension number */ 404 ErrorStringType proc) /* routine to call when I/O error happens */ 405{ 406 register _XExtension *e; /* for lookup of extension */ 407 register ErrorStringType oldproc; 408 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 409 LockDisplay(dpy); 410 oldproc = e->error_string; 411 e->error_string = proc; 412 UnlockDisplay(dpy); 413 return (ErrorStringType)oldproc; 414} 415 416PrintErrorType XESetPrintErrorValues( 417 Display *dpy, /* display */ 418 int extension, /* extension number */ 419 PrintErrorType proc) /* routine to call to print */ 420{ 421 register _XExtension *e; /* for lookup of extension */ 422 register PrintErrorType oldproc; 423 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 424 LockDisplay(dpy); 425 oldproc = e->error_values; 426 e->error_values = proc; 427 UnlockDisplay(dpy); 428 return (PrintErrorType)oldproc; 429} 430 431BeforeFlushType XESetBeforeFlush( 432 Display *dpy, /* display */ 433 int extension, /* extension number */ 434 BeforeFlushType proc) /* routine to call on flush */ 435{ 436 register _XExtension *e; /* for lookup of extension */ 437 register BeforeFlushType oldproc; 438 register _XExtension *ext; 439 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 440 LockDisplay(dpy); 441 oldproc = e->before_flush; 442 e->before_flush = proc; 443 for (ext = dpy->flushes; ext && ext != e; ext = ext->next) 444 ; 445 if (!ext) { 446 e->next_flush = dpy->flushes; 447 dpy->flushes = e; 448 } 449 UnlockDisplay(dpy); 450 return (BeforeFlushType)oldproc; 451} 452