Home | History | Annotate | Download | only in Xxf86dga
      1 /* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.19 2001/08/18 02:41:30 dawes Exp $ */
      2 /*
      3 
      4 Copyright (c) 1995  Jon Tombs
      5 Copyright (c) 1995,1996  The XFree86 Project, Inc
      6 
      7 */
      8 
      9 /* THIS IS NOT AN X CONSORTIUM STANDARD */
     10 
     11 #ifdef __EMX__ /* needed here to override certain constants in X headers */
     12 #define INCL_DOS
     13 #define INCL_DOSIOCTL
     14 #include <os2.h>
     15 #endif
     16 
     17 #if defined(linux)
     18 #define HAS_MMAP_ANON
     19 #include <sys/types.h>
     20 #include <sys/mman.h>
     21 /*#include <asm/page.h>*/   /* PAGE_SIZE */
     22 #define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
     23 #define HAS_GETPAGESIZE
     24 #endif /* linux */
     25 
     26 #if defined(CSRG_BASED)
     27 #define HAS_MMAP_ANON
     28 #define HAS_GETPAGESIZE
     29 #include <sys/types.h>
     30 #include <sys/mman.h>
     31 #endif /* CSRG_BASED */
     32 
     33 #if defined(DGUX)
     34 #define HAS_GETPAGESIZE
     35 #define MMAP_DEV_ZERO
     36 #include <sys/types.h>
     37 #include <sys/mman.h>
     38 #include <unistd.h>
     39 #endif /* DGUX */
     40 
     41 #if defined(SVR4) && !defined(DGUX)
     42 #define MMAP_DEV_ZERO
     43 #include <sys/types.h>
     44 #include <sys/mman.h>
     45 #include <unistd.h>
     46 #endif /* SVR4 && !DGUX */
     47 
     48 #if defined(sun) && !defined(SVR4) /* SunOS */
     49 #define MMAP_DEV_ZERO   /* doesn't SunOS have MAP_ANON ?? */
     50 #define HAS_GETPAGESIZE
     51 #include <sys/types.h>
     52 #include <sys/mman.h>
     53 #endif /* sun && !SVR4 */
     54 
     55 #ifdef XNO_SYSCONF
     56 #undef _SC_PAGESIZE
     57 #endif
     58 
     59 #define NEED_EVENTS
     60 #define NEED_REPLIES
     61 
     62 #include <X11/Xlibint.h>
     63 #include "../extensions/xf86dga.h"
     64 #include "../extensions/xf86dgastr.h"
     65 #include "../extensions/Xext.h"
     66 #include "../extensions/extutil.h"
     67 
     68 extern XExtDisplayInfo* SDL_NAME(xdga_find_display)(Display*);
     69 extern char *SDL_NAME(xdga_extension_name);
     70 
     71 #define XF86DGACheckExtension(dpy,i,val) \
     72   XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
     73 
     74 /*****************************************************************************
     75  *                                                                           *
     76  *		    public XFree86-DGA Extension routines                    *
     77  *                                                                           *
     78  *****************************************************************************/
     79 
     80 Bool SDL_NAME(XF86DGAQueryExtension) (
     81     Display *dpy,
     82     int *event_basep,
     83     int *error_basep
     84 ){
     85     return SDL_NAME(XDGAQueryExtension)(dpy, event_basep, error_basep);
     86 }
     87 
     88 Bool SDL_NAME(XF86DGAQueryVersion)(
     89     Display* dpy,
     90     int* majorVersion,
     91     int* minorVersion
     92 ){
     93     return SDL_NAME(XDGAQueryVersion)(dpy, majorVersion, minorVersion);
     94 }
     95 
     96 Bool SDL_NAME(XF86DGAGetVideoLL)(
     97     Display* dpy,
     98     int screen,
     99     int *offset,
    100     int *width,
    101     int *bank_size,
    102     int *ram_size
    103 ){
    104     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    105     xXF86DGAGetVideoLLReply rep;
    106     xXF86DGAGetVideoLLReq *req;
    107 
    108     XF86DGACheckExtension (dpy, info, False);
    109 
    110     LockDisplay(dpy);
    111     GetReq(XF86DGAGetVideoLL, req);
    112     req->reqType = info->codes->major_opcode;
    113     req->dgaReqType = X_XF86DGAGetVideoLL;
    114     req->screen = screen;
    115     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    116 	UnlockDisplay(dpy);
    117 	SyncHandle();
    118 	return False;
    119     }
    120 
    121     *offset = /*(char *)*/rep.offset;
    122     *width = rep.width;
    123     *bank_size = rep.bank_size;
    124     *ram_size = rep.ram_size;
    125 
    126     UnlockDisplay(dpy);
    127     SyncHandle();
    128     return True;
    129 }
    130 
    131 
    132 Bool SDL_NAME(XF86DGADirectVideoLL)(
    133     Display* dpy,
    134     int screen,
    135     int enable
    136 ){
    137     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    138     xXF86DGADirectVideoReq *req;
    139 
    140     XF86DGACheckExtension (dpy, info, False);
    141 
    142     LockDisplay(dpy);
    143     GetReq(XF86DGADirectVideo, req);
    144     req->reqType = info->codes->major_opcode;
    145     req->dgaReqType = X_XF86DGADirectVideo;
    146     req->screen = screen;
    147     req->enable = enable;
    148     UnlockDisplay(dpy);
    149     SyncHandle();
    150     XSync(dpy,False);
    151     return True;
    152 }
    153 
    154 Bool SDL_NAME(XF86DGAGetViewPortSize)(
    155     Display* dpy,
    156     int screen,
    157     int *width,
    158     int *height
    159 ){
    160     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    161     xXF86DGAGetViewPortSizeReply rep;
    162     xXF86DGAGetViewPortSizeReq *req;
    163 
    164     XF86DGACheckExtension (dpy, info, False);
    165 
    166     LockDisplay(dpy);
    167     GetReq(XF86DGAGetViewPortSize, req);
    168     req->reqType = info->codes->major_opcode;
    169     req->dgaReqType = X_XF86DGAGetViewPortSize;
    170     req->screen = screen;
    171     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    172 	UnlockDisplay(dpy);
    173 	SyncHandle();
    174 	return False;
    175     }
    176 
    177     *width = rep.width;
    178     *height = rep.height;
    179 
    180     UnlockDisplay(dpy);
    181     SyncHandle();
    182     return True;
    183 }
    184 
    185 
    186 Bool SDL_NAME(XF86DGASetViewPort)(
    187     Display* dpy,
    188     int screen,
    189     int x,
    190     int y
    191 ){
    192     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    193     xXF86DGASetViewPortReq *req;
    194 
    195     XF86DGACheckExtension (dpy, info, False);
    196 
    197     LockDisplay(dpy);
    198     GetReq(XF86DGASetViewPort, req);
    199     req->reqType = info->codes->major_opcode;
    200     req->dgaReqType = X_XF86DGASetViewPort;
    201     req->screen = screen;
    202     req->x = x;
    203     req->y = y;
    204     UnlockDisplay(dpy);
    205     SyncHandle();
    206     XSync(dpy,False);
    207     return True;
    208 }
    209 
    210 
    211 Bool SDL_NAME(XF86DGAGetVidPage)(
    212     Display* dpy,
    213     int screen,
    214     int *vpage
    215 ){
    216     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    217     xXF86DGAGetVidPageReply rep;
    218     xXF86DGAGetVidPageReq *req;
    219 
    220     XF86DGACheckExtension (dpy, info, False);
    221 
    222     LockDisplay(dpy);
    223     GetReq(XF86DGAGetVidPage, req);
    224     req->reqType = info->codes->major_opcode;
    225     req->dgaReqType = X_XF86DGAGetVidPage;
    226     req->screen = screen;
    227     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    228 	UnlockDisplay(dpy);
    229 	SyncHandle();
    230 	return False;
    231     }
    232 
    233     *vpage = rep.vpage;
    234     UnlockDisplay(dpy);
    235     SyncHandle();
    236     return True;
    237 }
    238 
    239 
    240 Bool SDL_NAME(XF86DGASetVidPage)(
    241     Display* dpy,
    242     int screen,
    243     int vpage
    244 ){
    245     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    246     xXF86DGASetVidPageReq *req;
    247 
    248     XF86DGACheckExtension (dpy, info, False);
    249 
    250     LockDisplay(dpy);
    251     GetReq(XF86DGASetVidPage, req);
    252     req->reqType = info->codes->major_opcode;
    253     req->dgaReqType = X_XF86DGASetVidPage;
    254     req->screen = screen;
    255     req->vpage = vpage;
    256     UnlockDisplay(dpy);
    257     SyncHandle();
    258     XSync(dpy,False);
    259     return True;
    260 }
    261 
    262 Bool SDL_NAME(XF86DGAInstallColormap)(
    263     Display* dpy,
    264     int screen,
    265     Colormap cmap
    266 ){
    267     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    268     xXF86DGAInstallColormapReq *req;
    269 
    270     XF86DGACheckExtension (dpy, info, False);
    271 
    272     LockDisplay(dpy);
    273     GetReq(XF86DGAInstallColormap, req);
    274     req->reqType = info->codes->major_opcode;
    275     req->dgaReqType = X_XF86DGAInstallColormap;
    276     req->screen = screen;
    277     req->id = cmap;
    278     UnlockDisplay(dpy);
    279     SyncHandle();
    280     XSync(dpy,False);
    281     return True;
    282 }
    283 
    284 Bool SDL_NAME(XF86DGAQueryDirectVideo)(
    285     Display *dpy,
    286     int screen,
    287     int *flags
    288 ){
    289     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    290     xXF86DGAQueryDirectVideoReply rep;
    291     xXF86DGAQueryDirectVideoReq *req;
    292 
    293     XF86DGACheckExtension (dpy, info, False);
    294 
    295     LockDisplay(dpy);
    296     GetReq(XF86DGAQueryDirectVideo, req);
    297     req->reqType = info->codes->major_opcode;
    298     req->dgaReqType = X_XF86DGAQueryDirectVideo;
    299     req->screen = screen;
    300     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    301 	UnlockDisplay(dpy);
    302 	SyncHandle();
    303 	return False;
    304     }
    305     *flags = rep.flags;
    306     UnlockDisplay(dpy);
    307     SyncHandle();
    308     return True;
    309 }
    310 
    311 Bool SDL_NAME(XF86DGAViewPortChanged)(
    312     Display *dpy,
    313     int screen,
    314     int n
    315 ){
    316     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    317     xXF86DGAViewPortChangedReply rep;
    318     xXF86DGAViewPortChangedReq *req;
    319 
    320     XF86DGACheckExtension (dpy, info, False);
    321 
    322     LockDisplay(dpy);
    323     GetReq(XF86DGAViewPortChanged, req);
    324     req->reqType = info->codes->major_opcode;
    325     req->dgaReqType = X_XF86DGAViewPortChanged;
    326     req->screen = screen;
    327     req->n = n;
    328     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    329 	UnlockDisplay(dpy);
    330 	SyncHandle();
    331 	return False;
    332     }
    333     UnlockDisplay(dpy);
    334     SyncHandle();
    335     return rep.result;
    336 }
    337 
    338 
    339 
    340 /* Helper functions */
    341 
    342 #include <X11/Xmd.h>
    343 #include "../extensions/xf86dga.h"
    344 #include <stdlib.h>
    345 #include <stdio.h>
    346 #include <fcntl.h>
    347 #if defined(ISC)
    348 # define HAS_SVR3_MMAP
    349 # include <sys/types.h>
    350 # include <errno.h>
    351 
    352 # include <sys/at_ansi.h>
    353 # include <sys/kd.h>
    354 
    355 # include <sys/sysmacros.h>
    356 # include <sys/immu.h>
    357 # include <sys/region.h>
    358 
    359 # include <sys/mmap.h>
    360 #else
    361 # if !defined(Lynx)
    362 #  if !defined(__EMX__)
    363 #   include <sys/mman.h>
    364 #  endif
    365 # else
    366 #  include <sys/types.h>
    367 #  include <errno.h>
    368 #  include <smem.h>
    369 # endif
    370 #endif
    371 #include <sys/wait.h>
    372 #include <signal.h>
    373 #include <unistd.h>
    374 
    375 #if defined(SVR4) && !defined(sun) && !defined(SCO325)
    376 #define DEV_MEM "/dev/pmem"
    377 #elif defined(SVR4) && defined(sun)
    378 #define DEV_MEM "/dev/xsvc"
    379 #else
    380 #define DEV_MEM "/dev/mem"
    381 #endif
    382 
    383 typedef struct {
    384     unsigned long physaddr;	/* actual requested physical address */
    385     unsigned long size;		/* actual requested map size */
    386     unsigned long delta;	/* delta to account for page alignment */
    387     void *	  vaddr;	/* mapped address, without the delta */
    388     int		  refcount;	/* reference count */
    389 } MapRec, *MapPtr;
    390 
    391 typedef struct {
    392     Display *	display;
    393     int		screen;
    394     MapPtr	map;
    395 } ScrRec, *ScrPtr;
    396 
    397 static int mapFd = -1;
    398 static int numMaps = 0;
    399 static int numScrs = 0;
    400 static MapPtr *mapList = NULL;
    401 static ScrPtr *scrList = NULL;
    402 
    403 static MapPtr
    404 AddMap(void)
    405 {
    406     MapPtr *old;
    407 
    408     old = mapList;
    409     mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1));
    410     if (!mapList) {
    411 	mapList = old;
    412 	return NULL;
    413     }
    414     mapList[numMaps] = malloc(sizeof(MapRec));
    415     if (!mapList[numMaps])
    416 	return NULL;
    417     return mapList[numMaps++];
    418 }
    419 
    420 static ScrPtr
    421 AddScr(void)
    422 {
    423     ScrPtr *old;
    424 
    425     old = scrList;
    426     scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1));
    427     if (!scrList) {
    428 	scrList = old;
    429 	return NULL;
    430     }
    431     scrList[numScrs] = malloc(sizeof(ScrRec));
    432     if (!scrList[numScrs])
    433 	return NULL;
    434     return scrList[numScrs++];
    435 }
    436 
    437 static MapPtr
    438 FindMap(unsigned long address, unsigned long size)
    439 {
    440     int i;
    441 
    442     for (i = 0; i < numMaps; i++) {
    443 	if (mapList[i]->physaddr == address &&
    444 	    mapList[i]->size == size)
    445 	    return mapList[i];
    446     }
    447     return NULL;
    448 }
    449 
    450 static ScrPtr
    451 FindScr(Display *display, int screen)
    452 {
    453     int i;
    454 
    455     for (i = 0; i < numScrs; i++) {
    456 	if (scrList[i]->display == display &&
    457 	    scrList[i]->screen == screen)
    458 	    return scrList[i];
    459     }
    460     return NULL;
    461 }
    462 
    463 static void *
    464 MapPhysAddress(unsigned long address, unsigned long size)
    465 {
    466     unsigned long offset, delta;
    467     int pagesize = -1;
    468     void *vaddr;
    469     MapPtr mp;
    470 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    471     struct kd_memloc mloc;
    472 #elif defined(__EMX__)
    473     APIRET rc;
    474     ULONG action;
    475     HFILE hfd;
    476 #endif
    477 
    478     if ((mp = FindMap(address, size))) {
    479 	mp->refcount++;
    480 	return (void *)((unsigned long)mp->vaddr + mp->delta);
    481     }
    482 
    483 #if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
    484     pagesize = sysconf(_SC_PAGESIZE);
    485 #endif
    486 #ifdef _SC_PAGE_SIZE
    487     if (pagesize == -1)
    488 	pagesize = sysconf(_SC_PAGE_SIZE);
    489 #endif
    490 #ifdef HAS_GETPAGESIZE
    491     if (pagesize == -1)
    492 	pagesize = getpagesize();
    493 #endif
    494 #ifdef PAGE_SIZE
    495     if (pagesize == -1)
    496 	pagesize = PAGE_SIZE;
    497 #endif
    498     if (pagesize == -1)
    499 	pagesize = 4096;
    500 
    501    delta = address % pagesize;
    502    offset = address - delta;
    503 
    504 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    505     if (mapFd < 0) {
    506 	if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
    507 	    return NULL;
    508     }
    509     mloc.vaddr = (char *)0;
    510     mloc.physaddr = (char *)offset;
    511     mloc.length = size + delta;
    512     mloc.ioflg=1;
    513 
    514     if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
    515 	return NULL;
    516 #elif defined (__EMX__)
    517     /*
    518      * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
    519      * Consecutive calling of this routine will make PMAP$ driver run out
    520      * of memory handles. Some umap/close mechanism should be provided
    521      */
    522 
    523     rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
    524 		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
    525     if (rc != 0)
    526 	return NULL;
    527     {
    528 	struct map_ioctl {
    529 		union {
    530 			ULONG phys;
    531 			void* user;
    532 		} a;
    533 		ULONG size;
    534 	} pmap,dmap;
    535 	ULONG plen,dlen;
    536 #define XFREE86_PMAP	0x76
    537 #define PMAP_MAP	0x44
    538 
    539 	pmap.a.phys = offset;
    540 	pmap.size = size + delta;
    541 	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
    542 			 (PULONG)&pmap, sizeof(pmap), &plen,
    543 			 (PULONG)&dmap, sizeof(dmap), &dlen);
    544 	if (rc == 0) {
    545 		vaddr = dmap.a.user;
    546 	}
    547    }
    548    if (rc != 0)
    549 	return NULL;
    550 #elif defined (Lynx)
    551     vaddr = (void *)smem_create("XF86DGA", (char *)offset,
    552 				size + delta, SM_READ|SM_WRITE);
    553 #else
    554 #ifndef MAP_FILE
    555 #define MAP_FILE 0
    556 #endif
    557     if (mapFd < 0) {
    558 	if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
    559 	    return NULL;
    560     }
    561     vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
    562                         MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
    563     if (vaddr == (void *)-1)
    564 	return NULL;
    565 #endif
    566 
    567     if (!vaddr) {
    568 	if (!(mp = AddMap()))
    569 	    return NULL;
    570 	mp->physaddr = address;
    571 	mp->size = size;
    572 	mp->delta = delta;
    573 	mp->vaddr = vaddr;
    574 	mp->refcount = 1;
    575     }
    576     return (void *)((unsigned long)vaddr + delta);
    577 }
    578 
    579 /*
    580  * Still need to find a clean way of detecting the death of a DGA app
    581  * and returning things to normal - Jon
    582  * This is here to help debugging without rebooting... Also C-A-BS
    583  * should restore text mode.
    584  */
    585 
    586 int
    587 SDL_NAME(XF86DGAForkApp)(int screen)
    588 {
    589     pid_t pid;
    590     int status;
    591     int i;
    592 
    593      /* fork the app, parent hangs around to clean up */
    594     if ((pid = fork()) > 0) {
    595 	ScrPtr sp;
    596 
    597 	waitpid(pid, &status, 0);
    598 	for (i = 0; i < numScrs; i++) {
    599 	    sp = scrList[i];
    600 	    SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0);
    601 	    XSync(sp->display, False);
    602 	}
    603         if (WIFEXITED(status))
    604 	    _exit(0);
    605 	else
    606 	    _exit(-1);
    607     }
    608     return pid;
    609 }
    610 
    611 
    612 Bool
    613 SDL_NAME(XF86DGADirectVideo)(
    614     Display *dis,
    615     int screen,
    616     int enable
    617 ){
    618     ScrPtr sp;
    619     MapPtr mp = NULL;
    620 
    621     if ((sp = FindScr(dis, screen)))
    622 	mp = sp->map;
    623 
    624     if (enable & XF86DGADirectGraphics) {
    625 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    626 	&& !defined(__EMX__)
    627 	if (mp && mp->vaddr)
    628 	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);
    629 #endif
    630     } else {
    631 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    632 	&& !defined(__EMX__)
    633 	if (mp && mp->vaddr)
    634 	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);
    635 #elif defined(Lynx)
    636 	/* XXX this doesn't allow enable after disable */
    637 	smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH);
    638 	smem_remove("XF86DGA");
    639 #endif
    640     }
    641 
    642     SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable);
    643     return 1;
    644 }
    645 
    646 
    647 static void
    648 XF86cleanup(int sig)
    649 {
    650     ScrPtr sp;
    651     int i;
    652     static char beenhere = 0;
    653 
    654     if (beenhere)
    655 	_exit(3);
    656     beenhere = 1;
    657 
    658     for (i = 0; i < numScrs; i++) {
    659 	sp = scrList[i];
    660 	SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0);
    661 	XSync(sp->display, False);
    662     }
    663     _exit(3);
    664 }
    665 
    666 Bool
    667 SDL_NAME(XF86DGAGetVideo)(
    668     Display *dis,
    669     int screen,
    670     char **addr,
    671     int *width,
    672     int *bank,
    673     int *ram
    674 ){
    675     /*unsigned long*/ int offset;
    676     static int beenHere = 0;
    677     ScrPtr sp;
    678     MapPtr mp;
    679 
    680     if (!(sp = FindScr(dis, screen))) {
    681 	if (!(sp = AddScr())) {
    682 	    fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
    683 	    exit(-2);
    684 	}
    685 	sp->display = dis;
    686 	sp->screen = screen;
    687 	sp->map = NULL;
    688     }
    689 
    690     SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram);
    691 
    692     *addr = MapPhysAddress(offset, *bank);
    693     if (*addr == NULL) {
    694 	fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
    695 		strerror(errno));
    696 	exit(-2);
    697     }
    698 
    699     if ((mp = FindMap(offset, *bank)))
    700 	sp->map = mp;
    701 
    702     if (!beenHere) {
    703 	beenHere = 1;
    704 	atexit((void(*)(void))XF86cleanup);
    705 	/* one shot XF86cleanup attempts */
    706 	signal(SIGSEGV, XF86cleanup);
    707 #ifdef SIGBUS
    708 	signal(SIGBUS, XF86cleanup);
    709 #endif
    710 	signal(SIGHUP, XF86cleanup);
    711 	signal(SIGFPE, XF86cleanup);
    712     }
    713 
    714     return 1;
    715 }
    716 
    717