Home | History | Annotate | Download | only in Xxf86dga
      1 /* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 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 #define NEED_EVENTS
     18 #define NEED_REPLIES
     19 
     20 /* Apparently some X11 systems can't include this multiple times... */
     21 #ifndef SDL_INCLUDED_XLIBINT_H
     22 #define SDL_INCLUDED_XLIBINT_H 1
     23 #include <X11/Xlibint.h>
     24 #endif
     25 
     26 #include "../extensions/xf86dga.h"
     27 #include "../extensions/xf86dgastr.h"
     28 #include "../extensions/Xext.h"
     29 #include "../extensions/extutil.h"
     30 #include <stdio.h>
     31 
     32 #if defined(ENABLE_FBCON)  /* Needed for framebuffer console support */
     33 #include <sys/ioctl.h>
     34 #include <linux/fb.h>
     35 #endif
     36 
     37 /* If you change this, change the Bases[] array below as well */
     38 #define MAX_HEADS 16
     39 
     40 char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
     41 
     42 static XExtensionInfo _xdga_info_data;
     43 static XExtensionInfo *xdga_info = &_xdga_info_data;
     44 
     45 
     46 Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32);
     47 void SDL_NAME(XDGAUnmapFramebuffer)(int);
     48 unsigned char* SDL_NAME(XDGAGetMappedMemory)(int);
     49 
     50 #define XDGACheckExtension(dpy,i,val) \
     51   XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
     52 
     53 /*****************************************************************************
     54  *                                                                           *
     55  *			   private utility routines                          *
     56  *                                                                           *
     57  *****************************************************************************/
     58 
     59 static int xdga_close_display(Display *dpy, XExtCodes *codes);
     60 static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
     61 static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
     62 
     63 static XExtensionHooks xdga_extension_hooks = {
     64     NULL,				/* create_gc */
     65     NULL,				/* copy_gc */
     66     NULL,				/* flush_gc */
     67     NULL,				/* free_gc */
     68     NULL,				/* create_font */
     69     NULL,				/* free_font */
     70     xdga_close_display,			/* close_display */
     71     xdga_wire_to_event,			/* wire_to_event */
     72     xdga_event_to_wire,			/* event_to_wire */
     73     NULL,				/* error */
     74     NULL,				/* error_string */
     75 };
     76 
     77 static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
     78 
     79 
     80 XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info,
     81 				   "XFree86-DGA",
     82 				   &xdga_extension_hooks,
     83 				   0, NULL)
     84 
     85 
     86 static Status
     87 xdga_event_to_wire(
     88   Display *dpy,
     89   XEvent *event,
     90   xEvent *wire_ev
     91 ){
     92     return True;
     93 }
     94 
     95 static Bool
     96 xdga_wire_to_event(
     97   Display *dpy,
     98   XEvent *event,
     99   xEvent *wire_ev
    100 ){
    101   dgaEvent *wire = (dgaEvent *) wire_ev;
    102   SDL_NAME(XDGAButtonEvent) *bevent;
    103   SDL_NAME(XDGAKeyEvent) *kevent;
    104   SDL_NAME(XDGAMotionEvent) *mevent;
    105   XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    106 
    107   XDGACheckExtension (dpy, info, False);
    108 
    109   switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
    110   case MotionNotify:
    111 	mevent = (SDL_NAME(XDGAMotionEvent)*)event;
    112 	mevent->type = wire->u.u.type & 0x7F;
    113 	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    114 	mevent->display = dpy;
    115 	mevent->screen = wire->u.event.screen;
    116 	mevent->time = wire->u.event.time;
    117 	mevent->state = wire->u.event.state;
    118 	mevent->dx = wire->u.event.dx;
    119 	mevent->dy = wire->u.event.dy;
    120 	return True;
    121   case ButtonPress:
    122   case ButtonRelease:
    123 	bevent = (SDL_NAME(XDGAButtonEvent)*)event;
    124 	bevent->type = wire->u.u.type & 0x7F;
    125 	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    126 	bevent->display = dpy;
    127 	bevent->screen = wire->u.event.screen;
    128 	bevent->time = wire->u.event.time;
    129 	bevent->state = wire->u.event.state;
    130 	bevent->button = wire->u.u.detail;
    131 	return True;
    132   case KeyPress:
    133   case KeyRelease:
    134 	kevent = (SDL_NAME(XDGAKeyEvent)*)event;
    135 	kevent->type = wire->u.u.type & 0x7F;
    136 	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    137 	kevent->display = dpy;
    138 	kevent->screen = wire->u.event.screen;
    139 	kevent->time = wire->u.event.time;
    140 	kevent->state = wire->u.event.state;
    141 	kevent->keycode = wire->u.u.detail;
    142 	return True;
    143   }
    144 
    145   return False;
    146 }
    147 
    148 
    149 Bool SDL_NAME(XDGAQueryExtension) (
    150     Display *dpy,
    151     int *event_basep,
    152     int *error_basep
    153 ){
    154     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    155 
    156     if (XextHasExtension(info)) {
    157 	*event_basep = info->codes->first_event;
    158 	*error_basep = info->codes->first_error;
    159 	return True;
    160     } else {
    161 	return False;
    162     }
    163 }
    164 
    165 
    166 Bool SDL_NAME(XDGAQueryVersion)(
    167     Display *dpy,
    168     int *majorVersion,
    169     int *minorVersion
    170 ){
    171     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    172     xXDGAQueryVersionReply rep;
    173     xXDGAQueryVersionReq *req;
    174 
    175     XDGACheckExtension (dpy, info, False);
    176 
    177     LockDisplay(dpy);
    178     GetReq(XDGAQueryVersion, req);
    179     req->reqType = info->codes->major_opcode;
    180     req->dgaReqType = X_XDGAQueryVersion;
    181     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    182 	UnlockDisplay(dpy);
    183 	SyncHandle();
    184 	return False;
    185     }
    186     *majorVersion = rep.majorVersion;
    187     *minorVersion = rep.minorVersion;
    188     UnlockDisplay(dpy);
    189     SyncHandle();
    190     if (*majorVersion >= 2)
    191     {
    192 	int i, j;
    193 
    194 	for (i = 0, j = info->codes->first_event;
    195 	     i < XF86DGANumberEvents;
    196 	     i++, j++)
    197 	{
    198 	    XESetWireToEvent(dpy, j, xdga_wire_to_event);
    199 	    XESetEventToWire(dpy, j, xdga_event_to_wire);
    200 	}
    201 	SDL_NAME(XDGASetClientVersion)(dpy);
    202     }
    203     return True;
    204 }
    205 
    206 Bool SDL_NAME(XDGASetClientVersion)(
    207     Display	*dpy
    208 ){
    209     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    210     xXDGASetClientVersionReq *req;
    211 
    212     XDGACheckExtension (dpy, info, False);
    213 
    214     LockDisplay(dpy);
    215     GetReq(XDGASetClientVersion, req);
    216     req->reqType = info->codes->major_opcode;
    217     req->dgaReqType = X_XDGASetClientVersion;
    218     req->major = XDGA_MAJOR_VERSION;
    219     req->minor = XDGA_MINOR_VERSION;
    220     UnlockDisplay(dpy);
    221     SyncHandle();
    222     return True;
    223 }
    224 
    225 Bool SDL_NAME(XDGAOpenFramebuffer)(
    226     Display	*dpy,
    227     int 	screen
    228 ){
    229     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    230     xXDGAOpenFramebufferReply rep;
    231     xXDGAOpenFramebufferReq *req;
    232     char *deviceName = NULL;
    233     Bool ret;
    234 
    235     XDGACheckExtension (dpy, info, False);
    236 
    237     LockDisplay(dpy);
    238     GetReq(XDGAOpenFramebuffer, req);
    239     req->reqType = info->codes->major_opcode;
    240     req->dgaReqType = X_XDGAOpenFramebuffer;
    241     req->screen = screen;
    242     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    243 	UnlockDisplay(dpy);
    244 	SyncHandle();
    245 	return False;
    246     }
    247 
    248     if(rep.length) {
    249 	deviceName = Xmalloc(rep.length << 2);
    250 	_XRead(dpy, deviceName, rep.length << 2);
    251     }
    252 
    253     ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName,
    254 				(unsigned char*)(long)rep.mem1,
    255 				rep.size, rep.offset, rep.extra);
    256 
    257     if(deviceName)
    258 	Xfree(deviceName);
    259 
    260     UnlockDisplay(dpy);
    261     SyncHandle();
    262     return ret;
    263 }
    264 
    265 void SDL_NAME(XDGACloseFramebuffer)(
    266     Display	*dpy,
    267     int		screen
    268 ){
    269     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    270     xXDGACloseFramebufferReq *req;
    271 
    272     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    273 
    274     SDL_NAME(XDGAUnmapFramebuffer)(screen);
    275 
    276     LockDisplay(dpy);
    277     GetReq(XDGACloseFramebuffer, req);
    278     req->reqType = info->codes->major_opcode;
    279     req->dgaReqType = X_XDGACloseFramebuffer;
    280     req->screen = screen;
    281     UnlockDisplay(dpy);
    282     SyncHandle();
    283 }
    284 
    285 
    286 
    287 SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
    288     Display *dpy,
    289     int screen,
    290     int *num
    291 ){
    292     XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
    293     xXDGAQueryModesReply rep;
    294     xXDGAQueryModesReq *req;
    295     SDL_NAME(XDGAMode) *modes = NULL;
    296 
    297     *num = 0;
    298 
    299     XDGACheckExtension (dpy, dinfo, NULL);
    300 
    301     LockDisplay(dpy);
    302     GetReq(XDGAQueryModes, req);
    303     req->reqType = dinfo->codes->major_opcode;
    304     req->dgaReqType = X_XDGAQueryModes;
    305     req->screen = screen;
    306 
    307     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    308 	if(rep.length) {
    309 	   xXDGAModeInfo info;
    310 	   int i, size;
    311 	   char *offset;
    312 
    313 	   size = rep.length << 2;
    314 	   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
    315 	   modes = (SDL_NAME(XDGAMode)*)Xmalloc((rep.number * sizeof(SDL_NAME(XDGAMode))) + size);
    316 	   offset = (char*)(&modes[rep.number]); /* start of text */
    317 
    318 
    319 	   if(modes) {
    320 	      for(i = 0; i < rep.number; i++) {
    321 		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
    322 
    323 		modes[i].num = info.num;
    324 		modes[i].verticalRefresh =
    325 			(float)info.vsync_num / (float)info.vsync_den;
    326 		modes[i].flags = info.flags;
    327 		modes[i].imageWidth = info.image_width;
    328 		modes[i].imageHeight = info.image_height;
    329 		modes[i].pixmapWidth = info.pixmap_width;
    330 		modes[i].pixmapHeight = info.pixmap_height;
    331 		modes[i].bytesPerScanline = info.bytes_per_scanline;
    332 		modes[i].byteOrder = info.byte_order;
    333 		modes[i].depth = info.depth;
    334 		modes[i].bitsPerPixel = info.bpp;
    335 		modes[i].redMask = info.red_mask;
    336 		modes[i].greenMask = info.green_mask;
    337 		modes[i].blueMask = info.blue_mask;
    338 		modes[i].visualClass = info.visual_class;
    339 		modes[i].viewportWidth = info.viewport_width;
    340 		modes[i].viewportHeight = info.viewport_height;
    341 		modes[i].xViewportStep = info.viewport_xstep;
    342 		modes[i].yViewportStep = info.viewport_ystep;
    343 		modes[i].maxViewportX = info.viewport_xmax;
    344 		modes[i].maxViewportY = info.viewport_ymax;
    345 		modes[i].viewportFlags = info.viewport_flags;
    346 		modes[i].reserved1 = info.reserved1;
    347 		modes[i].reserved2 = info.reserved2;
    348 
    349 		_XRead(dpy, offset, info.name_size);
    350 		modes[i].name = offset;
    351 		offset += info.name_size;
    352 	      }
    353 	      *num = rep.number;
    354 	   } else
    355 		_XEatData(dpy, rep.length << 2);
    356 	}
    357     }
    358 
    359     UnlockDisplay(dpy);
    360     SyncHandle();
    361 
    362     return modes;
    363 }
    364 
    365 
    366 SDL_NAME(XDGADevice) *
    367 SDL_NAME(XDGASetMode)(
    368     Display	*dpy,
    369     int		screen,
    370     int		mode
    371 ){
    372     XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
    373     xXDGASetModeReply rep;
    374     xXDGASetModeReq *req;
    375     SDL_NAME(XDGADevice) *dev = NULL;
    376     Pixmap pid;
    377 
    378     XDGACheckExtension (dpy, dinfo, NULL);
    379 
    380     LockDisplay(dpy);
    381     GetReq(XDGASetMode, req);
    382     req->reqType = dinfo->codes->major_opcode;
    383     req->dgaReqType = X_XDGASetMode;
    384     req->screen = screen;
    385     req->mode = mode;
    386     req->pid = pid = XAllocID(dpy);
    387 
    388     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    389 	if(rep.length) {
    390 	   xXDGAModeInfo info;
    391 	   int size;
    392 
    393 	   size = rep.length << 2;
    394 	   size -= sz_xXDGAModeInfo; /* get text size */
    395 
    396 	   dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size);
    397 
    398 	   if(dev) {
    399 		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
    400 
    401 		dev->mode.num = info.num;
    402 		dev->mode.verticalRefresh =
    403 				(float)info.vsync_num / (float)info.vsync_den;
    404 		dev->mode.flags = info.flags;
    405 		dev->mode.imageWidth = info.image_width;
    406 		dev->mode.imageHeight = info.image_height;
    407 		dev->mode.pixmapWidth = info.pixmap_width;
    408 		dev->mode.pixmapHeight = info.pixmap_height;
    409 		dev->mode.bytesPerScanline = info.bytes_per_scanline;
    410 		dev->mode.byteOrder = info.byte_order;
    411 		dev->mode.depth = info.depth;
    412 		dev->mode.bitsPerPixel = info.bpp;
    413 		dev->mode.redMask = info.red_mask;
    414 		dev->mode.greenMask = info.green_mask;
    415 		dev->mode.blueMask = info.blue_mask;
    416 		dev->mode.visualClass = info.visual_class;
    417 		dev->mode.viewportWidth = info.viewport_width;
    418 		dev->mode.viewportHeight = info.viewport_height;
    419 		dev->mode.xViewportStep = info.viewport_xstep;
    420 		dev->mode.yViewportStep = info.viewport_ystep;
    421 		dev->mode.maxViewportX = info.viewport_xmax;
    422 		dev->mode.maxViewportY = info.viewport_ymax;
    423 		dev->mode.viewportFlags = info.viewport_flags;
    424 		dev->mode.reserved1 = info.reserved1;
    425 		dev->mode.reserved2 = info.reserved2;
    426 
    427 		dev->mode.name = (char*)(&dev[1]);
    428 		_XRead(dpy, dev->mode.name, info.name_size);
    429 
    430 		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
    431 		dev->data = SDL_NAME(XDGAGetMappedMemory)(screen);
    432 
    433 		if(dev->data)
    434 		    dev->data += rep.offset;
    435 	   }
    436 	   /* not sure what to do if the allocation fails */
    437 	}
    438     }
    439 
    440     UnlockDisplay(dpy);
    441     SyncHandle();
    442 
    443     return dev;
    444 }
    445 
    446 
    447 void SDL_NAME(XDGASetViewport)(
    448     Display	*dpy,
    449     int		screen,
    450     int		x,
    451     int		y,
    452     int		flags
    453 ){
    454     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    455     xXDGASetViewportReq *req;
    456 
    457     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    458 
    459     LockDisplay(dpy);
    460     GetReq(XDGASetViewport, req);
    461     req->reqType = info->codes->major_opcode;
    462     req->dgaReqType = X_XDGASetViewport;
    463     req->screen = screen;
    464     req->x = x;
    465     req->y = y;
    466     req->flags = flags;
    467     UnlockDisplay(dpy);
    468     SyncHandle();
    469 }
    470 
    471 
    472 void SDL_NAME(XDGAInstallColormap)(
    473     Display	*dpy,
    474     int		screen,
    475     Colormap	cmap
    476 ){
    477     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    478     xXDGAInstallColormapReq *req;
    479 
    480     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    481 
    482     LockDisplay(dpy);
    483     GetReq(XDGAInstallColormap, req);
    484     req->reqType = info->codes->major_opcode;
    485     req->dgaReqType = X_XDGAInstallColormap;
    486     req->screen = screen;
    487     req->cmap = cmap;
    488     UnlockDisplay(dpy);
    489     SyncHandle();
    490 }
    491 
    492 void SDL_NAME(XDGASelectInput)(
    493     Display	*dpy,
    494     int		screen,
    495     long	mask
    496 ){
    497     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    498     xXDGASelectInputReq *req;
    499 
    500     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    501 
    502     LockDisplay(dpy);
    503     GetReq(XDGASelectInput, req);
    504     req->reqType = info->codes->major_opcode;
    505     req->dgaReqType = X_XDGASelectInput;
    506     req->screen = screen;
    507     req->mask = mask;
    508     UnlockDisplay(dpy);
    509     SyncHandle();
    510 }
    511 
    512 void SDL_NAME(XDGAFillRectangle)(
    513     Display	*dpy,
    514     int		screen,
    515     int		x,
    516     int		y,
    517     unsigned int	width,
    518     unsigned int	height,
    519     unsigned long	color
    520 ){
    521     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    522     xXDGAFillRectangleReq *req;
    523 
    524     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    525 
    526     LockDisplay(dpy);
    527     GetReq(XDGAFillRectangle, req);
    528     req->reqType = info->codes->major_opcode;
    529     req->dgaReqType = X_XDGAFillRectangle;
    530     req->screen = screen;
    531     req->x = x;
    532     req->y = y;
    533     req->width = width;
    534     req->height = height;
    535     req->color = color;
    536     UnlockDisplay(dpy);
    537     SyncHandle();
    538 }
    539 
    540 void SDL_NAME(XDGACopyArea)(
    541     Display	*dpy,
    542     int		screen,
    543     int		srcx,
    544     int		srcy,
    545     unsigned int	width,
    546     unsigned int	height,
    547     int		dstx,
    548     int		dsty
    549 ){
    550     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    551     xXDGACopyAreaReq *req;
    552 
    553     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    554 
    555     LockDisplay(dpy);
    556     GetReq(XDGACopyArea, req);
    557     req->reqType = info->codes->major_opcode;
    558     req->dgaReqType = X_XDGACopyArea;
    559     req->screen = screen;
    560     req->srcx = srcx;
    561     req->srcy = srcy;
    562     req->width = width;
    563     req->height = height;
    564     req->dstx = dstx;
    565     req->dsty = dsty;
    566     UnlockDisplay(dpy);
    567     SyncHandle();
    568 }
    569 
    570 void SDL_NAME(XDGACopyTransparentArea)(
    571     Display	*dpy,
    572     int		screen,
    573     int		srcx,
    574     int		srcy,
    575     unsigned int	width,
    576     unsigned int	height,
    577     int		dstx,
    578     int		dsty,
    579     unsigned long key
    580 ){
    581     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    582     xXDGACopyTransparentAreaReq *req;
    583 
    584     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    585 
    586     LockDisplay(dpy);
    587     GetReq(XDGACopyTransparentArea, req);
    588     req->reqType = info->codes->major_opcode;
    589     req->dgaReqType = X_XDGACopyTransparentArea;
    590     req->screen = screen;
    591     req->srcx = srcx;
    592     req->srcy = srcy;
    593     req->width = width;
    594     req->height = height;
    595     req->dstx = dstx;
    596     req->dsty = dsty;
    597     req->key = key;
    598     UnlockDisplay(dpy);
    599     SyncHandle();
    600 }
    601 
    602 
    603 int SDL_NAME(XDGAGetViewportStatus)(
    604     Display *dpy,
    605     int screen
    606 ){
    607     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    608     xXDGAGetViewportStatusReply rep;
    609     xXDGAGetViewportStatusReq *req;
    610     int status = 0;
    611 
    612     XDGACheckExtension (dpy, info, 0);
    613 
    614     LockDisplay(dpy);
    615     GetReq(XDGAGetViewportStatus, req);
    616     req->reqType = info->codes->major_opcode;
    617     req->dgaReqType = X_XDGAGetViewportStatus;
    618     req->screen = screen;
    619     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
    620 	status = rep.status;
    621     UnlockDisplay(dpy);
    622     SyncHandle();
    623     return status;
    624 }
    625 
    626 void SDL_NAME(XDGASync)(
    627     Display *dpy,
    628     int screen
    629 ){
    630     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    631     xXDGASyncReply rep;
    632     xXDGASyncReq *req;
    633 
    634     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    635 
    636     LockDisplay(dpy);
    637     GetReq(XDGASync, req);
    638     req->reqType = info->codes->major_opcode;
    639     req->dgaReqType = X_XDGASync;
    640     req->screen = screen;
    641     _XReply(dpy, (xReply *)&rep, 0, xFalse);
    642     UnlockDisplay(dpy);
    643     SyncHandle();
    644 }
    645 
    646 
    647 void SDL_NAME(XDGAChangePixmapMode)(
    648     Display *dpy,
    649     int screen,
    650     int *x,
    651     int *y,
    652     int mode
    653 ){
    654     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    655     xXDGAChangePixmapModeReq *req;
    656     xXDGAChangePixmapModeReply rep;
    657 
    658     XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
    659 
    660     LockDisplay(dpy);
    661     GetReq(XDGAChangePixmapMode, req);
    662     req->reqType = info->codes->major_opcode;
    663     req->dgaReqType = X_XDGAChangePixmapMode;
    664     req->screen = screen;
    665     req->x = *x;
    666     req->y = *y;
    667     req->flags = mode;
    668     _XReply(dpy, (xReply *)&rep, 0, xFalse);
    669     *x = rep.x;
    670     *y = rep.y;
    671     UnlockDisplay(dpy);
    672     SyncHandle();
    673 }
    674 
    675 Colormap SDL_NAME(XDGACreateColormap)(
    676     Display *dpy,
    677     int screen,
    678     SDL_NAME(XDGADevice) *dev,
    679     int	alloc
    680 ){
    681     XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
    682     xXDGACreateColormapReq *req;
    683     Colormap cid;
    684 
    685     XDGACheckExtension (dpy, info, -1);
    686 
    687     LockDisplay(dpy);
    688     GetReq(XDGACreateColormap, req);
    689     req->reqType = info->codes->major_opcode;
    690     req->dgaReqType = X_XDGACreateColormap;
    691     req->screen = screen;
    692     req->mode = dev->mode.num;
    693     req->alloc = alloc;
    694     cid = req->id = XAllocID(dpy);
    695     UnlockDisplay(dpy);
    696     SyncHandle();
    697 
    698     return cid;
    699 }
    700 
    701 
    702 void SDL_NAME(XDGAKeyEventToXKeyEvent)(
    703     SDL_NAME(XDGAKeyEvent)* dk,
    704     XKeyEvent* xk
    705 ){
    706     xk->type = dk->type;
    707     xk->serial = dk->serial;
    708     xk->send_event = False;
    709     xk->display = dk->display;
    710     xk->window = RootWindow(dk->display, dk->screen);
    711     xk->root = xk->window;
    712     xk->subwindow = None;
    713     xk->time = dk->time;
    714     xk->x = xk->y = xk->x_root = xk->y_root = 0;
    715     xk->state = dk->state;
    716     xk->keycode = dk->keycode;
    717     xk->same_screen = True;
    718 }
    719 
    720 #include <X11/Xmd.h>
    721 #include <stdlib.h>
    722 #include <stdio.h>
    723 #include <fcntl.h>
    724 #if defined(ISC)
    725 # define HAS_SVR3_MMAP
    726 # include <sys/types.h>
    727 # include <errno.h>
    728 
    729 # include <sys/at_ansi.h>
    730 # include <sys/kd.h>
    731 
    732 # include <sys/sysmacros.h>
    733 # include <sys/immu.h>
    734 # include <sys/region.h>
    735 
    736 # include <sys/mmap.h>
    737 #else
    738 # if !defined(Lynx)
    739 #  if !defined(__EMX__)
    740 #   include <sys/mman.h>
    741 #  endif
    742 # else
    743 #  include <sys/types.h>
    744 #  include <errno.h>
    745 #  include <smem.h>
    746 # endif
    747 #endif
    748 #include <sys/wait.h>
    749 #include <signal.h>
    750 #include <unistd.h>
    751 
    752 #if defined(SVR4) && !defined(sun) && !defined(SCO325)
    753 #define DEV_MEM "/dev/pmem"
    754 #elif defined(SVR4) && defined(sun)
    755 #define DEV_MEM "/dev/xsvc"
    756 #else
    757 #define DEV_MEM "/dev/mem"
    758 #endif
    759 
    760 
    761 
    762 typedef struct _DGAMapRec{
    763   unsigned char *physical;
    764   unsigned char *virtual;
    765   CARD32 size;
    766   int fd;
    767   int screen;
    768   struct _DGAMapRec *next;
    769 } DGAMapRec, *DGAMapPtr;
    770 
    771 static Bool
    772 DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
    773 static void DGAUnmapPhysical(DGAMapPtr);
    774 
    775 static DGAMapPtr _Maps = NULL;
    776 
    777 
    778 unsigned char*
    779 SDL_NAME(XDGAGetMappedMemory)(int screen)
    780 {
    781     DGAMapPtr pMap = _Maps;
    782     unsigned char *pntr = NULL;
    783 
    784     while(pMap != NULL) {
    785 	if(pMap->screen == screen) {
    786 	    pntr = pMap->virtual;
    787 	    break;
    788 	}
    789 	pMap = pMap->next;
    790     }
    791 
    792     return pntr;
    793 }
    794 
    795 Bool
    796 SDL_NAME(XDGAMapFramebuffer)(
    797    int screen,
    798    char *name,			/* optional device name */
    799    unsigned char* base,		/* physical memory */
    800    CARD32 size,			/* size */
    801    CARD32 offset,		/* optional offset */
    802    CARD32 extra			/* optional extra data */
    803 ){
    804    DGAMapPtr pMap = _Maps;
    805    Bool result;
    806 
    807    /* is it already mapped ? */
    808    while(pMap != NULL) {
    809      if(pMap->screen == screen)
    810 	return True;
    811      pMap = pMap->next;
    812    }
    813 
    814    if(extra & XDGANeedRoot) {
    815     /* we should probably check if we have root permissions and
    816        return False here */
    817 
    818    }
    819 
    820    pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
    821 
    822    result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
    823 
    824    if(result) {
    825       pMap->next = _Maps;
    826       _Maps = pMap;
    827    } else
    828       Xfree(pMap);
    829 
    830    return result;
    831 }
    832 
    833 void
    834 SDL_NAME(XDGAUnmapFramebuffer)(int screen)
    835 {
    836    DGAMapPtr pMap = _Maps;
    837    DGAMapPtr pPrev = NULL;
    838 
    839    /* is it already mapped */
    840     while(pMap != NULL) {
    841 	if(pMap->screen == screen)
    842 	    break;
    843 	pPrev = pMap;
    844 	pMap = pMap->next;
    845     }
    846 
    847     if(!pMap)
    848 	return;
    849 
    850     DGAUnmapPhysical(pMap);
    851 
    852     if(!pPrev)
    853 	_Maps = pMap->next;
    854     else
    855 	pPrev->next = pMap->next;
    856 
    857     Xfree(pMap);
    858 }
    859 
    860 
    861 static Bool
    862 DGAMapPhysical(
    863    int screen,
    864    char *name,			/* optional device name */
    865    unsigned char* base,		/* physical memory */
    866    CARD32 size,			/* size */
    867    CARD32 offset,		/* optional offset */
    868    CARD32 extra,		/* optional extra data */
    869    DGAMapPtr pMap
    870 ) {
    871 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    872     struct kd_memloc mloc;
    873 #elif defined(__EMX__)
    874     APIRET rc;
    875     ULONG action;
    876     HFILE hfd;
    877 #endif
    878 
    879     base += offset;
    880 
    881     pMap->screen = screen;
    882     pMap->physical = base;
    883     pMap->size = size;
    884 
    885 #if defined(ISC) && defined(HAS_SVR3_MMAP)
    886     if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
    887 	return False;
    888     mloc.vaddr = (char *)0;
    889     mloc.physaddr = (char *)base;
    890     mloc.length = size;
    891     mloc.ioflg=1;
    892 
    893     if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
    894 	return False;
    895 #elif defined (__EMX__)
    896     /*
    897      * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
    898      * Consecutive calling of this routine will make PMAP$ driver run out
    899      * of memory handles. Some umap/close mechanism should be provided
    900      */
    901 
    902     rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
    903 		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
    904     if (rc != 0)
    905 	return False;
    906     {
    907 	struct map_ioctl {
    908 		union {
    909 			ULONG phys;
    910 			void* user;
    911 		} a;
    912 		ULONG size;
    913 	} pmap,dmap;
    914 	ULONG plen,dlen;
    915 #define XFREE86_PMAP	0x76
    916 #define PMAP_MAP	0x44
    917 
    918 	pmap.a.phys = base;
    919 	pmap.size = size;
    920 	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
    921 			 (PULONG)&pmap, sizeof(pmap), &plen,
    922 			 (PULONG)&dmap, sizeof(dmap), &dlen);
    923 	if (rc == 0) {
    924 		pMap->virtual = dmap.a.user;
    925 	}
    926    }
    927    if (rc != 0)
    928 	return False;
    929 #elif defined (Lynx)
    930     pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
    931 #else
    932 #ifndef MAP_FILE
    933 #define MAP_FILE 0
    934 #endif
    935     if (!name)
    936 	    name = DEV_MEM;
    937     if ((pMap->fd = open(name, O_RDWR)) < 0)
    938 #if defined(ENABLE_FBCON)
    939     { /* /dev/fb0 fallback added by Sam Lantinga <hercules (at) lokigames.com> */
    940         /* Try to fall back to /dev/fb on Linux - FIXME: verify the device */
    941         struct fb_fix_screeninfo finfo;
    942 
    943         if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) {
    944             return False;
    945         }
    946         /* The useable framebuffer console memory may not be the whole
    947            framebuffer that X has access to. :-(
    948          */
    949         if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
    950             close(pMap->fd);
    951             return False;
    952         }
    953         /* Warning: On PPC, the size and virtual need to be offset by:
    954            (((long)finfo.smem_start) -
    955            (((long)finfo.smem_start)&~(PAGE_SIZE-1)))
    956          */
    957         base = 0;
    958         size = pMap->size = finfo.smem_len;
    959     }
    960 #else
    961 	return False;
    962 #endif
    963     pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
    964 			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)((size_t)base));
    965     if (pMap->virtual == (void *)-1)
    966 	return False;
    967 #endif
    968 
    969 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    970 	&& !defined(__EMX__)
    971     mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
    972 #endif
    973 
    974     return True;
    975 }
    976 
    977 
    978 
    979 static void
    980 DGAUnmapPhysical(DGAMapPtr pMap)
    981 {
    982 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
    983 	&& !defined(__EMX__)
    984     mprotect(pMap->virtual,pMap->size, PROT_READ);
    985 #elif defined(Lynx)
    986 	/* XXX this doesn't allow enable after disable */
    987     smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
    988     smem_remove("XF86DGA");
    989 #endif
    990 
    991 
    992    /* We need to unmap and close too !!!!!!!!!!*/
    993 }
    994