InitExt.c revision b4ee4795
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/* 37 * This routine is used to link a extension in so it will be called 38 * at appropriate times. 39 */ 40 41XExtCodes *XInitExtension ( 42 Display *dpy, 43 _Xconst char *name) 44{ 45 XExtCodes codes; /* temp. place for extension information. */ 46 register _XExtension *ext;/* need a place to build it all */ 47 if (!XQueryExtension(dpy, name, 48 &codes.major_opcode, &codes.first_event, 49 &codes.first_error)) return (NULL); 50 51 LockDisplay (dpy); 52 if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) || 53 ! (ext->name = Xmalloc((unsigned) strlen(name) + 1))) { 54 if (ext) Xfree((char *) ext); 55 UnlockDisplay(dpy); 56 return (XExtCodes *) NULL; 57 } 58 codes.extension = dpy->ext_number++; 59 ext->codes = codes; 60 (void) strcpy(ext->name, name); 61 62 /* chain it onto the display list */ 63 ext->next = dpy->ext_procs; 64 dpy->ext_procs = ext; 65 UnlockDisplay (dpy); 66 67 return (&ext->codes); /* tell him which extension */ 68} 69 70XExtCodes *XAddExtension (Display *dpy) 71{ 72 register _XExtension *ext; 73 74 LockDisplay (dpy); 75 if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension)))) { 76 UnlockDisplay(dpy); 77 return (XExtCodes *) NULL; 78 } 79 ext->codes.extension = dpy->ext_number++; 80 81 /* chain it onto the display list */ 82 ext->next = dpy->ext_procs; 83 dpy->ext_procs = ext; 84 UnlockDisplay (dpy); 85 86 return (&ext->codes); /* tell him which extension */ 87} 88 89static _XExtension *XLookupExtension ( 90 register Display *dpy, /* display */ 91 register int extension) /* extension number */ 92{ 93 register _XExtension *ext; 94 for (ext = dpy->ext_procs; ext; ext = ext->next) 95 if (ext->codes.extension == extension) return (ext); 96 return (NULL); 97} 98 99XExtData **XEHeadOfExtensionList(XEDataObject object) 100{ 101 return *(XExtData ***)&object; 102} 103 104int 105XAddToExtensionList( 106 XExtData **structure, 107 XExtData *ext_data) 108{ 109 ext_data->next = *structure; 110 *structure = ext_data; 111 return 1; 112} 113 114XExtData *XFindOnExtensionList( 115 XExtData **structure, 116 int number) 117{ 118 XExtData *ext; 119 120 ext = *structure; 121 while (ext && (ext->number != number)) 122 ext = ext->next; 123 return ext; 124} 125 126/* 127 * Routines to hang procs on the extension structure. 128 */ 129CreateGCType XESetCreateGC( 130 Display *dpy, /* display */ 131 int extension, /* extension number */ 132 CreateGCType proc) /* routine to call when GC created */ 133{ 134 register _XExtension *e; /* for lookup of extension */ 135 register CreateGCType oldproc; 136 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 137 LockDisplay(dpy); 138 oldproc = e->create_GC; 139 e->create_GC = proc; 140 UnlockDisplay(dpy); 141 return (CreateGCType)oldproc; 142} 143 144CopyGCType XESetCopyGC( 145 Display *dpy, /* display */ 146 int extension, /* extension number */ 147 CopyGCType proc) /* routine to call when GC copied */ 148{ 149 register _XExtension *e; /* for lookup of extension */ 150 register CopyGCType oldproc; 151 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 152 LockDisplay(dpy); 153 oldproc = e->copy_GC; 154 e->copy_GC = proc; 155 UnlockDisplay(dpy); 156 return (CopyGCType)oldproc; 157} 158 159FlushGCType XESetFlushGC( 160 Display *dpy, /* display */ 161 int extension, /* extension number */ 162 FlushGCType proc) /* routine to call when GC copied */ 163{ 164 register _XExtension *e; /* for lookup of extension */ 165 register FlushGCType oldproc; 166 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 167 LockDisplay(dpy); 168 oldproc = e->flush_GC; 169 e->flush_GC = proc; 170 UnlockDisplay(dpy); 171 return (FlushGCType)oldproc; 172} 173 174FreeGCType XESetFreeGC( 175 Display *dpy, /* display */ 176 int extension, /* extension number */ 177 FreeGCType proc) /* routine to call when GC freed */ 178{ 179 register _XExtension *e; /* for lookup of extension */ 180 register FreeGCType oldproc; 181 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 182 LockDisplay(dpy); 183 oldproc = e->free_GC; 184 e->free_GC = proc; 185 UnlockDisplay(dpy); 186 return (FreeGCType)oldproc; 187} 188 189CreateFontType XESetCreateFont( 190 Display *dpy, /* display */ 191 int extension, /* extension number */ 192 CreateFontType proc) /* routine to call when font created */ 193{ 194 register _XExtension *e; /* for lookup of extension */ 195 register CreateFontType oldproc; 196 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 197 LockDisplay(dpy); 198 oldproc = e->create_Font; 199 e->create_Font = proc; 200 UnlockDisplay(dpy); 201 return (CreateFontType)oldproc; 202} 203 204FreeFontType XESetFreeFont( 205 Display *dpy, /* display */ 206 int extension, /* extension number */ 207 FreeFontType proc) /* routine to call when font freed */ 208{ 209 register _XExtension *e; /* for lookup of extension */ 210 register FreeFontType oldproc; 211 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 212 LockDisplay(dpy); 213 oldproc = e->free_Font; 214 e->free_Font = proc; 215 UnlockDisplay(dpy); 216 return (FreeFontType)oldproc; 217} 218 219CloseDisplayType XESetCloseDisplay( 220 Display *dpy, /* display */ 221 int extension, /* extension number */ 222 CloseDisplayType proc) /* routine to call when display closed */ 223{ 224 register _XExtension *e; /* for lookup of extension */ 225 register CloseDisplayType oldproc; 226 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 227 LockDisplay(dpy); 228 oldproc = e->close_display; 229 e->close_display = proc; 230 UnlockDisplay(dpy); 231 return (CloseDisplayType)oldproc; 232} 233 234typedef Bool (*WireToEventType) ( 235 Display* /* display */, 236 XEvent* /* re */, 237 xEvent* /* event */ 238); 239 240WireToEventType XESetWireToEvent( 241 Display *dpy, /* display */ 242 int event_number, /* event routine to replace */ 243 WireToEventType proc) /* routine to call when converting event */ 244{ 245 register WireToEventType oldproc; 246 if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent; 247 LockDisplay (dpy); 248 oldproc = dpy->event_vec[event_number]; 249 dpy->event_vec[event_number] = proc; 250 UnlockDisplay (dpy); 251 return (WireToEventType)oldproc; 252} 253 254typedef Bool (*WireToEventCookieType) ( 255 Display* /* display */, 256 XGenericEventCookie* /* re */, 257 xEvent* /* event */ 258); 259 260WireToEventCookieType XESetWireToEventCookie( 261 Display *dpy, /* display */ 262 int extension, /* extension major opcode */ 263 WireToEventCookieType proc /* routine to call for generic events */ 264 ) 265{ 266 WireToEventCookieType oldproc; 267 if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie; 268 LockDisplay (dpy); 269 oldproc = dpy->generic_event_vec[extension & 0x7F]; 270 dpy->generic_event_vec[extension & 0x7F] = proc; 271 UnlockDisplay (dpy); 272 return (WireToEventCookieType)oldproc; 273} 274 275typedef Bool (*CopyEventCookieType) ( 276 Display* /* display */, 277 XGenericEventCookie* /* in */, 278 XGenericEventCookie* /* out */ 279); 280 281CopyEventCookieType XESetCopyEventCookie( 282 Display *dpy, /* display */ 283 int extension, /* extension major opcode */ 284 CopyEventCookieType proc /* routine to copy generic events */ 285 ) 286{ 287 CopyEventCookieType oldproc; 288 if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie; 289 LockDisplay (dpy); 290 oldproc = dpy->generic_event_copy_vec[extension & 0x7F]; 291 dpy->generic_event_copy_vec[extension & 0x7F] = proc; 292 UnlockDisplay (dpy); 293 return (CopyEventCookieType)oldproc; 294} 295 296 297typedef Status (*EventToWireType) ( 298 Display* /* display */, 299 XEvent* /* re */, 300 xEvent* /* event */ 301); 302 303EventToWireType XESetEventToWire( 304 Display *dpy, /* display */ 305 int event_number, /* event routine to replace */ 306 EventToWireType proc) /* routine to call when converting event */ 307{ 308 register EventToWireType oldproc; 309 if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent; 310 LockDisplay (dpy); 311 oldproc = dpy->wire_vec[event_number]; 312 dpy->wire_vec[event_number] = proc; 313 UnlockDisplay(dpy); 314 return (EventToWireType)oldproc; 315} 316 317typedef Bool (*WireToErrorType) ( 318 Display* /* display */, 319 XErrorEvent* /* he */, 320 xError* /* we */ 321); 322 323WireToErrorType XESetWireToError( 324 Display *dpy, /* display */ 325 int error_number, /* error routine to replace */ 326 WireToErrorType proc) /* routine to call when converting error */ 327{ 328 register WireToErrorType oldproc = NULL; 329 if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError; 330 LockDisplay (dpy); 331 if (!dpy->error_vec) { 332 int i; 333 dpy->error_vec = Xmalloc(256 * sizeof(oldproc)); 334 for (i = 1; i < 256; i++) 335 dpy->error_vec[i] = _XDefaultWireError; 336 } 337 if (dpy->error_vec) { 338 oldproc = dpy->error_vec[error_number]; 339 dpy->error_vec[error_number] = proc; 340 } 341 UnlockDisplay (dpy); 342 return (WireToErrorType)oldproc; 343} 344 345ErrorType XESetError( 346 Display *dpy, /* display */ 347 int extension, /* extension number */ 348 ErrorType proc) /* routine to call when X error happens */ 349{ 350 register _XExtension *e; /* for lookup of extension */ 351 register ErrorType oldproc; 352 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 353 LockDisplay(dpy); 354 oldproc = e->error; 355 e->error = proc; 356 UnlockDisplay(dpy); 357 return (ErrorType)oldproc; 358} 359 360ErrorStringType XESetErrorString( 361 Display *dpy, /* display */ 362 int extension, /* extension number */ 363 ErrorStringType proc) /* routine to call when I/O error happens */ 364{ 365 register _XExtension *e; /* for lookup of extension */ 366 register ErrorStringType oldproc; 367 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 368 LockDisplay(dpy); 369 oldproc = e->error_string; 370 e->error_string = proc; 371 UnlockDisplay(dpy); 372 return (ErrorStringType)oldproc; 373} 374 375PrintErrorType XESetPrintErrorValues( 376 Display *dpy, /* display */ 377 int extension, /* extension number */ 378 PrintErrorType proc) /* routine to call to print */ 379{ 380 register _XExtension *e; /* for lookup of extension */ 381 register PrintErrorType oldproc; 382 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 383 LockDisplay(dpy); 384 oldproc = e->error_values; 385 e->error_values = proc; 386 UnlockDisplay(dpy); 387 return (PrintErrorType)oldproc; 388} 389 390BeforeFlushType XESetBeforeFlush( 391 Display *dpy, /* display */ 392 int extension, /* extension number */ 393 BeforeFlushType proc) /* routine to call on flush */ 394{ 395 register _XExtension *e; /* for lookup of extension */ 396 register BeforeFlushType oldproc; 397 register _XExtension *ext; 398 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL); 399 LockDisplay(dpy); 400 oldproc = e->before_flush; 401 e->before_flush = proc; 402 for (ext = dpy->flushes; ext && ext != e; ext = ext->next) 403 ; 404 if (!ext) { 405 e->next_flush = dpy->flushes; 406 dpy->flushes = e; 407 } 408 UnlockDisplay(dpy); 409 return (BeforeFlushType)oldproc; 410} 411