Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright (c) 1995  Jon Tombs
      4 Copyright (c) 1995,1996  The XFree86 Project, Inc
      5 
      6 */
      7 
      8 /* THIS IS NOT AN X CONSORTIUM STANDARD */
      9 #ifdef HAVE_CONFIG_H
     10 #include <config.h>
     11 #endif
     12 
     13 
     14 #include <X11/Xlibint.h>
     15 #include <X11/extensions/Xxf86dga.h>
     16 #include <X11/extensions/xf86dgaproto.h>
     17 #include <X11/extensions/Xext.h>
     18 #include <X11/extensions/extutil.h>
     19 #include <stdio.h>
     20 
     21 #include <stdint.h>
     22 #include <limits.h>
     23 
     24 /* If you change this, change the Bases[] array below as well */
     25 #define MAX_HEADS 16
     26 
     27 const char *xdga_extension_name = XF86DGANAME;
     28 
     29 static XExtensionInfo _xdga_info_data;
     30 static XExtensionInfo *xdga_info = &_xdga_info_data;
     31 
     32 
     33 Bool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32);
     34 void XDGAUnmapFramebuffer(int);
     35 unsigned char* XDGAGetMappedMemory(int);
     36 
     37 #define XDGACheckExtension(dpy,i,val) \
     38   XextCheckExtension (dpy, i, xdga_extension_name, val)
     39 
     40 /*****************************************************************************
     41  *                                                                           *
     42  *			   private utility routines                          *
     43  *                                                                           *
     44  *****************************************************************************/
     45 
     46 static int xdga_close_display(Display *dpy, XExtCodes *codes);
     47 static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
     48 static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
     49 
     50 static XExtensionHooks xdga_extension_hooks = {
     51     NULL,				/* create_gc */
     52     NULL,				/* copy_gc */
     53     NULL,				/* flush_gc */
     54     NULL,				/* free_gc */
     55     NULL,				/* create_font */
     56     NULL,				/* free_font */
     57     xdga_close_display,			/* close_display */
     58     xdga_wire_to_event,			/* wire_to_event */
     59     xdga_event_to_wire,			/* event_to_wire */
     60     NULL,				/* error */
     61     NULL,				/* error_string */
     62 };
     63 
     64 static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
     65 
     66 
     67 XExtDisplayInfo* xdga_find_display(Display*);
     68 XEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info,
     69 				   "XFree86-DGA",
     70 				   &xdga_extension_hooks,
     71 				   0, NULL)
     72 
     73 
     74 static Status
     75 xdga_event_to_wire(
     76   Display *dpy,
     77   XEvent *event,
     78   xEvent *wire_ev
     79 ){
     80     return True;
     81 }
     82 
     83 static Bool
     84 xdga_wire_to_event(
     85   Display *dpy,
     86   XEvent *event,
     87   xEvent *wire_ev
     88 ){
     89   dgaEvent *wire = (dgaEvent *) wire_ev;
     90   XDGAButtonEvent *bevent;
     91   XDGAKeyEvent *kevent;
     92   XDGAMotionEvent *mevent;
     93   XExtDisplayInfo *info = xdga_find_display (dpy);
     94 
     95   XDGACheckExtension (dpy, info, False);
     96 
     97   switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
     98   case MotionNotify:
     99 	mevent = (XDGAMotionEvent*)event;
    100 	mevent->type = wire->u.u.type & 0x7F;
    101 	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    102 	mevent->display = dpy;
    103 	mevent->screen = wire->u.event.screen;
    104 	mevent->time = wire->u.event.time;
    105 	mevent->state = wire->u.event.state;
    106 	mevent->dx = wire->u.event.dx;
    107 	mevent->dy = wire->u.event.dy;
    108 	return True;
    109   case ButtonPress:
    110   case ButtonRelease:
    111 	bevent = (XDGAButtonEvent*)event;
    112 	bevent->type = wire->u.u.type & 0x7F;
    113 	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    114 	bevent->display = dpy;
    115 	bevent->screen = wire->u.event.screen;
    116 	bevent->time = wire->u.event.time;
    117 	bevent->state = wire->u.event.state;
    118 	bevent->button = wire->u.u.detail;
    119 	return True;
    120   case KeyPress:
    121   case KeyRelease:
    122 	kevent = (XDGAKeyEvent*)event;
    123 	kevent->type = wire->u.u.type & 0x7F;
    124 	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
    125 	kevent->display = dpy;
    126 	kevent->screen = wire->u.event.screen;
    127 	kevent->time = wire->u.event.time;
    128 	kevent->state = wire->u.event.state;
    129 	kevent->keycode = wire->u.u.detail;
    130 	return True;
    131   }
    132 
    133   return False;
    134 }
    135 
    136 
    137 Bool XDGAQueryExtension (
    138     Display *dpy,
    139     int *event_basep,
    140     int *error_basep
    141 ){
    142     XExtDisplayInfo *info = xdga_find_display (dpy);
    143 
    144     if (XextHasExtension(info)) {
    145 	*event_basep = info->codes->first_event;
    146 	*error_basep = info->codes->first_error;
    147 	return True;
    148     } else {
    149 	return False;
    150     }
    151 }
    152 
    153 
    154 Bool XDGAQueryVersion(
    155     Display *dpy,
    156     int *majorVersion,
    157     int *minorVersion
    158 ){
    159     XExtDisplayInfo *info = xdga_find_display (dpy);
    160     xXDGAQueryVersionReply rep;
    161     xXDGAQueryVersionReq *req;
    162 
    163     XDGACheckExtension (dpy, info, False);
    164 
    165     LockDisplay(dpy);
    166     GetReq(XDGAQueryVersion, req);
    167     req->reqType = info->codes->major_opcode;
    168     req->dgaReqType = X_XDGAQueryVersion;
    169     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    170 	UnlockDisplay(dpy);
    171 	SyncHandle();
    172 	return False;
    173     }
    174     *majorVersion = rep.majorVersion;
    175     *minorVersion = rep.minorVersion;
    176     UnlockDisplay(dpy);
    177     SyncHandle();
    178     if (*majorVersion >= 2)
    179     {
    180 	int i, j;
    181 
    182 	for (i = 0, j = info->codes->first_event;
    183 	     i < XF86DGANumberEvents;
    184 	     i++, j++)
    185 	{
    186 	    XESetWireToEvent (dpy, j, xdga_wire_to_event);
    187 	    XESetEventToWire (dpy, j, xdga_event_to_wire);
    188 	}
    189 	XDGASetClientVersion(dpy);
    190     }
    191     return True;
    192 }
    193 
    194 Bool XDGASetClientVersion(
    195     Display	*dpy
    196 ){
    197     XExtDisplayInfo *info = xdga_find_display (dpy);
    198     xXDGASetClientVersionReq *req;
    199 
    200     XDGACheckExtension (dpy, info, False);
    201 
    202     LockDisplay(dpy);
    203     GetReq(XDGASetClientVersion, req);
    204     req->reqType = info->codes->major_opcode;
    205     req->dgaReqType = X_XDGASetClientVersion;
    206     req->major = XDGA_MAJOR_VERSION;
    207     req->minor = XDGA_MINOR_VERSION;
    208     UnlockDisplay(dpy);
    209     SyncHandle();
    210     return True;
    211 }
    212 
    213 Bool XDGAOpenFramebuffer(
    214     Display	*dpy,
    215     int 	screen
    216 ){
    217     XExtDisplayInfo *info = xdga_find_display (dpy);
    218     xXDGAOpenFramebufferReply rep;
    219     xXDGAOpenFramebufferReq *req;
    220     char *deviceName = NULL;
    221     Bool ret;
    222 
    223     XDGACheckExtension (dpy, info, False);
    224 
    225     LockDisplay(dpy);
    226     GetReq(XDGAOpenFramebuffer, req);
    227     req->reqType = info->codes->major_opcode;
    228     req->dgaReqType = X_XDGAOpenFramebuffer;
    229     req->screen = screen;
    230     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    231 	UnlockDisplay(dpy);
    232 	SyncHandle();
    233 	return False;
    234     }
    235 
    236     if (rep.length) {
    237 	if (rep.length < (INT_MAX >> 2)) {
    238 	    unsigned long size = rep.length << 2;
    239 	    deviceName = Xmalloc(size);
    240 	    _XRead(dpy, deviceName, size);
    241 	    deviceName[size - 1] = '\0';
    242 	} else
    243 	    _XEatDataWords(dpy, rep.length);
    244     }
    245 
    246     ret = XDGAMapFramebuffer(screen, deviceName,
    247 				(unsigned char*)(long)rep.mem1,
    248 				rep.size, rep.offset, rep.extra);
    249 
    250     if(deviceName)
    251 	Xfree(deviceName);
    252 
    253     UnlockDisplay(dpy);
    254     SyncHandle();
    255     return ret;
    256 }
    257 
    258 void XDGACloseFramebuffer(
    259     Display	*dpy,
    260     int		screen
    261 ){
    262     XExtDisplayInfo *info = xdga_find_display (dpy);
    263     xXDGACloseFramebufferReq *req;
    264 
    265     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    266 
    267     XDGAUnmapFramebuffer(screen);
    268 
    269     LockDisplay(dpy);
    270     GetReq(XDGACloseFramebuffer, req);
    271     req->reqType = info->codes->major_opcode;
    272     req->dgaReqType = X_XDGACloseFramebuffer;
    273     req->screen = screen;
    274     UnlockDisplay(dpy);
    275     SyncHandle();
    276 }
    277 
    278 
    279 
    280 XDGAMode* XDGAQueryModes(
    281     Display *dpy,
    282     int screen,
    283     int *num
    284 ){
    285     XExtDisplayInfo *dinfo = xdga_find_display (dpy);
    286     xXDGAQueryModesReply rep;
    287     xXDGAQueryModesReq *req;
    288     XDGAMode *modes = NULL;
    289 
    290     *num = 0;
    291 
    292     XDGACheckExtension (dpy, dinfo, NULL);
    293 
    294     LockDisplay(dpy);
    295     GetReq(XDGAQueryModes, req);
    296     req->reqType = dinfo->codes->major_opcode;
    297     req->dgaReqType = X_XDGAQueryModes;
    298     req->screen = screen;
    299 
    300     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    301 	if(rep.length) {
    302 	   xXDGAModeInfo info;
    303 	   unsigned long size = 0;
    304 	   char *offset;
    305 
    306 	   if ((rep.length < (INT_MAX >> 2)) &&
    307 	       (rep.number < (INT_MAX / sizeof(XDGAMode)))) {
    308 	       size = rep.length << 2;
    309 	       if (size > (rep.number * sz_xXDGAModeInfo)) {
    310 		   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
    311 		   modes = Xmalloc((rep.number * sizeof(XDGAMode)) + size);
    312 		   offset = (char*)(&modes[rep.number]);  /* start of text */
    313 	       }
    314 	   }
    315 
    316 	   if (modes != NULL) {
    317 	      unsigned int i;
    318 	      for(i = 0; i < rep.number; i++) {
    319 		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
    320 
    321 		modes[i].num = info.num;
    322 		modes[i].verticalRefresh =
    323 			(float)info.vsync_num / (float)info.vsync_den;
    324 		modes[i].flags = info.flags;
    325 		modes[i].imageWidth = info.image_width;
    326 		modes[i].imageHeight = info.image_height;
    327 		modes[i].pixmapWidth = info.pixmap_width;
    328 		modes[i].pixmapHeight = info.pixmap_height;
    329 		modes[i].bytesPerScanline = info.bytes_per_scanline;
    330 		modes[i].byteOrder = info.byte_order;
    331 		modes[i].depth = info.depth;
    332 		modes[i].bitsPerPixel = info.bpp;
    333 		modes[i].redMask = info.red_mask;
    334 		modes[i].greenMask = info.green_mask;
    335 		modes[i].blueMask = info.blue_mask;
    336 		modes[i].visualClass = info.visual_class;
    337 		modes[i].viewportWidth = info.viewport_width;
    338 		modes[i].viewportHeight = info.viewport_height;
    339 		modes[i].xViewportStep = info.viewport_xstep;
    340 		modes[i].yViewportStep = info.viewport_ystep;
    341 		modes[i].maxViewportX = info.viewport_xmax;
    342 		modes[i].maxViewportY = info.viewport_ymax;
    343 		modes[i].viewportFlags = info.viewport_flags;
    344 		modes[i].reserved1 = info.reserved1;
    345 		modes[i].reserved2 = info.reserved2;
    346 
    347 		if (info.name_size > 0 && info.name_size <= size) {
    348 		    _XRead(dpy, offset, info.name_size);
    349 		    modes[i].name = offset;
    350 		    modes[i].name[info.name_size - 1] = '\0';
    351 		    offset += info.name_size;
    352 		    size -= info.name_size;
    353 		} else {
    354 		    _XEatData(dpy, info.name_size);
    355 		    modes[i].name = NULL;
    356 		}
    357 	      }
    358 	      *num = rep.number;
    359 	   } else
    360 		_XEatDataWords(dpy, rep.length);
    361 	}
    362     }
    363 
    364     UnlockDisplay(dpy);
    365     SyncHandle();
    366 
    367     return modes;
    368 }
    369 
    370 
    371 XDGADevice *
    372 XDGASetMode(
    373     Display	*dpy,
    374     int		screen,
    375     int		mode
    376 ){
    377     XExtDisplayInfo *dinfo = xdga_find_display (dpy);
    378     xXDGASetModeReply rep;
    379     xXDGASetModeReq *req;
    380     XDGADevice *dev = NULL;
    381     Pixmap pid;
    382 
    383     XDGACheckExtension (dpy, dinfo, NULL);
    384 
    385     LockDisplay(dpy);
    386     GetReq(XDGASetMode, req);
    387     req->reqType = dinfo->codes->major_opcode;
    388     req->dgaReqType = X_XDGASetMode;
    389     req->screen = screen;
    390     req->mode = mode;
    391     req->pid = pid = XAllocID(dpy);
    392 
    393     if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
    394 	if(rep.length) {
    395 	   xXDGAModeInfo info;
    396 	   unsigned long size;
    397 
    398 	   if ((rep.length < (INT_MAX >> 2)) &&
    399 	       (rep.length > (sz_xXDGAModeInfo >> 2))) {
    400 	       size = rep.length << 2;
    401 	       size -= sz_xXDGAModeInfo; /* get text size */
    402 
    403 	       dev = Xmalloc(sizeof(XDGADevice) + size);
    404 	   }
    405 
    406 	   if(dev) {
    407 		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
    408 
    409 		dev->mode.num = info.num;
    410 		dev->mode.verticalRefresh =
    411 				(float)info.vsync_num / (float)info.vsync_den;
    412 		dev->mode.flags = info.flags;
    413 		dev->mode.imageWidth = info.image_width;
    414 		dev->mode.imageHeight = info.image_height;
    415 		dev->mode.pixmapWidth = info.pixmap_width;
    416 		dev->mode.pixmapHeight = info.pixmap_height;
    417 		dev->mode.bytesPerScanline = info.bytes_per_scanline;
    418 		dev->mode.byteOrder = info.byte_order;
    419 		dev->mode.depth = info.depth;
    420 		dev->mode.bitsPerPixel = info.bpp;
    421 		dev->mode.redMask = info.red_mask;
    422 		dev->mode.greenMask = info.green_mask;
    423 		dev->mode.blueMask = info.blue_mask;
    424 		dev->mode.visualClass = info.visual_class;
    425 		dev->mode.viewportWidth = info.viewport_width;
    426 		dev->mode.viewportHeight = info.viewport_height;
    427 		dev->mode.xViewportStep = info.viewport_xstep;
    428 		dev->mode.yViewportStep = info.viewport_ystep;
    429 		dev->mode.maxViewportX = info.viewport_xmax;
    430 		dev->mode.maxViewportY = info.viewport_ymax;
    431 		dev->mode.viewportFlags = info.viewport_flags;
    432 		dev->mode.reserved1 = info.reserved1;
    433 		dev->mode.reserved2 = info.reserved2;
    434 
    435 		if (info.name_size > 0 && info.name_size <= size) {
    436 		    dev->mode.name = (char*)(&dev[1]);
    437 		    _XRead(dpy, dev->mode.name, info.name_size);
    438 		    dev->mode.name[info.name_size - 1] = '\0';
    439 		} else {
    440 		    dev->mode.name = NULL;
    441 		    _XEatDataWords(dpy, rep.length);
    442 		}
    443 
    444 		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
    445 		dev->data = XDGAGetMappedMemory(screen);
    446 
    447 		if(dev->data)
    448 		    dev->data += rep.offset;
    449 	   }
    450 	   /* not sure what to do if the allocation fails */
    451 	   else
    452 	       _XEatDataWords(dpy, rep.length);
    453 	}
    454     }
    455 
    456     UnlockDisplay(dpy);
    457     SyncHandle();
    458 
    459     return dev;
    460 }
    461 
    462 
    463 void XDGASetViewport(
    464     Display	*dpy,
    465     int		screen,
    466     int		x,
    467     int		y,
    468     int		flags
    469 ){
    470     XExtDisplayInfo *info = xdga_find_display (dpy);
    471     xXDGASetViewportReq *req;
    472 
    473     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    474 
    475     LockDisplay(dpy);
    476     GetReq(XDGASetViewport, req);
    477     req->reqType = info->codes->major_opcode;
    478     req->dgaReqType = X_XDGASetViewport;
    479     req->screen = screen;
    480     req->x = x;
    481     req->y = y;
    482     req->flags = flags;
    483     UnlockDisplay(dpy);
    484     SyncHandle();
    485 }
    486 
    487 
    488 void XDGAInstallColormap(
    489     Display	*dpy,
    490     int		screen,
    491     Colormap	cmap
    492 ){
    493     XExtDisplayInfo *info = xdga_find_display (dpy);
    494     xXDGAInstallColormapReq *req;
    495 
    496     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    497 
    498     LockDisplay(dpy);
    499     GetReq(XDGAInstallColormap, req);
    500     req->reqType = info->codes->major_opcode;
    501     req->dgaReqType = X_XDGAInstallColormap;
    502     req->screen = screen;
    503     req->cmap = cmap;
    504     UnlockDisplay(dpy);
    505     SyncHandle();
    506 }
    507 
    508 void XDGASelectInput(
    509     Display	*dpy,
    510     int		screen,
    511     long	mask
    512 ){
    513     XExtDisplayInfo *info = xdga_find_display (dpy);
    514     xXDGASelectInputReq *req;
    515 
    516     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    517 
    518     LockDisplay(dpy);
    519     GetReq(XDGASelectInput, req);
    520     req->reqType = info->codes->major_opcode;
    521     req->dgaReqType = X_XDGASelectInput;
    522     req->screen = screen;
    523     req->mask = mask;
    524     UnlockDisplay(dpy);
    525     SyncHandle();
    526 }
    527 
    528 void XDGAFillRectangle(
    529     Display	*dpy,
    530     int		screen,
    531     int		x,
    532     int		y,
    533     unsigned int	width,
    534     unsigned int	height,
    535     unsigned long	color
    536 ){
    537     XExtDisplayInfo *info = xdga_find_display (dpy);
    538     xXDGAFillRectangleReq *req;
    539 
    540     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    541 
    542     LockDisplay(dpy);
    543     GetReq(XDGAFillRectangle, req);
    544     req->reqType = info->codes->major_opcode;
    545     req->dgaReqType = X_XDGAFillRectangle;
    546     req->screen = screen;
    547     req->x = x;
    548     req->y = y;
    549     req->width = width;
    550     req->height = height;
    551     req->color = color;
    552     UnlockDisplay(dpy);
    553     SyncHandle();
    554 }
    555 
    556 void XDGACopyArea(
    557     Display	*dpy,
    558     int		screen,
    559     int		srcx,
    560     int		srcy,
    561     unsigned int	width,
    562     unsigned int	height,
    563     int		dstx,
    564     int		dsty
    565 ){
    566     XExtDisplayInfo *info = xdga_find_display (dpy);
    567     xXDGACopyAreaReq *req;
    568 
    569     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    570 
    571     LockDisplay(dpy);
    572     GetReq(XDGACopyArea, req);
    573     req->reqType = info->codes->major_opcode;
    574     req->dgaReqType = X_XDGACopyArea;
    575     req->screen = screen;
    576     req->srcx = srcx;
    577     req->srcy = srcy;
    578     req->width = width;
    579     req->height = height;
    580     req->dstx = dstx;
    581     req->dsty = dsty;
    582     UnlockDisplay(dpy);
    583     SyncHandle();
    584 }
    585 
    586 void XDGACopyTransparentArea(
    587     Display	*dpy,
    588     int		screen,
    589     int		srcx,
    590     int		srcy,
    591     unsigned int	width,
    592     unsigned int	height,
    593     int		dstx,
    594     int		dsty,
    595     unsigned long key
    596 ){
    597     XExtDisplayInfo *info = xdga_find_display (dpy);
    598     xXDGACopyTransparentAreaReq *req;
    599 
    600     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    601 
    602     LockDisplay(dpy);
    603     GetReq(XDGACopyTransparentArea, req);
    604     req->reqType = info->codes->major_opcode;
    605     req->dgaReqType = X_XDGACopyTransparentArea;
    606     req->screen = screen;
    607     req->srcx = srcx;
    608     req->srcy = srcy;
    609     req->width = width;
    610     req->height = height;
    611     req->dstx = dstx;
    612     req->dsty = dsty;
    613     req->key = key;
    614     UnlockDisplay(dpy);
    615     SyncHandle();
    616 }
    617 
    618 
    619 int XDGAGetViewportStatus(
    620     Display *dpy,
    621     int screen
    622 ){
    623     XExtDisplayInfo *info = xdga_find_display (dpy);
    624     xXDGAGetViewportStatusReply rep;
    625     xXDGAGetViewportStatusReq *req;
    626     int status = 0;
    627 
    628     XDGACheckExtension (dpy, info, 0);
    629 
    630     LockDisplay(dpy);
    631     GetReq(XDGAGetViewportStatus, req);
    632     req->reqType = info->codes->major_opcode;
    633     req->dgaReqType = X_XDGAGetViewportStatus;
    634     req->screen = screen;
    635     if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
    636 	status = rep.status;
    637     UnlockDisplay(dpy);
    638     SyncHandle();
    639     return status;
    640 }
    641 
    642 void XDGASync(
    643     Display *dpy,
    644     int screen
    645 ){
    646     XExtDisplayInfo *info = xdga_find_display (dpy);
    647     xXDGASyncReply rep;
    648     xXDGASyncReq *req;
    649 
    650     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    651 
    652     LockDisplay(dpy);
    653     GetReq(XDGASync, req);
    654     req->reqType = info->codes->major_opcode;
    655     req->dgaReqType = X_XDGASync;
    656     req->screen = screen;
    657     _XReply(dpy, (xReply *)&rep, 0, xFalse);
    658     UnlockDisplay(dpy);
    659     SyncHandle();
    660 }
    661 
    662 
    663 void XDGAChangePixmapMode(
    664     Display *dpy,
    665     int screen,
    666     int *x,
    667     int *y,
    668     int mode
    669 ){
    670     XExtDisplayInfo *info = xdga_find_display (dpy);
    671     xXDGAChangePixmapModeReq *req;
    672     xXDGAChangePixmapModeReply rep;
    673 
    674     XextSimpleCheckExtension (dpy, info, xdga_extension_name);
    675 
    676     LockDisplay(dpy);
    677     GetReq(XDGAChangePixmapMode, req);
    678     req->reqType = info->codes->major_opcode;
    679     req->dgaReqType = X_XDGAChangePixmapMode;
    680     req->screen = screen;
    681     req->x = *x;
    682     req->y = *y;
    683     req->flags = mode;
    684     _XReply(dpy, (xReply *)&rep, 0, xFalse);
    685     *x = rep.x;
    686     *y = rep.y;
    687     UnlockDisplay(dpy);
    688     SyncHandle();
    689 }
    690 
    691 Colormap XDGACreateColormap(
    692     Display *dpy,
    693     int screen,
    694     XDGADevice *dev,
    695     int	alloc
    696 ){
    697     XExtDisplayInfo *info = xdga_find_display (dpy);
    698     xXDGACreateColormapReq *req;
    699     Colormap cid;
    700 
    701     XDGACheckExtension (dpy, info, -1);
    702 
    703     LockDisplay(dpy);
    704     GetReq(XDGACreateColormap, req);
    705     req->reqType = info->codes->major_opcode;
    706     req->dgaReqType = X_XDGACreateColormap;
    707     req->screen = screen;
    708     req->mode = dev->mode.num;
    709     req->alloc = alloc;
    710     cid = req->id = XAllocID(dpy);
    711     UnlockDisplay(dpy);
    712     SyncHandle();
    713 
    714     return cid;
    715 }
    716 
    717 
    718 void XDGAKeyEventToXKeyEvent(
    719     XDGAKeyEvent* dk,
    720     XKeyEvent* xk
    721 ){
    722     xk->type = dk->type;
    723     xk->serial = dk->serial;
    724     xk->send_event = False;
    725     xk->display = dk->display;
    726     xk->window = RootWindow(dk->display, dk->screen);
    727     xk->root = xk->window;
    728     xk->subwindow = None;
    729     xk->time = dk->time;
    730     xk->x = xk->y = xk->x_root = xk->y_root = 0;
    731     xk->state = dk->state;
    732     xk->keycode = dk->keycode;
    733     xk->same_screen = True;
    734 }
    735 
    736 #include <X11/Xmd.h>
    737 #include <stdlib.h>
    738 #include <stdio.h>
    739 #include <fcntl.h>
    740 #include <sys/mman.h>
    741 #include <sys/wait.h>
    742 #include <signal.h>
    743 #include <unistd.h>
    744 
    745 #if defined(SVR4) && !defined(sun)
    746 #define DEV_MEM "/dev/pmem"
    747 #elif defined(SVR4) && defined(sun)
    748 #define DEV_MEM "/dev/xsvc"
    749 #elif defined(HAS_APERTURE_DRV)
    750 #define DEV_MEM "/dev/xf86"
    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, const char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
    768 static void DGAUnmapPhysical(DGAMapPtr);
    769 
    770 static DGAMapPtr _Maps = NULL;
    771 
    772 
    773 unsigned char*
    774 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 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 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    const 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 
    867     base += offset;
    868 
    869     pMap->screen = screen;
    870     pMap->physical = base;
    871     pMap->size = size;
    872 
    873 #ifndef MAP_FILE
    874 #define MAP_FILE 0
    875 #endif
    876     if (!name)
    877 	    name = DEV_MEM;
    878     if ((pMap->fd = open(name, O_RDWR)) < 0)
    879 	return False;
    880     pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
    881 			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)(uintptr_t)base);
    882     if (pMap->virtual == (void *)-1)
    883 	return False;
    884     mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
    885 
    886     return True;
    887 }
    888 
    889 
    890 
    891 static void
    892 DGAUnmapPhysical(DGAMapPtr pMap)
    893 {
    894     if (pMap->virtual && pMap->virtual != (void *)-1) {
    895 	mprotect(pMap->virtual,pMap->size, PROT_READ);
    896 	munmap(pMap->virtual, pMap->size);
    897 	pMap->virtual = 0;
    898     }
    899     if (pMap->fd >= 0) {
    900 	close(pMap->fd);
    901 	pMap->fd = -1;
    902     }
    903 }
    904