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