18dd3e0eeSmrg/*
28dd3e0eeSmrg
38dd3e0eeSmrgCopyright (c) 1995  Jon Tombs
48dd3e0eeSmrgCopyright (c) 1995,1996  The XFree86 Project, Inc
58dd3e0eeSmrg
68dd3e0eeSmrg*/
78dd3e0eeSmrg
88dd3e0eeSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD */
9d5a688bcSmrg#ifdef HAVE_CONFIG_H
10d5a688bcSmrg#include <config.h>
11d5a688bcSmrg#endif
128dd3e0eeSmrg
138dd3e0eeSmrg
148dd3e0eeSmrg#include <X11/Xlibint.h>
15329fdfe9Smrg#include <X11/extensions/Xxf86dga.h>
16329fdfe9Smrg#include <X11/extensions/xf86dgaproto.h>
178dd3e0eeSmrg#include <X11/extensions/Xext.h>
188dd3e0eeSmrg#include <X11/extensions/extutil.h>
198dd3e0eeSmrg#include <stdio.h>
208dd3e0eeSmrg
21d5a688bcSmrg#include <stdint.h>
22d5a688bcSmrg#include <limits.h>
23d5a688bcSmrg
248dd3e0eeSmrg/* If you change this, change the Bases[] array below as well */
258dd3e0eeSmrg#define MAX_HEADS 16
268dd3e0eeSmrg
27d5a688bcSmrgconst char *xdga_extension_name = XF86DGANAME;
288dd3e0eeSmrg
298dd3e0eeSmrgstatic XExtensionInfo _xdga_info_data;
308dd3e0eeSmrgstatic XExtensionInfo *xdga_info = &_xdga_info_data;
318dd3e0eeSmrg
32d5a688bcSmrg
338dd3e0eeSmrgBool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32);
348dd3e0eeSmrgvoid XDGAUnmapFramebuffer(int);
358dd3e0eeSmrgunsigned char* XDGAGetMappedMemory(int);
368dd3e0eeSmrg
378dd3e0eeSmrg#define XDGACheckExtension(dpy,i,val) \
388dd3e0eeSmrg  XextCheckExtension (dpy, i, xdga_extension_name, val)
398dd3e0eeSmrg
408dd3e0eeSmrg/*****************************************************************************
418dd3e0eeSmrg *                                                                           *
428dd3e0eeSmrg *			   private utility routines                          *
438dd3e0eeSmrg *                                                                           *
448dd3e0eeSmrg *****************************************************************************/
458dd3e0eeSmrg
468dd3e0eeSmrgstatic int xdga_close_display(Display *dpy, XExtCodes *codes);
478dd3e0eeSmrgstatic Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
488dd3e0eeSmrgstatic Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
498dd3e0eeSmrg
508dd3e0eeSmrgstatic XExtensionHooks xdga_extension_hooks = {
518dd3e0eeSmrg    NULL,				/* create_gc */
528dd3e0eeSmrg    NULL,				/* copy_gc */
538dd3e0eeSmrg    NULL,				/* flush_gc */
548dd3e0eeSmrg    NULL,				/* free_gc */
558dd3e0eeSmrg    NULL,				/* create_font */
568dd3e0eeSmrg    NULL,				/* free_font */
578dd3e0eeSmrg    xdga_close_display,			/* close_display */
588dd3e0eeSmrg    xdga_wire_to_event,			/* wire_to_event */
598dd3e0eeSmrg    xdga_event_to_wire,			/* event_to_wire */
608dd3e0eeSmrg    NULL,				/* error */
618dd3e0eeSmrg    NULL,				/* error_string */
628dd3e0eeSmrg};
638dd3e0eeSmrg
648dd3e0eeSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
658dd3e0eeSmrg
668dd3e0eeSmrg
678dd3e0eeSmrgXExtDisplayInfo* xdga_find_display(Display*);
68d5a688bcSmrgXEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info,
69d5a688bcSmrg				   "XFree86-DGA",
70d5a688bcSmrg				   &xdga_extension_hooks,
718dd3e0eeSmrg				   0, NULL)
728dd3e0eeSmrg
738dd3e0eeSmrg
748dd3e0eeSmrgstatic Status
758dd3e0eeSmrgxdga_event_to_wire(
768dd3e0eeSmrg  Display *dpy,
778dd3e0eeSmrg  XEvent *event,
788dd3e0eeSmrg  xEvent *wire_ev
798dd3e0eeSmrg){
808dd3e0eeSmrg    return True;
818dd3e0eeSmrg}
828dd3e0eeSmrg
838dd3e0eeSmrgstatic Bool
848dd3e0eeSmrgxdga_wire_to_event(
858dd3e0eeSmrg  Display *dpy,
868dd3e0eeSmrg  XEvent *event,
878dd3e0eeSmrg  xEvent *wire_ev
888dd3e0eeSmrg){
898dd3e0eeSmrg  dgaEvent *wire = (dgaEvent *) wire_ev;
908dd3e0eeSmrg  XDGAButtonEvent *bevent;
918dd3e0eeSmrg  XDGAKeyEvent *kevent;
928dd3e0eeSmrg  XDGAMotionEvent *mevent;
938dd3e0eeSmrg  XExtDisplayInfo *info = xdga_find_display (dpy);
948dd3e0eeSmrg
958dd3e0eeSmrg  XDGACheckExtension (dpy, info, False);
968dd3e0eeSmrg
978dd3e0eeSmrg  switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
988dd3e0eeSmrg  case MotionNotify:
998dd3e0eeSmrg	mevent = (XDGAMotionEvent*)event;
1008dd3e0eeSmrg	mevent->type = wire->u.u.type & 0x7F;
1018dd3e0eeSmrg	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1028dd3e0eeSmrg	mevent->display = dpy;
1038dd3e0eeSmrg	mevent->screen = wire->u.event.screen;
1048dd3e0eeSmrg	mevent->time = wire->u.event.time;
1058dd3e0eeSmrg	mevent->state = wire->u.event.state;
1068dd3e0eeSmrg	mevent->dx = wire->u.event.dx;
1078dd3e0eeSmrg	mevent->dy = wire->u.event.dy;
1088dd3e0eeSmrg	return True;
1098dd3e0eeSmrg  case ButtonPress:
1108dd3e0eeSmrg  case ButtonRelease:
1118dd3e0eeSmrg	bevent = (XDGAButtonEvent*)event;
1128dd3e0eeSmrg	bevent->type = wire->u.u.type & 0x7F;
1138dd3e0eeSmrg	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1148dd3e0eeSmrg	bevent->display = dpy;
1158dd3e0eeSmrg	bevent->screen = wire->u.event.screen;
1168dd3e0eeSmrg	bevent->time = wire->u.event.time;
1178dd3e0eeSmrg	bevent->state = wire->u.event.state;
1188dd3e0eeSmrg	bevent->button = wire->u.u.detail;
1198dd3e0eeSmrg	return True;
1208dd3e0eeSmrg  case KeyPress:
1218dd3e0eeSmrg  case KeyRelease:
1228dd3e0eeSmrg	kevent = (XDGAKeyEvent*)event;
1238dd3e0eeSmrg	kevent->type = wire->u.u.type & 0x7F;
1248dd3e0eeSmrg	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1258dd3e0eeSmrg	kevent->display = dpy;
1268dd3e0eeSmrg	kevent->screen = wire->u.event.screen;
1278dd3e0eeSmrg	kevent->time = wire->u.event.time;
1288dd3e0eeSmrg	kevent->state = wire->u.event.state;
1298dd3e0eeSmrg	kevent->keycode = wire->u.u.detail;
1308dd3e0eeSmrg	return True;
1318dd3e0eeSmrg  }
1328dd3e0eeSmrg
1338dd3e0eeSmrg  return False;
1348dd3e0eeSmrg}
1358dd3e0eeSmrg
1368dd3e0eeSmrg
1378dd3e0eeSmrgBool XDGAQueryExtension (
1388dd3e0eeSmrg    Display *dpy,
1398dd3e0eeSmrg    int *event_basep,
1408dd3e0eeSmrg    int *error_basep
1418dd3e0eeSmrg){
1428dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1438dd3e0eeSmrg
1448dd3e0eeSmrg    if (XextHasExtension(info)) {
1458dd3e0eeSmrg	*event_basep = info->codes->first_event;
1468dd3e0eeSmrg	*error_basep = info->codes->first_error;
1478dd3e0eeSmrg	return True;
1488dd3e0eeSmrg    } else {
1498dd3e0eeSmrg	return False;
1508dd3e0eeSmrg    }
1518dd3e0eeSmrg}
1528dd3e0eeSmrg
1538dd3e0eeSmrg
1548dd3e0eeSmrgBool XDGAQueryVersion(
1558dd3e0eeSmrg    Display *dpy,
156d5a688bcSmrg    int *majorVersion,
1578dd3e0eeSmrg    int *minorVersion
1588dd3e0eeSmrg){
1598dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1608dd3e0eeSmrg    xXDGAQueryVersionReply rep;
1618dd3e0eeSmrg    xXDGAQueryVersionReq *req;
1628dd3e0eeSmrg
1638dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
1648dd3e0eeSmrg
1658dd3e0eeSmrg    LockDisplay(dpy);
1668dd3e0eeSmrg    GetReq(XDGAQueryVersion, req);
1678dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1688dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryVersion;
1698dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1708dd3e0eeSmrg	UnlockDisplay(dpy);
1718dd3e0eeSmrg	SyncHandle();
1728dd3e0eeSmrg	return False;
1738dd3e0eeSmrg    }
1748dd3e0eeSmrg    *majorVersion = rep.majorVersion;
1758dd3e0eeSmrg    *minorVersion = rep.minorVersion;
1768dd3e0eeSmrg    UnlockDisplay(dpy);
1778dd3e0eeSmrg    SyncHandle();
1788dd3e0eeSmrg    if (*majorVersion >= 2)
1798dd3e0eeSmrg    {
1808dd3e0eeSmrg	int i, j;
1818dd3e0eeSmrg
1828dd3e0eeSmrg	for (i = 0, j = info->codes->first_event;
1838dd3e0eeSmrg	     i < XF86DGANumberEvents;
184d5a688bcSmrg	     i++, j++)
1858dd3e0eeSmrg	{
1868dd3e0eeSmrg	    XESetWireToEvent (dpy, j, xdga_wire_to_event);
1878dd3e0eeSmrg	    XESetEventToWire (dpy, j, xdga_event_to_wire);
1888dd3e0eeSmrg	}
1898dd3e0eeSmrg	XDGASetClientVersion(dpy);
1908dd3e0eeSmrg    }
1918dd3e0eeSmrg    return True;
1928dd3e0eeSmrg}
1938dd3e0eeSmrg
1948dd3e0eeSmrgBool XDGASetClientVersion(
1958dd3e0eeSmrg    Display	*dpy
1968dd3e0eeSmrg){
1978dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1988dd3e0eeSmrg    xXDGASetClientVersionReq *req;
1998dd3e0eeSmrg
2008dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2018dd3e0eeSmrg
2028dd3e0eeSmrg    LockDisplay(dpy);
2038dd3e0eeSmrg    GetReq(XDGASetClientVersion, req);
2048dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2058dd3e0eeSmrg    req->dgaReqType = X_XDGASetClientVersion;
2068dd3e0eeSmrg    req->major = XDGA_MAJOR_VERSION;
2078dd3e0eeSmrg    req->minor = XDGA_MINOR_VERSION;
2088dd3e0eeSmrg    UnlockDisplay(dpy);
2098dd3e0eeSmrg    SyncHandle();
2108dd3e0eeSmrg    return True;
2118dd3e0eeSmrg}
2128dd3e0eeSmrg
2138dd3e0eeSmrgBool XDGAOpenFramebuffer(
2148dd3e0eeSmrg    Display	*dpy,
2158dd3e0eeSmrg    int 	screen
2168dd3e0eeSmrg){
2178dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2188dd3e0eeSmrg    xXDGAOpenFramebufferReply rep;
2198dd3e0eeSmrg    xXDGAOpenFramebufferReq *req;
2208dd3e0eeSmrg    char *deviceName = NULL;
2218dd3e0eeSmrg    Bool ret;
2228dd3e0eeSmrg
2238dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2248dd3e0eeSmrg
2258dd3e0eeSmrg    LockDisplay(dpy);
2268dd3e0eeSmrg    GetReq(XDGAOpenFramebuffer, req);
2278dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2288dd3e0eeSmrg    req->dgaReqType = X_XDGAOpenFramebuffer;
2298dd3e0eeSmrg    req->screen = screen;
2308dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2318dd3e0eeSmrg	UnlockDisplay(dpy);
2328dd3e0eeSmrg	SyncHandle();
2338dd3e0eeSmrg	return False;
2348dd3e0eeSmrg    }
2358dd3e0eeSmrg
236d5a688bcSmrg    if (rep.length) {
237d5a688bcSmrg	if (rep.length < (INT_MAX >> 2)) {
238d5a688bcSmrg	    unsigned long size = rep.length << 2;
239d5a688bcSmrg	    deviceName = Xmalloc(size);
240d5a688bcSmrg	    _XRead(dpy, deviceName, size);
241d5a688bcSmrg	    deviceName[size - 1] = '\0';
242d5a688bcSmrg	} else
243d5a688bcSmrg	    _XEatDataWords(dpy, rep.length);
2448dd3e0eeSmrg    }
2458dd3e0eeSmrg
2468dd3e0eeSmrg    ret = XDGAMapFramebuffer(screen, deviceName,
247d5a688bcSmrg				(unsigned char*)(long)rep.mem1,
2488dd3e0eeSmrg				rep.size, rep.offset, rep.extra);
2498dd3e0eeSmrg
2508dd3e0eeSmrg    if(deviceName)
251d5a688bcSmrg	Xfree(deviceName);
2528dd3e0eeSmrg
2538dd3e0eeSmrg    UnlockDisplay(dpy);
2548dd3e0eeSmrg    SyncHandle();
2558dd3e0eeSmrg    return ret;
2568dd3e0eeSmrg}
2578dd3e0eeSmrg
2588dd3e0eeSmrgvoid XDGACloseFramebuffer(
2598dd3e0eeSmrg    Display	*dpy,
2608dd3e0eeSmrg    int		screen
2618dd3e0eeSmrg){
2628dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2638dd3e0eeSmrg    xXDGACloseFramebufferReq *req;
2648dd3e0eeSmrg
2658dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
2668dd3e0eeSmrg
2678dd3e0eeSmrg    XDGAUnmapFramebuffer(screen);
2688dd3e0eeSmrg
2698dd3e0eeSmrg    LockDisplay(dpy);
2708dd3e0eeSmrg    GetReq(XDGACloseFramebuffer, req);
2718dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2728dd3e0eeSmrg    req->dgaReqType = X_XDGACloseFramebuffer;
2738dd3e0eeSmrg    req->screen = screen;
2748dd3e0eeSmrg    UnlockDisplay(dpy);
2758dd3e0eeSmrg    SyncHandle();
2768dd3e0eeSmrg}
2778dd3e0eeSmrg
2788dd3e0eeSmrg
2798dd3e0eeSmrg
2808dd3e0eeSmrgXDGAMode* XDGAQueryModes(
2818dd3e0eeSmrg    Display *dpy,
2828dd3e0eeSmrg    int screen,
2838dd3e0eeSmrg    int *num
2848dd3e0eeSmrg){
2858dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
2868dd3e0eeSmrg    xXDGAQueryModesReply rep;
2878dd3e0eeSmrg    xXDGAQueryModesReq *req;
2888dd3e0eeSmrg    XDGAMode *modes = NULL;
2898dd3e0eeSmrg
2908dd3e0eeSmrg    *num = 0;
2918dd3e0eeSmrg
2928dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
2938dd3e0eeSmrg
2948dd3e0eeSmrg    LockDisplay(dpy);
2958dd3e0eeSmrg    GetReq(XDGAQueryModes, req);
2968dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
2978dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryModes;
2988dd3e0eeSmrg    req->screen = screen;
2998dd3e0eeSmrg
3008dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3018dd3e0eeSmrg	if(rep.length) {
3028dd3e0eeSmrg	   xXDGAModeInfo info;
303d5a688bcSmrg	   unsigned long size = 0;
3048dd3e0eeSmrg	   char *offset;
3058dd3e0eeSmrg
306d5a688bcSmrg	   if ((rep.length < (INT_MAX >> 2)) &&
307d5a688bcSmrg	       (rep.number < (INT_MAX / sizeof(XDGAMode)))) {
308d5a688bcSmrg	       size = rep.length << 2;
309d5a688bcSmrg	       if (size > (rep.number * sz_xXDGAModeInfo)) {
310d5a688bcSmrg		   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
311d5a688bcSmrg		   modes = Xmalloc((rep.number * sizeof(XDGAMode)) + size);
312d5a688bcSmrg		   offset = (char*)(&modes[rep.number]);  /* start of text */
313d5a688bcSmrg	       }
314d5a688bcSmrg	   }
315d5a688bcSmrg
316d5a688bcSmrg	   if (modes != NULL) {
317d5a688bcSmrg	      unsigned int i;
3188dd3e0eeSmrg	      for(i = 0; i < rep.number; i++) {
3198dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
3208dd3e0eeSmrg
3218dd3e0eeSmrg		modes[i].num = info.num;
322d5a688bcSmrg		modes[i].verticalRefresh =
3238dd3e0eeSmrg			(float)info.vsync_num / (float)info.vsync_den;
3248dd3e0eeSmrg		modes[i].flags = info.flags;
3258dd3e0eeSmrg		modes[i].imageWidth = info.image_width;
3268dd3e0eeSmrg		modes[i].imageHeight = info.image_height;
3278dd3e0eeSmrg		modes[i].pixmapWidth = info.pixmap_width;
3288dd3e0eeSmrg		modes[i].pixmapHeight = info.pixmap_height;
3298dd3e0eeSmrg		modes[i].bytesPerScanline = info.bytes_per_scanline;
3308dd3e0eeSmrg		modes[i].byteOrder = info.byte_order;
3318dd3e0eeSmrg		modes[i].depth = info.depth;
3328dd3e0eeSmrg		modes[i].bitsPerPixel = info.bpp;
3338dd3e0eeSmrg		modes[i].redMask = info.red_mask;
3348dd3e0eeSmrg		modes[i].greenMask = info.green_mask;
3358dd3e0eeSmrg		modes[i].blueMask = info.blue_mask;
3368dd3e0eeSmrg		modes[i].visualClass = info.visual_class;
3378dd3e0eeSmrg		modes[i].viewportWidth = info.viewport_width;
3388dd3e0eeSmrg		modes[i].viewportHeight = info.viewport_height;
3398dd3e0eeSmrg		modes[i].xViewportStep = info.viewport_xstep;
3408dd3e0eeSmrg		modes[i].yViewportStep = info.viewport_ystep;
3418dd3e0eeSmrg		modes[i].maxViewportX = info.viewport_xmax;
3428dd3e0eeSmrg		modes[i].maxViewportY = info.viewport_ymax;
3438dd3e0eeSmrg		modes[i].viewportFlags = info.viewport_flags;
3448dd3e0eeSmrg		modes[i].reserved1 = info.reserved1;
345d5a688bcSmrg		modes[i].reserved2 = info.reserved2;
346d5a688bcSmrg
347d5a688bcSmrg		if (info.name_size > 0 && info.name_size <= size) {
348d5a688bcSmrg		    _XRead(dpy, offset, info.name_size);
349d5a688bcSmrg		    modes[i].name = offset;
350d5a688bcSmrg		    modes[i].name[info.name_size - 1] = '\0';
351d5a688bcSmrg		    offset += info.name_size;
352d5a688bcSmrg		    size -= info.name_size;
353d5a688bcSmrg		} else {
354d5a688bcSmrg		    _XEatData(dpy, info.name_size);
355d5a688bcSmrg		    modes[i].name = NULL;
356d5a688bcSmrg		}
3578dd3e0eeSmrg	      }
3588dd3e0eeSmrg	      *num = rep.number;
3598dd3e0eeSmrg	   } else
360d5a688bcSmrg		_XEatDataWords(dpy, rep.length);
3618dd3e0eeSmrg	}
3628dd3e0eeSmrg    }
3638dd3e0eeSmrg
3648dd3e0eeSmrg    UnlockDisplay(dpy);
3658dd3e0eeSmrg    SyncHandle();
3668dd3e0eeSmrg
3678dd3e0eeSmrg    return modes;
3688dd3e0eeSmrg}
3698dd3e0eeSmrg
3708dd3e0eeSmrg
371d5a688bcSmrgXDGADevice *
3728dd3e0eeSmrgXDGASetMode(
3738dd3e0eeSmrg    Display	*dpy,
3748dd3e0eeSmrg    int		screen,
3758dd3e0eeSmrg    int		mode
3768dd3e0eeSmrg){
3778dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
3788dd3e0eeSmrg    xXDGASetModeReply rep;
3798dd3e0eeSmrg    xXDGASetModeReq *req;
3808dd3e0eeSmrg    XDGADevice *dev = NULL;
3818dd3e0eeSmrg    Pixmap pid;
3828dd3e0eeSmrg
3838dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
3848dd3e0eeSmrg
3858dd3e0eeSmrg    LockDisplay(dpy);
3868dd3e0eeSmrg    GetReq(XDGASetMode, req);
3878dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
3888dd3e0eeSmrg    req->dgaReqType = X_XDGASetMode;
3898dd3e0eeSmrg    req->screen = screen;
3908dd3e0eeSmrg    req->mode = mode;
3918dd3e0eeSmrg    req->pid = pid = XAllocID(dpy);
392d5a688bcSmrg
3938dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3948dd3e0eeSmrg	if(rep.length) {
3958dd3e0eeSmrg	   xXDGAModeInfo info;
396d5a688bcSmrg	   unsigned long size;
397d5a688bcSmrg
398d5a688bcSmrg	   if ((rep.length < (INT_MAX >> 2)) &&
399d5a688bcSmrg	       (rep.length > (sz_xXDGAModeInfo >> 2))) {
400d5a688bcSmrg	       size = rep.length << 2;
401d5a688bcSmrg	       size -= sz_xXDGAModeInfo; /* get text size */
4028dd3e0eeSmrg
403d5a688bcSmrg	       dev = Xmalloc(sizeof(XDGADevice) + size);
404d5a688bcSmrg	   }
4058dd3e0eeSmrg
4068dd3e0eeSmrg	   if(dev) {
4078dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
4088dd3e0eeSmrg
4098dd3e0eeSmrg		dev->mode.num = info.num;
410d5a688bcSmrg		dev->mode.verticalRefresh =
4118dd3e0eeSmrg				(float)info.vsync_num / (float)info.vsync_den;
4128dd3e0eeSmrg		dev->mode.flags = info.flags;
4138dd3e0eeSmrg		dev->mode.imageWidth = info.image_width;
4148dd3e0eeSmrg		dev->mode.imageHeight = info.image_height;
4158dd3e0eeSmrg		dev->mode.pixmapWidth = info.pixmap_width;
4168dd3e0eeSmrg		dev->mode.pixmapHeight = info.pixmap_height;
4178dd3e0eeSmrg		dev->mode.bytesPerScanline = info.bytes_per_scanline;
4188dd3e0eeSmrg		dev->mode.byteOrder = info.byte_order;
4198dd3e0eeSmrg		dev->mode.depth = info.depth;
4208dd3e0eeSmrg		dev->mode.bitsPerPixel = info.bpp;
4218dd3e0eeSmrg		dev->mode.redMask = info.red_mask;
4228dd3e0eeSmrg		dev->mode.greenMask = info.green_mask;
4238dd3e0eeSmrg		dev->mode.blueMask = info.blue_mask;
4248dd3e0eeSmrg		dev->mode.visualClass = info.visual_class;
4258dd3e0eeSmrg		dev->mode.viewportWidth = info.viewport_width;
4268dd3e0eeSmrg		dev->mode.viewportHeight = info.viewport_height;
4278dd3e0eeSmrg		dev->mode.xViewportStep = info.viewport_xstep;
4288dd3e0eeSmrg		dev->mode.yViewportStep = info.viewport_ystep;
4298dd3e0eeSmrg		dev->mode.maxViewportX = info.viewport_xmax;
4308dd3e0eeSmrg		dev->mode.maxViewportY = info.viewport_ymax;
4318dd3e0eeSmrg		dev->mode.viewportFlags = info.viewport_flags;
4328dd3e0eeSmrg		dev->mode.reserved1 = info.reserved1;
4338dd3e0eeSmrg		dev->mode.reserved2 = info.reserved2;
4348dd3e0eeSmrg
435d5a688bcSmrg		if (info.name_size > 0 && info.name_size <= size) {
436d5a688bcSmrg		    dev->mode.name = (char*)(&dev[1]);
437d5a688bcSmrg		    _XRead(dpy, dev->mode.name, info.name_size);
438d5a688bcSmrg		    dev->mode.name[info.name_size - 1] = '\0';
439d5a688bcSmrg		} else {
440d5a688bcSmrg		    dev->mode.name = NULL;
441d5a688bcSmrg		    _XEatDataWords(dpy, rep.length);
442d5a688bcSmrg		}
4438dd3e0eeSmrg
4448dd3e0eeSmrg		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
4458dd3e0eeSmrg		dev->data = XDGAGetMappedMemory(screen);
4468dd3e0eeSmrg
4478dd3e0eeSmrg		if(dev->data)
4488dd3e0eeSmrg		    dev->data += rep.offset;
449d5a688bcSmrg	   }
4508dd3e0eeSmrg	   /* not sure what to do if the allocation fails */
451d5a688bcSmrg	   else
452d5a688bcSmrg	       _XEatDataWords(dpy, rep.length);
4538dd3e0eeSmrg	}
4548dd3e0eeSmrg    }
4558dd3e0eeSmrg
4568dd3e0eeSmrg    UnlockDisplay(dpy);
4578dd3e0eeSmrg    SyncHandle();
4588dd3e0eeSmrg
4598dd3e0eeSmrg    return dev;
4608dd3e0eeSmrg}
4618dd3e0eeSmrg
4628dd3e0eeSmrg
4638dd3e0eeSmrgvoid XDGASetViewport(
4648dd3e0eeSmrg    Display	*dpy,
4658dd3e0eeSmrg    int		screen,
4668dd3e0eeSmrg    int		x,
4678dd3e0eeSmrg    int		y,
4688dd3e0eeSmrg    int		flags
4698dd3e0eeSmrg){
4708dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4718dd3e0eeSmrg    xXDGASetViewportReq *req;
4728dd3e0eeSmrg
4738dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4748dd3e0eeSmrg
4758dd3e0eeSmrg    LockDisplay(dpy);
4768dd3e0eeSmrg    GetReq(XDGASetViewport, req);
4778dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
4788dd3e0eeSmrg    req->dgaReqType = X_XDGASetViewport;
4798dd3e0eeSmrg    req->screen = screen;
4808dd3e0eeSmrg    req->x = x;
4818dd3e0eeSmrg    req->y = y;
4828dd3e0eeSmrg    req->flags = flags;
4838dd3e0eeSmrg    UnlockDisplay(dpy);
4848dd3e0eeSmrg    SyncHandle();
4858dd3e0eeSmrg}
4868dd3e0eeSmrg
4878dd3e0eeSmrg
4888dd3e0eeSmrgvoid XDGAInstallColormap(
4898dd3e0eeSmrg    Display	*dpy,
4908dd3e0eeSmrg    int		screen,
4918dd3e0eeSmrg    Colormap	cmap
4928dd3e0eeSmrg){
4938dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4948dd3e0eeSmrg    xXDGAInstallColormapReq *req;
4958dd3e0eeSmrg
4968dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4978dd3e0eeSmrg
4988dd3e0eeSmrg    LockDisplay(dpy);
4998dd3e0eeSmrg    GetReq(XDGAInstallColormap, req);
5008dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5018dd3e0eeSmrg    req->dgaReqType = X_XDGAInstallColormap;
5028dd3e0eeSmrg    req->screen = screen;
5038dd3e0eeSmrg    req->cmap = cmap;
5048dd3e0eeSmrg    UnlockDisplay(dpy);
5058dd3e0eeSmrg    SyncHandle();
5068dd3e0eeSmrg}
5078dd3e0eeSmrg
5088dd3e0eeSmrgvoid XDGASelectInput(
5098dd3e0eeSmrg    Display	*dpy,
5108dd3e0eeSmrg    int		screen,
5118dd3e0eeSmrg    long	mask
5128dd3e0eeSmrg){
5138dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5148dd3e0eeSmrg    xXDGASelectInputReq *req;
5158dd3e0eeSmrg
5168dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5178dd3e0eeSmrg
5188dd3e0eeSmrg    LockDisplay(dpy);
5198dd3e0eeSmrg    GetReq(XDGASelectInput, req);
5208dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5218dd3e0eeSmrg    req->dgaReqType = X_XDGASelectInput;
5228dd3e0eeSmrg    req->screen = screen;
5238dd3e0eeSmrg    req->mask = mask;
5248dd3e0eeSmrg    UnlockDisplay(dpy);
5258dd3e0eeSmrg    SyncHandle();
5268dd3e0eeSmrg}
5278dd3e0eeSmrg
5288dd3e0eeSmrgvoid XDGAFillRectangle(
5298dd3e0eeSmrg    Display	*dpy,
5308dd3e0eeSmrg    int		screen,
5318dd3e0eeSmrg    int		x,
5328dd3e0eeSmrg    int		y,
5338dd3e0eeSmrg    unsigned int	width,
5348dd3e0eeSmrg    unsigned int	height,
5358dd3e0eeSmrg    unsigned long	color
5368dd3e0eeSmrg){
5378dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5388dd3e0eeSmrg    xXDGAFillRectangleReq *req;
5398dd3e0eeSmrg
5408dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5418dd3e0eeSmrg
5428dd3e0eeSmrg    LockDisplay(dpy);
5438dd3e0eeSmrg    GetReq(XDGAFillRectangle, req);
5448dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5458dd3e0eeSmrg    req->dgaReqType = X_XDGAFillRectangle;
5468dd3e0eeSmrg    req->screen = screen;
5478dd3e0eeSmrg    req->x = x;
5488dd3e0eeSmrg    req->y = y;
5498dd3e0eeSmrg    req->width = width;
5508dd3e0eeSmrg    req->height = height;
5518dd3e0eeSmrg    req->color = color;
5528dd3e0eeSmrg    UnlockDisplay(dpy);
5538dd3e0eeSmrg    SyncHandle();
5548dd3e0eeSmrg}
5558dd3e0eeSmrg
5568dd3e0eeSmrgvoid XDGACopyArea(
5578dd3e0eeSmrg    Display	*dpy,
5588dd3e0eeSmrg    int		screen,
5598dd3e0eeSmrg    int		srcx,
5608dd3e0eeSmrg    int		srcy,
5618dd3e0eeSmrg    unsigned int	width,
5628dd3e0eeSmrg    unsigned int	height,
5638dd3e0eeSmrg    int		dstx,
5648dd3e0eeSmrg    int		dsty
5658dd3e0eeSmrg){
5668dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5678dd3e0eeSmrg    xXDGACopyAreaReq *req;
5688dd3e0eeSmrg
5698dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5708dd3e0eeSmrg
5718dd3e0eeSmrg    LockDisplay(dpy);
5728dd3e0eeSmrg    GetReq(XDGACopyArea, req);
5738dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5748dd3e0eeSmrg    req->dgaReqType = X_XDGACopyArea;
5758dd3e0eeSmrg    req->screen = screen;
5768dd3e0eeSmrg    req->srcx = srcx;
5778dd3e0eeSmrg    req->srcy = srcy;
5788dd3e0eeSmrg    req->width = width;
5798dd3e0eeSmrg    req->height = height;
5808dd3e0eeSmrg    req->dstx = dstx;
5818dd3e0eeSmrg    req->dsty = dsty;
5828dd3e0eeSmrg    UnlockDisplay(dpy);
5838dd3e0eeSmrg    SyncHandle();
5848dd3e0eeSmrg}
5858dd3e0eeSmrg
5868dd3e0eeSmrgvoid XDGACopyTransparentArea(
5878dd3e0eeSmrg    Display	*dpy,
5888dd3e0eeSmrg    int		screen,
5898dd3e0eeSmrg    int		srcx,
5908dd3e0eeSmrg    int		srcy,
5918dd3e0eeSmrg    unsigned int	width,
5928dd3e0eeSmrg    unsigned int	height,
5938dd3e0eeSmrg    int		dstx,
5948dd3e0eeSmrg    int		dsty,
5958dd3e0eeSmrg    unsigned long key
5968dd3e0eeSmrg){
5978dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5988dd3e0eeSmrg    xXDGACopyTransparentAreaReq *req;
5998dd3e0eeSmrg
6008dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6018dd3e0eeSmrg
6028dd3e0eeSmrg    LockDisplay(dpy);
6038dd3e0eeSmrg    GetReq(XDGACopyTransparentArea, req);
6048dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6058dd3e0eeSmrg    req->dgaReqType = X_XDGACopyTransparentArea;
6068dd3e0eeSmrg    req->screen = screen;
6078dd3e0eeSmrg    req->srcx = srcx;
6088dd3e0eeSmrg    req->srcy = srcy;
6098dd3e0eeSmrg    req->width = width;
6108dd3e0eeSmrg    req->height = height;
6118dd3e0eeSmrg    req->dstx = dstx;
6128dd3e0eeSmrg    req->dsty = dsty;
6138dd3e0eeSmrg    req->key = key;
6148dd3e0eeSmrg    UnlockDisplay(dpy);
6158dd3e0eeSmrg    SyncHandle();
6168dd3e0eeSmrg}
6178dd3e0eeSmrg
6188dd3e0eeSmrg
6198dd3e0eeSmrgint XDGAGetViewportStatus(
6208dd3e0eeSmrg    Display *dpy,
621d5a688bcSmrg    int screen
6228dd3e0eeSmrg){
6238dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6248dd3e0eeSmrg    xXDGAGetViewportStatusReply rep;
6258dd3e0eeSmrg    xXDGAGetViewportStatusReq *req;
6268dd3e0eeSmrg    int status = 0;
6278dd3e0eeSmrg
6288dd3e0eeSmrg    XDGACheckExtension (dpy, info, 0);
6298dd3e0eeSmrg
6308dd3e0eeSmrg    LockDisplay(dpy);
6318dd3e0eeSmrg    GetReq(XDGAGetViewportStatus, req);
6328dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6338dd3e0eeSmrg    req->dgaReqType = X_XDGAGetViewportStatus;
6348dd3e0eeSmrg    req->screen = screen;
6358dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
6368dd3e0eeSmrg	status = rep.status;
6378dd3e0eeSmrg    UnlockDisplay(dpy);
6388dd3e0eeSmrg    SyncHandle();
6398dd3e0eeSmrg    return status;
6408dd3e0eeSmrg}
6418dd3e0eeSmrg
6428dd3e0eeSmrgvoid XDGASync(
6438dd3e0eeSmrg    Display *dpy,
644d5a688bcSmrg    int screen
6458dd3e0eeSmrg){
6468dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6478dd3e0eeSmrg    xXDGASyncReply rep;
6488dd3e0eeSmrg    xXDGASyncReq *req;
6498dd3e0eeSmrg
6508dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6518dd3e0eeSmrg
6528dd3e0eeSmrg    LockDisplay(dpy);
6538dd3e0eeSmrg    GetReq(XDGASync, req);
6548dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6558dd3e0eeSmrg    req->dgaReqType = X_XDGASync;
6568dd3e0eeSmrg    req->screen = screen;
6578dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
6588dd3e0eeSmrg    UnlockDisplay(dpy);
6598dd3e0eeSmrg    SyncHandle();
6608dd3e0eeSmrg}
6618dd3e0eeSmrg
6628dd3e0eeSmrg
6638dd3e0eeSmrgvoid XDGAChangePixmapMode(
6648dd3e0eeSmrg    Display *dpy,
6658dd3e0eeSmrg    int screen,
6668dd3e0eeSmrg    int *x,
6678dd3e0eeSmrg    int *y,
668d5a688bcSmrg    int mode
6698dd3e0eeSmrg){
6708dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6718dd3e0eeSmrg    xXDGAChangePixmapModeReq *req;
6728dd3e0eeSmrg    xXDGAChangePixmapModeReply rep;
6738dd3e0eeSmrg
6748dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6758dd3e0eeSmrg
6768dd3e0eeSmrg    LockDisplay(dpy);
6778dd3e0eeSmrg    GetReq(XDGAChangePixmapMode, req);
6788dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6798dd3e0eeSmrg    req->dgaReqType = X_XDGAChangePixmapMode;
6808dd3e0eeSmrg    req->screen = screen;
6818dd3e0eeSmrg    req->x = *x;
6828dd3e0eeSmrg    req->y = *y;
6838dd3e0eeSmrg    req->flags = mode;
6848dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
6858dd3e0eeSmrg    *x = rep.x;
6868dd3e0eeSmrg    *y = rep.y;
6878dd3e0eeSmrg    UnlockDisplay(dpy);
6888dd3e0eeSmrg    SyncHandle();
6898dd3e0eeSmrg}
6908dd3e0eeSmrg
6918dd3e0eeSmrgColormap XDGACreateColormap(
6928dd3e0eeSmrg    Display *dpy,
6938dd3e0eeSmrg    int screen,
6948dd3e0eeSmrg    XDGADevice *dev,
6958dd3e0eeSmrg    int	alloc
6968dd3e0eeSmrg){
6978dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6988dd3e0eeSmrg    xXDGACreateColormapReq *req;
6998dd3e0eeSmrg    Colormap cid;
7008dd3e0eeSmrg
7018dd3e0eeSmrg    XDGACheckExtension (dpy, info, -1);
7028dd3e0eeSmrg
7038dd3e0eeSmrg    LockDisplay(dpy);
7048dd3e0eeSmrg    GetReq(XDGACreateColormap, req);
7058dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
7068dd3e0eeSmrg    req->dgaReqType = X_XDGACreateColormap;
7078dd3e0eeSmrg    req->screen = screen;
7088dd3e0eeSmrg    req->mode = dev->mode.num;
7098dd3e0eeSmrg    req->alloc = alloc;
7108dd3e0eeSmrg    cid = req->id = XAllocID(dpy);
7118dd3e0eeSmrg    UnlockDisplay(dpy);
7128dd3e0eeSmrg    SyncHandle();
7138dd3e0eeSmrg
7148dd3e0eeSmrg    return cid;
7158dd3e0eeSmrg}
7168dd3e0eeSmrg
7178dd3e0eeSmrg
7188dd3e0eeSmrgvoid XDGAKeyEventToXKeyEvent(
719d5a688bcSmrg    XDGAKeyEvent* dk,
7208dd3e0eeSmrg    XKeyEvent* xk
7218dd3e0eeSmrg){
7228dd3e0eeSmrg    xk->type = dk->type;
7238dd3e0eeSmrg    xk->serial = dk->serial;
7248dd3e0eeSmrg    xk->send_event = False;
7258dd3e0eeSmrg    xk->display = dk->display;
7268dd3e0eeSmrg    xk->window = RootWindow(dk->display, dk->screen);
7278dd3e0eeSmrg    xk->root = xk->window;
7288dd3e0eeSmrg    xk->subwindow = None;
7298dd3e0eeSmrg    xk->time = dk->time;
7308dd3e0eeSmrg    xk->x = xk->y = xk->x_root = xk->y_root = 0;
7318dd3e0eeSmrg    xk->state = dk->state;
7328dd3e0eeSmrg    xk->keycode = dk->keycode;
7338dd3e0eeSmrg    xk->same_screen = True;
7348dd3e0eeSmrg}
7358dd3e0eeSmrg
7368dd3e0eeSmrg#include <X11/Xmd.h>
7378dd3e0eeSmrg#include <stdlib.h>
7388dd3e0eeSmrg#include <stdio.h>
7398dd3e0eeSmrg#include <fcntl.h>
74027485fbcSmrg#include <sys/mman.h>
7418dd3e0eeSmrg#include <sys/wait.h>
7428dd3e0eeSmrg#include <signal.h>
7438dd3e0eeSmrg#include <unistd.h>
7448dd3e0eeSmrg
7458dd3e0eeSmrg#if defined(SVR4) && !defined(sun)
7468dd3e0eeSmrg#define DEV_MEM "/dev/pmem"
7478dd3e0eeSmrg#elif defined(SVR4) && defined(sun)
7488dd3e0eeSmrg#define DEV_MEM "/dev/xsvc"
7498dd3e0eeSmrg#elif defined(HAS_APERTURE_DRV)
7508dd3e0eeSmrg#define DEV_MEM "/dev/xf86"
7518dd3e0eeSmrg#else
7528dd3e0eeSmrg#define DEV_MEM "/dev/mem"
7538dd3e0eeSmrg#endif
7548dd3e0eeSmrg
7558dd3e0eeSmrg
7568dd3e0eeSmrg
7578dd3e0eeSmrgtypedef struct _DGAMapRec{
7588dd3e0eeSmrg  unsigned char *physical;
7598dd3e0eeSmrg  unsigned char *virtual;
7608dd3e0eeSmrg  CARD32 size;
7618dd3e0eeSmrg  int fd;
7628dd3e0eeSmrg  int screen;
7638dd3e0eeSmrg  struct _DGAMapRec *next;
7648dd3e0eeSmrg} DGAMapRec, *DGAMapPtr;
7658dd3e0eeSmrg
7668dd3e0eeSmrgstatic Bool
767d5a688bcSmrgDGAMapPhysical(int, const char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
7688dd3e0eeSmrgstatic void DGAUnmapPhysical(DGAMapPtr);
7698dd3e0eeSmrg
7708dd3e0eeSmrgstatic DGAMapPtr _Maps = NULL;
7718dd3e0eeSmrg
7728dd3e0eeSmrg
7738dd3e0eeSmrgunsigned char*
7748dd3e0eeSmrgXDGAGetMappedMemory(int screen)
7758dd3e0eeSmrg{
7768dd3e0eeSmrg    DGAMapPtr pMap = _Maps;
7778dd3e0eeSmrg    unsigned char *pntr = NULL;
7788dd3e0eeSmrg
7798dd3e0eeSmrg    while(pMap != NULL) {
7808dd3e0eeSmrg	if(pMap->screen == screen) {
7818dd3e0eeSmrg	    pntr = pMap->virtual;
7828dd3e0eeSmrg	    break;
7838dd3e0eeSmrg	}
7848dd3e0eeSmrg	pMap = pMap->next;
7858dd3e0eeSmrg    }
7868dd3e0eeSmrg
7878dd3e0eeSmrg    return pntr;
7888dd3e0eeSmrg}
7898dd3e0eeSmrg
7908dd3e0eeSmrgBool
7918dd3e0eeSmrgXDGAMapFramebuffer(
7928dd3e0eeSmrg   int screen,
7938dd3e0eeSmrg   char *name,			/* optional device name */
7948dd3e0eeSmrg   unsigned char* base,		/* physical memory */
7958dd3e0eeSmrg   CARD32 size,			/* size */
7968dd3e0eeSmrg   CARD32 offset,		/* optional offset */
7978dd3e0eeSmrg   CARD32 extra			/* optional extra data */
7988dd3e0eeSmrg){
7998dd3e0eeSmrg   DGAMapPtr pMap = _Maps;
8008dd3e0eeSmrg   Bool result;
801d5a688bcSmrg
8028dd3e0eeSmrg   /* is it already mapped ? */
8038dd3e0eeSmrg   while(pMap != NULL) {
8048dd3e0eeSmrg     if(pMap->screen == screen)
8058dd3e0eeSmrg	return True;
8068dd3e0eeSmrg     pMap = pMap->next;
8078dd3e0eeSmrg   }
8088dd3e0eeSmrg
8098dd3e0eeSmrg   if(extra & XDGANeedRoot) {
8108dd3e0eeSmrg    /* we should probably check if we have root permissions and
8118dd3e0eeSmrg       return False here */
8128dd3e0eeSmrg
8138dd3e0eeSmrg   }
8148dd3e0eeSmrg
8158dd3e0eeSmrg   pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
8168dd3e0eeSmrg
8178dd3e0eeSmrg   result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
8188dd3e0eeSmrg
8198dd3e0eeSmrg   if(result) {
8208dd3e0eeSmrg      pMap->next = _Maps;
8218dd3e0eeSmrg      _Maps = pMap;
822d5a688bcSmrg   } else
8238dd3e0eeSmrg      Xfree(pMap);
824d5a688bcSmrg
8258dd3e0eeSmrg   return result;
8268dd3e0eeSmrg}
8278dd3e0eeSmrg
8288dd3e0eeSmrgvoid
8298dd3e0eeSmrgXDGAUnmapFramebuffer(int screen)
8308dd3e0eeSmrg{
8318dd3e0eeSmrg   DGAMapPtr pMap = _Maps;
8328dd3e0eeSmrg   DGAMapPtr pPrev = NULL;
8338dd3e0eeSmrg
8348dd3e0eeSmrg   /* is it already mapped */
8358dd3e0eeSmrg    while(pMap != NULL) {
8368dd3e0eeSmrg	if(pMap->screen == screen)
8378dd3e0eeSmrg	    break;
8388dd3e0eeSmrg	pPrev = pMap;
8398dd3e0eeSmrg	pMap = pMap->next;
8408dd3e0eeSmrg    }
8418dd3e0eeSmrg
8428dd3e0eeSmrg    if(!pMap)
8438dd3e0eeSmrg	return;
8448dd3e0eeSmrg
8458dd3e0eeSmrg    DGAUnmapPhysical(pMap);
8468dd3e0eeSmrg
8478dd3e0eeSmrg    if(!pPrev)
8488dd3e0eeSmrg	_Maps = pMap->next;
8498dd3e0eeSmrg    else
8508dd3e0eeSmrg	pPrev->next = pMap->next;
8518dd3e0eeSmrg
8528dd3e0eeSmrg    Xfree(pMap);
8538dd3e0eeSmrg}
8548dd3e0eeSmrg
8558dd3e0eeSmrg
8568dd3e0eeSmrgstatic Bool
8578dd3e0eeSmrgDGAMapPhysical(
8588dd3e0eeSmrg   int screen,
859d5a688bcSmrg   const char *name,		/* optional device name */
8608dd3e0eeSmrg   unsigned char* base,		/* physical memory */
8618dd3e0eeSmrg   CARD32 size,			/* size */
8628dd3e0eeSmrg   CARD32 offset,		/* optional offset */
8638dd3e0eeSmrg   CARD32 extra,		/* optional extra data */
8648dd3e0eeSmrg   DGAMapPtr pMap
8658dd3e0eeSmrg) {
866d5a688bcSmrg
8678dd3e0eeSmrg    base += offset;
8688dd3e0eeSmrg
8698dd3e0eeSmrg    pMap->screen = screen;
8708dd3e0eeSmrg    pMap->physical = base;
8718dd3e0eeSmrg    pMap->size = size;
8728dd3e0eeSmrg
8738dd3e0eeSmrg#ifndef MAP_FILE
8748dd3e0eeSmrg#define MAP_FILE 0
8758dd3e0eeSmrg#endif
8768dd3e0eeSmrg    if (!name)
8778dd3e0eeSmrg	    name = DEV_MEM;
8788dd3e0eeSmrg    if ((pMap->fd = open(name, O_RDWR)) < 0)
8798dd3e0eeSmrg	return False;
880d5a688bcSmrg    pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
881d5a688bcSmrg			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)(uintptr_t)base);
8828dd3e0eeSmrg    if (pMap->virtual == (void *)-1)
8838dd3e0eeSmrg	return False;
8848dd3e0eeSmrg    mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
8858dd3e0eeSmrg
8868dd3e0eeSmrg    return True;
8878dd3e0eeSmrg}
8888dd3e0eeSmrg
8898dd3e0eeSmrg
8908dd3e0eeSmrg
8918dd3e0eeSmrgstatic void
8928dd3e0eeSmrgDGAUnmapPhysical(DGAMapPtr pMap)
8938dd3e0eeSmrg{
8948dd3e0eeSmrg    if (pMap->virtual && pMap->virtual != (void *)-1) {
8958dd3e0eeSmrg	mprotect(pMap->virtual,pMap->size, PROT_READ);
8968dd3e0eeSmrg	munmap(pMap->virtual, pMap->size);
8978dd3e0eeSmrg	pMap->virtual = 0;
8988dd3e0eeSmrg    }
8998dd3e0eeSmrg    if (pMap->fd >= 0) {
9008dd3e0eeSmrg	close(pMap->fd);
9018dd3e0eeSmrg	pMap->fd = -1;
9028dd3e0eeSmrg    }
9038dd3e0eeSmrg}
904