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