XF86DGA2.c revision 8dd3e0ee
18dd3e0eeSmrg/* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.23 2003/05/05 20:42:30 tsi Exp $ */
28dd3e0eeSmrg/*
38dd3e0eeSmrg
48dd3e0eeSmrgCopyright (c) 1995  Jon Tombs
58dd3e0eeSmrgCopyright (c) 1995,1996  The XFree86 Project, Inc
68dd3e0eeSmrg
78dd3e0eeSmrg*/
88dd3e0eeSmrg
98dd3e0eeSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD */
108dd3e0eeSmrg
118dd3e0eeSmrg#ifdef __UNIXOS2__ /* needed here to override certain constants in X headers */
128dd3e0eeSmrg#define INCL_DOS
138dd3e0eeSmrg#define INCL_DOSIOCTL
148dd3e0eeSmrg#define I_NEED_OS2_H
158dd3e0eeSmrg#include <os2.h>
168dd3e0eeSmrg#endif
178dd3e0eeSmrg
188dd3e0eeSmrg#define NEED_EVENTS
198dd3e0eeSmrg#define NEED_REPLIES
208dd3e0eeSmrg#include <X11/Xlibint.h>
218dd3e0eeSmrg#include <X11/extensions/xf86dga.h>
228dd3e0eeSmrg#include <X11/extensions/xf86dgastr.h>
238dd3e0eeSmrg#include <X11/extensions/Xext.h>
248dd3e0eeSmrg#include <X11/extensions/extutil.h>
258dd3e0eeSmrg#include <stdio.h>
268dd3e0eeSmrg
278dd3e0eeSmrg
288dd3e0eeSmrg/* If you change this, change the Bases[] array below as well */
298dd3e0eeSmrg#define MAX_HEADS 16
308dd3e0eeSmrg
318dd3e0eeSmrgchar *xdga_extension_name = XF86DGANAME;
328dd3e0eeSmrg
338dd3e0eeSmrgstatic XExtensionInfo _xdga_info_data;
348dd3e0eeSmrgstatic XExtensionInfo *xdga_info = &_xdga_info_data;
358dd3e0eeSmrg
368dd3e0eeSmrg
378dd3e0eeSmrgBool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32);
388dd3e0eeSmrgvoid XDGAUnmapFramebuffer(int);
398dd3e0eeSmrgunsigned char* XDGAGetMappedMemory(int);
408dd3e0eeSmrg
418dd3e0eeSmrg#define XDGACheckExtension(dpy,i,val) \
428dd3e0eeSmrg  XextCheckExtension (dpy, i, xdga_extension_name, val)
438dd3e0eeSmrg
448dd3e0eeSmrg/*****************************************************************************
458dd3e0eeSmrg *                                                                           *
468dd3e0eeSmrg *			   private utility routines                          *
478dd3e0eeSmrg *                                                                           *
488dd3e0eeSmrg *****************************************************************************/
498dd3e0eeSmrg
508dd3e0eeSmrgstatic int xdga_close_display(Display *dpy, XExtCodes *codes);
518dd3e0eeSmrgstatic Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
528dd3e0eeSmrgstatic Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
538dd3e0eeSmrg
548dd3e0eeSmrgstatic XExtensionHooks xdga_extension_hooks = {
558dd3e0eeSmrg    NULL,				/* create_gc */
568dd3e0eeSmrg    NULL,				/* copy_gc */
578dd3e0eeSmrg    NULL,				/* flush_gc */
588dd3e0eeSmrg    NULL,				/* free_gc */
598dd3e0eeSmrg    NULL,				/* create_font */
608dd3e0eeSmrg    NULL,				/* free_font */
618dd3e0eeSmrg    xdga_close_display,			/* close_display */
628dd3e0eeSmrg    xdga_wire_to_event,			/* wire_to_event */
638dd3e0eeSmrg    xdga_event_to_wire,			/* event_to_wire */
648dd3e0eeSmrg    NULL,				/* error */
658dd3e0eeSmrg    NULL,				/* error_string */
668dd3e0eeSmrg};
678dd3e0eeSmrg
688dd3e0eeSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
698dd3e0eeSmrg
708dd3e0eeSmrg
718dd3e0eeSmrgXExtDisplayInfo* xdga_find_display(Display*);
728dd3e0eeSmrgXEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info,
738dd3e0eeSmrg				   "XFree86-DGA",
748dd3e0eeSmrg				   &xdga_extension_hooks,
758dd3e0eeSmrg				   0, NULL)
768dd3e0eeSmrg
778dd3e0eeSmrg
788dd3e0eeSmrgstatic Status
798dd3e0eeSmrgxdga_event_to_wire(
808dd3e0eeSmrg  Display *dpy,
818dd3e0eeSmrg  XEvent *event,
828dd3e0eeSmrg  xEvent *wire_ev
838dd3e0eeSmrg){
848dd3e0eeSmrg    return True;
858dd3e0eeSmrg}
868dd3e0eeSmrg
878dd3e0eeSmrgstatic Bool
888dd3e0eeSmrgxdga_wire_to_event(
898dd3e0eeSmrg  Display *dpy,
908dd3e0eeSmrg  XEvent *event,
918dd3e0eeSmrg  xEvent *wire_ev
928dd3e0eeSmrg){
938dd3e0eeSmrg  dgaEvent *wire = (dgaEvent *) wire_ev;
948dd3e0eeSmrg  XDGAButtonEvent *bevent;
958dd3e0eeSmrg  XDGAKeyEvent *kevent;
968dd3e0eeSmrg  XDGAMotionEvent *mevent;
978dd3e0eeSmrg  XExtDisplayInfo *info = xdga_find_display (dpy);
988dd3e0eeSmrg
998dd3e0eeSmrg  XDGACheckExtension (dpy, info, False);
1008dd3e0eeSmrg
1018dd3e0eeSmrg  switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
1028dd3e0eeSmrg  case MotionNotify:
1038dd3e0eeSmrg	mevent = (XDGAMotionEvent*)event;
1048dd3e0eeSmrg	mevent->type = wire->u.u.type & 0x7F;
1058dd3e0eeSmrg	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1068dd3e0eeSmrg	mevent->display = dpy;
1078dd3e0eeSmrg	mevent->screen = wire->u.event.screen;
1088dd3e0eeSmrg	mevent->time = wire->u.event.time;
1098dd3e0eeSmrg	mevent->state = wire->u.event.state;
1108dd3e0eeSmrg	mevent->dx = wire->u.event.dx;
1118dd3e0eeSmrg	mevent->dy = wire->u.event.dy;
1128dd3e0eeSmrg	return True;
1138dd3e0eeSmrg  case ButtonPress:
1148dd3e0eeSmrg  case ButtonRelease:
1158dd3e0eeSmrg	bevent = (XDGAButtonEvent*)event;
1168dd3e0eeSmrg	bevent->type = wire->u.u.type & 0x7F;
1178dd3e0eeSmrg	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1188dd3e0eeSmrg	bevent->display = dpy;
1198dd3e0eeSmrg	bevent->screen = wire->u.event.screen;
1208dd3e0eeSmrg	bevent->time = wire->u.event.time;
1218dd3e0eeSmrg	bevent->state = wire->u.event.state;
1228dd3e0eeSmrg	bevent->button = wire->u.u.detail;
1238dd3e0eeSmrg	return True;
1248dd3e0eeSmrg  case KeyPress:
1258dd3e0eeSmrg  case KeyRelease:
1268dd3e0eeSmrg	kevent = (XDGAKeyEvent*)event;
1278dd3e0eeSmrg	kevent->type = wire->u.u.type & 0x7F;
1288dd3e0eeSmrg	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1298dd3e0eeSmrg	kevent->display = dpy;
1308dd3e0eeSmrg	kevent->screen = wire->u.event.screen;
1318dd3e0eeSmrg	kevent->time = wire->u.event.time;
1328dd3e0eeSmrg	kevent->state = wire->u.event.state;
1338dd3e0eeSmrg	kevent->keycode = wire->u.u.detail;
1348dd3e0eeSmrg	return True;
1358dd3e0eeSmrg  }
1368dd3e0eeSmrg
1378dd3e0eeSmrg  return False;
1388dd3e0eeSmrg}
1398dd3e0eeSmrg
1408dd3e0eeSmrg
1418dd3e0eeSmrgBool XDGAQueryExtension (
1428dd3e0eeSmrg    Display *dpy,
1438dd3e0eeSmrg    int *event_basep,
1448dd3e0eeSmrg    int *error_basep
1458dd3e0eeSmrg){
1468dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1478dd3e0eeSmrg
1488dd3e0eeSmrg    if (XextHasExtension(info)) {
1498dd3e0eeSmrg	*event_basep = info->codes->first_event;
1508dd3e0eeSmrg	*error_basep = info->codes->first_error;
1518dd3e0eeSmrg	return True;
1528dd3e0eeSmrg    } else {
1538dd3e0eeSmrg	return False;
1548dd3e0eeSmrg    }
1558dd3e0eeSmrg}
1568dd3e0eeSmrg
1578dd3e0eeSmrg
1588dd3e0eeSmrgBool XDGAQueryVersion(
1598dd3e0eeSmrg    Display *dpy,
1608dd3e0eeSmrg    int *majorVersion,
1618dd3e0eeSmrg    int *minorVersion
1628dd3e0eeSmrg){
1638dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1648dd3e0eeSmrg    xXDGAQueryVersionReply rep;
1658dd3e0eeSmrg    xXDGAQueryVersionReq *req;
1668dd3e0eeSmrg
1678dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
1688dd3e0eeSmrg
1698dd3e0eeSmrg    LockDisplay(dpy);
1708dd3e0eeSmrg    GetReq(XDGAQueryVersion, req);
1718dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1728dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryVersion;
1738dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1748dd3e0eeSmrg	UnlockDisplay(dpy);
1758dd3e0eeSmrg	SyncHandle();
1768dd3e0eeSmrg	return False;
1778dd3e0eeSmrg    }
1788dd3e0eeSmrg    *majorVersion = rep.majorVersion;
1798dd3e0eeSmrg    *minorVersion = rep.minorVersion;
1808dd3e0eeSmrg    UnlockDisplay(dpy);
1818dd3e0eeSmrg    SyncHandle();
1828dd3e0eeSmrg    if (*majorVersion >= 2)
1838dd3e0eeSmrg    {
1848dd3e0eeSmrg	int i, j;
1858dd3e0eeSmrg
1868dd3e0eeSmrg	for (i = 0, j = info->codes->first_event;
1878dd3e0eeSmrg	     i < XF86DGANumberEvents;
1888dd3e0eeSmrg	     i++, j++)
1898dd3e0eeSmrg	{
1908dd3e0eeSmrg	    XESetWireToEvent (dpy, j, xdga_wire_to_event);
1918dd3e0eeSmrg	    XESetEventToWire (dpy, j, xdga_event_to_wire);
1928dd3e0eeSmrg	}
1938dd3e0eeSmrg	XDGASetClientVersion(dpy);
1948dd3e0eeSmrg    }
1958dd3e0eeSmrg    return True;
1968dd3e0eeSmrg}
1978dd3e0eeSmrg
1988dd3e0eeSmrgBool XDGASetClientVersion(
1998dd3e0eeSmrg    Display	*dpy
2008dd3e0eeSmrg){
2018dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2028dd3e0eeSmrg    xXDGASetClientVersionReq *req;
2038dd3e0eeSmrg
2048dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2058dd3e0eeSmrg
2068dd3e0eeSmrg    LockDisplay(dpy);
2078dd3e0eeSmrg    GetReq(XDGASetClientVersion, req);
2088dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2098dd3e0eeSmrg    req->dgaReqType = X_XDGASetClientVersion;
2108dd3e0eeSmrg    req->major = XDGA_MAJOR_VERSION;
2118dd3e0eeSmrg    req->minor = XDGA_MINOR_VERSION;
2128dd3e0eeSmrg    UnlockDisplay(dpy);
2138dd3e0eeSmrg    SyncHandle();
2148dd3e0eeSmrg    return True;
2158dd3e0eeSmrg}
2168dd3e0eeSmrg
2178dd3e0eeSmrgBool XDGAOpenFramebuffer(
2188dd3e0eeSmrg    Display	*dpy,
2198dd3e0eeSmrg    int 	screen
2208dd3e0eeSmrg){
2218dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2228dd3e0eeSmrg    xXDGAOpenFramebufferReply rep;
2238dd3e0eeSmrg    xXDGAOpenFramebufferReq *req;
2248dd3e0eeSmrg    char *deviceName = NULL;
2258dd3e0eeSmrg    Bool ret;
2268dd3e0eeSmrg
2278dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2288dd3e0eeSmrg
2298dd3e0eeSmrg    LockDisplay(dpy);
2308dd3e0eeSmrg    GetReq(XDGAOpenFramebuffer, req);
2318dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2328dd3e0eeSmrg    req->dgaReqType = X_XDGAOpenFramebuffer;
2338dd3e0eeSmrg    req->screen = screen;
2348dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2358dd3e0eeSmrg	UnlockDisplay(dpy);
2368dd3e0eeSmrg	SyncHandle();
2378dd3e0eeSmrg	return False;
2388dd3e0eeSmrg    }
2398dd3e0eeSmrg
2408dd3e0eeSmrg    if(rep.length) {
2418dd3e0eeSmrg	deviceName = Xmalloc(rep.length << 2);
2428dd3e0eeSmrg	_XRead(dpy, deviceName, rep.length << 2);
2438dd3e0eeSmrg    }
2448dd3e0eeSmrg
2458dd3e0eeSmrg    ret = XDGAMapFramebuffer(screen, deviceName,
2468dd3e0eeSmrg				(unsigned char*)(long)rep.mem1,
2478dd3e0eeSmrg				rep.size, rep.offset, rep.extra);
2488dd3e0eeSmrg
2498dd3e0eeSmrg    if(deviceName)
2508dd3e0eeSmrg	Xfree(deviceName);
2518dd3e0eeSmrg
2528dd3e0eeSmrg    UnlockDisplay(dpy);
2538dd3e0eeSmrg    SyncHandle();
2548dd3e0eeSmrg    return ret;
2558dd3e0eeSmrg}
2568dd3e0eeSmrg
2578dd3e0eeSmrgvoid XDGACloseFramebuffer(
2588dd3e0eeSmrg    Display	*dpy,
2598dd3e0eeSmrg    int		screen
2608dd3e0eeSmrg){
2618dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2628dd3e0eeSmrg    xXDGACloseFramebufferReq *req;
2638dd3e0eeSmrg
2648dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
2658dd3e0eeSmrg
2668dd3e0eeSmrg    XDGAUnmapFramebuffer(screen);
2678dd3e0eeSmrg
2688dd3e0eeSmrg    LockDisplay(dpy);
2698dd3e0eeSmrg    GetReq(XDGACloseFramebuffer, req);
2708dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2718dd3e0eeSmrg    req->dgaReqType = X_XDGACloseFramebuffer;
2728dd3e0eeSmrg    req->screen = screen;
2738dd3e0eeSmrg    UnlockDisplay(dpy);
2748dd3e0eeSmrg    SyncHandle();
2758dd3e0eeSmrg}
2768dd3e0eeSmrg
2778dd3e0eeSmrg
2788dd3e0eeSmrg
2798dd3e0eeSmrgXDGAMode* XDGAQueryModes(
2808dd3e0eeSmrg    Display *dpy,
2818dd3e0eeSmrg    int screen,
2828dd3e0eeSmrg    int *num
2838dd3e0eeSmrg){
2848dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
2858dd3e0eeSmrg    xXDGAQueryModesReply rep;
2868dd3e0eeSmrg    xXDGAQueryModesReq *req;
2878dd3e0eeSmrg    XDGAMode *modes = NULL;
2888dd3e0eeSmrg
2898dd3e0eeSmrg    *num = 0;
2908dd3e0eeSmrg
2918dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
2928dd3e0eeSmrg
2938dd3e0eeSmrg    LockDisplay(dpy);
2948dd3e0eeSmrg    GetReq(XDGAQueryModes, req);
2958dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
2968dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryModes;
2978dd3e0eeSmrg    req->screen = screen;
2988dd3e0eeSmrg
2998dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3008dd3e0eeSmrg	if(rep.length) {
3018dd3e0eeSmrg	   xXDGAModeInfo info;
3028dd3e0eeSmrg	   int i, size;
3038dd3e0eeSmrg	   char *offset;
3048dd3e0eeSmrg
3058dd3e0eeSmrg	   size = rep.length << 2;
3068dd3e0eeSmrg	   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
3078dd3e0eeSmrg	   modes = (XDGAMode*)Xmalloc((rep.number * sizeof(XDGAMode)) + size);
3088dd3e0eeSmrg	   offset = (char*)(&modes[rep.number]); /* start of text */
3098dd3e0eeSmrg
3108dd3e0eeSmrg
3118dd3e0eeSmrg	   if(modes) {
3128dd3e0eeSmrg	      for(i = 0; i < rep.number; i++) {
3138dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
3148dd3e0eeSmrg
3158dd3e0eeSmrg		modes[i].num = info.num;
3168dd3e0eeSmrg		modes[i].verticalRefresh =
3178dd3e0eeSmrg			(float)info.vsync_num / (float)info.vsync_den;
3188dd3e0eeSmrg		modes[i].flags = info.flags;
3198dd3e0eeSmrg		modes[i].imageWidth = info.image_width;
3208dd3e0eeSmrg		modes[i].imageHeight = info.image_height;
3218dd3e0eeSmrg		modes[i].pixmapWidth = info.pixmap_width;
3228dd3e0eeSmrg		modes[i].pixmapHeight = info.pixmap_height;
3238dd3e0eeSmrg		modes[i].bytesPerScanline = info.bytes_per_scanline;
3248dd3e0eeSmrg		modes[i].byteOrder = info.byte_order;
3258dd3e0eeSmrg		modes[i].depth = info.depth;
3268dd3e0eeSmrg		modes[i].bitsPerPixel = info.bpp;
3278dd3e0eeSmrg		modes[i].redMask = info.red_mask;
3288dd3e0eeSmrg		modes[i].greenMask = info.green_mask;
3298dd3e0eeSmrg		modes[i].blueMask = info.blue_mask;
3308dd3e0eeSmrg		modes[i].visualClass = info.visual_class;
3318dd3e0eeSmrg		modes[i].viewportWidth = info.viewport_width;
3328dd3e0eeSmrg		modes[i].viewportHeight = info.viewport_height;
3338dd3e0eeSmrg		modes[i].xViewportStep = info.viewport_xstep;
3348dd3e0eeSmrg		modes[i].yViewportStep = info.viewport_ystep;
3358dd3e0eeSmrg		modes[i].maxViewportX = info.viewport_xmax;
3368dd3e0eeSmrg		modes[i].maxViewportY = info.viewport_ymax;
3378dd3e0eeSmrg		modes[i].viewportFlags = info.viewport_flags;
3388dd3e0eeSmrg		modes[i].reserved1 = info.reserved1;
3398dd3e0eeSmrg		modes[i].reserved2 = info.reserved2;
3408dd3e0eeSmrg
3418dd3e0eeSmrg		_XRead(dpy, offset, info.name_size);
3428dd3e0eeSmrg		modes[i].name = offset;
3438dd3e0eeSmrg		offset += info.name_size;
3448dd3e0eeSmrg	      }
3458dd3e0eeSmrg	      *num = rep.number;
3468dd3e0eeSmrg	   } else
3478dd3e0eeSmrg		_XEatData(dpy, rep.length << 2);
3488dd3e0eeSmrg	}
3498dd3e0eeSmrg    }
3508dd3e0eeSmrg
3518dd3e0eeSmrg    UnlockDisplay(dpy);
3528dd3e0eeSmrg    SyncHandle();
3538dd3e0eeSmrg
3548dd3e0eeSmrg    return modes;
3558dd3e0eeSmrg}
3568dd3e0eeSmrg
3578dd3e0eeSmrg
3588dd3e0eeSmrgXDGADevice *
3598dd3e0eeSmrgXDGASetMode(
3608dd3e0eeSmrg    Display	*dpy,
3618dd3e0eeSmrg    int		screen,
3628dd3e0eeSmrg    int		mode
3638dd3e0eeSmrg){
3648dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
3658dd3e0eeSmrg    xXDGASetModeReply rep;
3668dd3e0eeSmrg    xXDGASetModeReq *req;
3678dd3e0eeSmrg    XDGADevice *dev = NULL;
3688dd3e0eeSmrg    Pixmap pid;
3698dd3e0eeSmrg
3708dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
3718dd3e0eeSmrg
3728dd3e0eeSmrg    LockDisplay(dpy);
3738dd3e0eeSmrg    GetReq(XDGASetMode, req);
3748dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
3758dd3e0eeSmrg    req->dgaReqType = X_XDGASetMode;
3768dd3e0eeSmrg    req->screen = screen;
3778dd3e0eeSmrg    req->mode = mode;
3788dd3e0eeSmrg    req->pid = pid = XAllocID(dpy);
3798dd3e0eeSmrg
3808dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3818dd3e0eeSmrg	if(rep.length) {
3828dd3e0eeSmrg	   xXDGAModeInfo info;
3838dd3e0eeSmrg	   int size;
3848dd3e0eeSmrg
3858dd3e0eeSmrg	   size = rep.length << 2;
3868dd3e0eeSmrg	   size -= sz_xXDGAModeInfo; /* get text size */
3878dd3e0eeSmrg
3888dd3e0eeSmrg	   dev = (XDGADevice*)Xmalloc(sizeof(XDGADevice) + size);
3898dd3e0eeSmrg
3908dd3e0eeSmrg	   if(dev) {
3918dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
3928dd3e0eeSmrg
3938dd3e0eeSmrg		dev->mode.num = info.num;
3948dd3e0eeSmrg		dev->mode.verticalRefresh =
3958dd3e0eeSmrg				(float)info.vsync_num / (float)info.vsync_den;
3968dd3e0eeSmrg		dev->mode.flags = info.flags;
3978dd3e0eeSmrg		dev->mode.imageWidth = info.image_width;
3988dd3e0eeSmrg		dev->mode.imageHeight = info.image_height;
3998dd3e0eeSmrg		dev->mode.pixmapWidth = info.pixmap_width;
4008dd3e0eeSmrg		dev->mode.pixmapHeight = info.pixmap_height;
4018dd3e0eeSmrg		dev->mode.bytesPerScanline = info.bytes_per_scanline;
4028dd3e0eeSmrg		dev->mode.byteOrder = info.byte_order;
4038dd3e0eeSmrg		dev->mode.depth = info.depth;
4048dd3e0eeSmrg		dev->mode.bitsPerPixel = info.bpp;
4058dd3e0eeSmrg		dev->mode.redMask = info.red_mask;
4068dd3e0eeSmrg		dev->mode.greenMask = info.green_mask;
4078dd3e0eeSmrg		dev->mode.blueMask = info.blue_mask;
4088dd3e0eeSmrg		dev->mode.visualClass = info.visual_class;
4098dd3e0eeSmrg		dev->mode.viewportWidth = info.viewport_width;
4108dd3e0eeSmrg		dev->mode.viewportHeight = info.viewport_height;
4118dd3e0eeSmrg		dev->mode.xViewportStep = info.viewport_xstep;
4128dd3e0eeSmrg		dev->mode.yViewportStep = info.viewport_ystep;
4138dd3e0eeSmrg		dev->mode.maxViewportX = info.viewport_xmax;
4148dd3e0eeSmrg		dev->mode.maxViewportY = info.viewport_ymax;
4158dd3e0eeSmrg		dev->mode.viewportFlags = info.viewport_flags;
4168dd3e0eeSmrg		dev->mode.reserved1 = info.reserved1;
4178dd3e0eeSmrg		dev->mode.reserved2 = info.reserved2;
4188dd3e0eeSmrg
4198dd3e0eeSmrg		dev->mode.name = (char*)(&dev[1]);
4208dd3e0eeSmrg		_XRead(dpy, dev->mode.name, info.name_size);
4218dd3e0eeSmrg
4228dd3e0eeSmrg		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
4238dd3e0eeSmrg		dev->data = XDGAGetMappedMemory(screen);
4248dd3e0eeSmrg
4258dd3e0eeSmrg		if(dev->data)
4268dd3e0eeSmrg		    dev->data += rep.offset;
4278dd3e0eeSmrg	   }
4288dd3e0eeSmrg	   /* not sure what to do if the allocation fails */
4298dd3e0eeSmrg	}
4308dd3e0eeSmrg    }
4318dd3e0eeSmrg
4328dd3e0eeSmrg    UnlockDisplay(dpy);
4338dd3e0eeSmrg    SyncHandle();
4348dd3e0eeSmrg
4358dd3e0eeSmrg    return dev;
4368dd3e0eeSmrg}
4378dd3e0eeSmrg
4388dd3e0eeSmrg
4398dd3e0eeSmrgvoid XDGASetViewport(
4408dd3e0eeSmrg    Display	*dpy,
4418dd3e0eeSmrg    int		screen,
4428dd3e0eeSmrg    int		x,
4438dd3e0eeSmrg    int		y,
4448dd3e0eeSmrg    int		flags
4458dd3e0eeSmrg){
4468dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4478dd3e0eeSmrg    xXDGASetViewportReq *req;
4488dd3e0eeSmrg
4498dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4508dd3e0eeSmrg
4518dd3e0eeSmrg    LockDisplay(dpy);
4528dd3e0eeSmrg    GetReq(XDGASetViewport, req);
4538dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
4548dd3e0eeSmrg    req->dgaReqType = X_XDGASetViewport;
4558dd3e0eeSmrg    req->screen = screen;
4568dd3e0eeSmrg    req->x = x;
4578dd3e0eeSmrg    req->y = y;
4588dd3e0eeSmrg    req->flags = flags;
4598dd3e0eeSmrg    UnlockDisplay(dpy);
4608dd3e0eeSmrg    SyncHandle();
4618dd3e0eeSmrg}
4628dd3e0eeSmrg
4638dd3e0eeSmrg
4648dd3e0eeSmrgvoid XDGAInstallColormap(
4658dd3e0eeSmrg    Display	*dpy,
4668dd3e0eeSmrg    int		screen,
4678dd3e0eeSmrg    Colormap	cmap
4688dd3e0eeSmrg){
4698dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4708dd3e0eeSmrg    xXDGAInstallColormapReq *req;
4718dd3e0eeSmrg
4728dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4738dd3e0eeSmrg
4748dd3e0eeSmrg    LockDisplay(dpy);
4758dd3e0eeSmrg    GetReq(XDGAInstallColormap, req);
4768dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
4778dd3e0eeSmrg    req->dgaReqType = X_XDGAInstallColormap;
4788dd3e0eeSmrg    req->screen = screen;
4798dd3e0eeSmrg    req->cmap = cmap;
4808dd3e0eeSmrg    UnlockDisplay(dpy);
4818dd3e0eeSmrg    SyncHandle();
4828dd3e0eeSmrg}
4838dd3e0eeSmrg
4848dd3e0eeSmrgvoid XDGASelectInput(
4858dd3e0eeSmrg    Display	*dpy,
4868dd3e0eeSmrg    int		screen,
4878dd3e0eeSmrg    long	mask
4888dd3e0eeSmrg){
4898dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4908dd3e0eeSmrg    xXDGASelectInputReq *req;
4918dd3e0eeSmrg
4928dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4938dd3e0eeSmrg
4948dd3e0eeSmrg    LockDisplay(dpy);
4958dd3e0eeSmrg    GetReq(XDGASelectInput, req);
4968dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
4978dd3e0eeSmrg    req->dgaReqType = X_XDGASelectInput;
4988dd3e0eeSmrg    req->screen = screen;
4998dd3e0eeSmrg    req->mask = mask;
5008dd3e0eeSmrg    UnlockDisplay(dpy);
5018dd3e0eeSmrg    SyncHandle();
5028dd3e0eeSmrg}
5038dd3e0eeSmrg
5048dd3e0eeSmrgvoid XDGAFillRectangle(
5058dd3e0eeSmrg    Display	*dpy,
5068dd3e0eeSmrg    int		screen,
5078dd3e0eeSmrg    int		x,
5088dd3e0eeSmrg    int		y,
5098dd3e0eeSmrg    unsigned int	width,
5108dd3e0eeSmrg    unsigned int	height,
5118dd3e0eeSmrg    unsigned long	color
5128dd3e0eeSmrg){
5138dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5148dd3e0eeSmrg    xXDGAFillRectangleReq *req;
5158dd3e0eeSmrg
5168dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5178dd3e0eeSmrg
5188dd3e0eeSmrg    LockDisplay(dpy);
5198dd3e0eeSmrg    GetReq(XDGAFillRectangle, req);
5208dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5218dd3e0eeSmrg    req->dgaReqType = X_XDGAFillRectangle;
5228dd3e0eeSmrg    req->screen = screen;
5238dd3e0eeSmrg    req->x = x;
5248dd3e0eeSmrg    req->y = y;
5258dd3e0eeSmrg    req->width = width;
5268dd3e0eeSmrg    req->height = height;
5278dd3e0eeSmrg    req->color = color;
5288dd3e0eeSmrg    UnlockDisplay(dpy);
5298dd3e0eeSmrg    SyncHandle();
5308dd3e0eeSmrg}
5318dd3e0eeSmrg
5328dd3e0eeSmrgvoid XDGACopyArea(
5338dd3e0eeSmrg    Display	*dpy,
5348dd3e0eeSmrg    int		screen,
5358dd3e0eeSmrg    int		srcx,
5368dd3e0eeSmrg    int		srcy,
5378dd3e0eeSmrg    unsigned int	width,
5388dd3e0eeSmrg    unsigned int	height,
5398dd3e0eeSmrg    int		dstx,
5408dd3e0eeSmrg    int		dsty
5418dd3e0eeSmrg){
5428dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5438dd3e0eeSmrg    xXDGACopyAreaReq *req;
5448dd3e0eeSmrg
5458dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5468dd3e0eeSmrg
5478dd3e0eeSmrg    LockDisplay(dpy);
5488dd3e0eeSmrg    GetReq(XDGACopyArea, req);
5498dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5508dd3e0eeSmrg    req->dgaReqType = X_XDGACopyArea;
5518dd3e0eeSmrg    req->screen = screen;
5528dd3e0eeSmrg    req->srcx = srcx;
5538dd3e0eeSmrg    req->srcy = srcy;
5548dd3e0eeSmrg    req->width = width;
5558dd3e0eeSmrg    req->height = height;
5568dd3e0eeSmrg    req->dstx = dstx;
5578dd3e0eeSmrg    req->dsty = dsty;
5588dd3e0eeSmrg    UnlockDisplay(dpy);
5598dd3e0eeSmrg    SyncHandle();
5608dd3e0eeSmrg}
5618dd3e0eeSmrg
5628dd3e0eeSmrgvoid XDGACopyTransparentArea(
5638dd3e0eeSmrg    Display	*dpy,
5648dd3e0eeSmrg    int		screen,
5658dd3e0eeSmrg    int		srcx,
5668dd3e0eeSmrg    int		srcy,
5678dd3e0eeSmrg    unsigned int	width,
5688dd3e0eeSmrg    unsigned int	height,
5698dd3e0eeSmrg    int		dstx,
5708dd3e0eeSmrg    int		dsty,
5718dd3e0eeSmrg    unsigned long key
5728dd3e0eeSmrg){
5738dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5748dd3e0eeSmrg    xXDGACopyTransparentAreaReq *req;
5758dd3e0eeSmrg
5768dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5778dd3e0eeSmrg
5788dd3e0eeSmrg    LockDisplay(dpy);
5798dd3e0eeSmrg    GetReq(XDGACopyTransparentArea, req);
5808dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5818dd3e0eeSmrg    req->dgaReqType = X_XDGACopyTransparentArea;
5828dd3e0eeSmrg    req->screen = screen;
5838dd3e0eeSmrg    req->srcx = srcx;
5848dd3e0eeSmrg    req->srcy = srcy;
5858dd3e0eeSmrg    req->width = width;
5868dd3e0eeSmrg    req->height = height;
5878dd3e0eeSmrg    req->dstx = dstx;
5888dd3e0eeSmrg    req->dsty = dsty;
5898dd3e0eeSmrg    req->key = key;
5908dd3e0eeSmrg    UnlockDisplay(dpy);
5918dd3e0eeSmrg    SyncHandle();
5928dd3e0eeSmrg}
5938dd3e0eeSmrg
5948dd3e0eeSmrg
5958dd3e0eeSmrgint XDGAGetViewportStatus(
5968dd3e0eeSmrg    Display *dpy,
5978dd3e0eeSmrg    int screen
5988dd3e0eeSmrg){
5998dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6008dd3e0eeSmrg    xXDGAGetViewportStatusReply rep;
6018dd3e0eeSmrg    xXDGAGetViewportStatusReq *req;
6028dd3e0eeSmrg    int status = 0;
6038dd3e0eeSmrg
6048dd3e0eeSmrg    XDGACheckExtension (dpy, info, 0);
6058dd3e0eeSmrg
6068dd3e0eeSmrg    LockDisplay(dpy);
6078dd3e0eeSmrg    GetReq(XDGAGetViewportStatus, req);
6088dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6098dd3e0eeSmrg    req->dgaReqType = X_XDGAGetViewportStatus;
6108dd3e0eeSmrg    req->screen = screen;
6118dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
6128dd3e0eeSmrg	status = rep.status;
6138dd3e0eeSmrg    UnlockDisplay(dpy);
6148dd3e0eeSmrg    SyncHandle();
6158dd3e0eeSmrg    return status;
6168dd3e0eeSmrg}
6178dd3e0eeSmrg
6188dd3e0eeSmrgvoid XDGASync(
6198dd3e0eeSmrg    Display *dpy,
6208dd3e0eeSmrg    int screen
6218dd3e0eeSmrg){
6228dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6238dd3e0eeSmrg    xXDGASyncReply rep;
6248dd3e0eeSmrg    xXDGASyncReq *req;
6258dd3e0eeSmrg
6268dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6278dd3e0eeSmrg
6288dd3e0eeSmrg    LockDisplay(dpy);
6298dd3e0eeSmrg    GetReq(XDGASync, req);
6308dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6318dd3e0eeSmrg    req->dgaReqType = X_XDGASync;
6328dd3e0eeSmrg    req->screen = screen;
6338dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
6348dd3e0eeSmrg    UnlockDisplay(dpy);
6358dd3e0eeSmrg    SyncHandle();
6368dd3e0eeSmrg}
6378dd3e0eeSmrg
6388dd3e0eeSmrg
6398dd3e0eeSmrgvoid XDGAChangePixmapMode(
6408dd3e0eeSmrg    Display *dpy,
6418dd3e0eeSmrg    int screen,
6428dd3e0eeSmrg    int *x,
6438dd3e0eeSmrg    int *y,
6448dd3e0eeSmrg    int mode
6458dd3e0eeSmrg){
6468dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6478dd3e0eeSmrg    xXDGAChangePixmapModeReq *req;
6488dd3e0eeSmrg    xXDGAChangePixmapModeReply rep;
6498dd3e0eeSmrg
6508dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6518dd3e0eeSmrg
6528dd3e0eeSmrg    LockDisplay(dpy);
6538dd3e0eeSmrg    GetReq(XDGAChangePixmapMode, req);
6548dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6558dd3e0eeSmrg    req->dgaReqType = X_XDGAChangePixmapMode;
6568dd3e0eeSmrg    req->screen = screen;
6578dd3e0eeSmrg    req->x = *x;
6588dd3e0eeSmrg    req->y = *y;
6598dd3e0eeSmrg    req->flags = mode;
6608dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
6618dd3e0eeSmrg    *x = rep.x;
6628dd3e0eeSmrg    *y = rep.y;
6638dd3e0eeSmrg    UnlockDisplay(dpy);
6648dd3e0eeSmrg    SyncHandle();
6658dd3e0eeSmrg}
6668dd3e0eeSmrg
6678dd3e0eeSmrgColormap XDGACreateColormap(
6688dd3e0eeSmrg    Display *dpy,
6698dd3e0eeSmrg    int screen,
6708dd3e0eeSmrg    XDGADevice *dev,
6718dd3e0eeSmrg    int	alloc
6728dd3e0eeSmrg){
6738dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6748dd3e0eeSmrg    xXDGACreateColormapReq *req;
6758dd3e0eeSmrg    Colormap cid;
6768dd3e0eeSmrg
6778dd3e0eeSmrg    XDGACheckExtension (dpy, info, -1);
6788dd3e0eeSmrg
6798dd3e0eeSmrg    LockDisplay(dpy);
6808dd3e0eeSmrg    GetReq(XDGACreateColormap, req);
6818dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6828dd3e0eeSmrg    req->dgaReqType = X_XDGACreateColormap;
6838dd3e0eeSmrg    req->screen = screen;
6848dd3e0eeSmrg    req->mode = dev->mode.num;
6858dd3e0eeSmrg    req->alloc = alloc;
6868dd3e0eeSmrg    cid = req->id = XAllocID(dpy);
6878dd3e0eeSmrg    UnlockDisplay(dpy);
6888dd3e0eeSmrg    SyncHandle();
6898dd3e0eeSmrg
6908dd3e0eeSmrg    return cid;
6918dd3e0eeSmrg}
6928dd3e0eeSmrg
6938dd3e0eeSmrg
6948dd3e0eeSmrgvoid XDGAKeyEventToXKeyEvent(
6958dd3e0eeSmrg    XDGAKeyEvent* dk,
6968dd3e0eeSmrg    XKeyEvent* xk
6978dd3e0eeSmrg){
6988dd3e0eeSmrg    xk->type = dk->type;
6998dd3e0eeSmrg    xk->serial = dk->serial;
7008dd3e0eeSmrg    xk->send_event = False;
7018dd3e0eeSmrg    xk->display = dk->display;
7028dd3e0eeSmrg    xk->window = RootWindow(dk->display, dk->screen);
7038dd3e0eeSmrg    xk->root = xk->window;
7048dd3e0eeSmrg    xk->subwindow = None;
7058dd3e0eeSmrg    xk->time = dk->time;
7068dd3e0eeSmrg    xk->x = xk->y = xk->x_root = xk->y_root = 0;
7078dd3e0eeSmrg    xk->state = dk->state;
7088dd3e0eeSmrg    xk->keycode = dk->keycode;
7098dd3e0eeSmrg    xk->same_screen = True;
7108dd3e0eeSmrg}
7118dd3e0eeSmrg
7128dd3e0eeSmrg#include <X11/Xmd.h>
7138dd3e0eeSmrg#include <X11/extensions/xf86dga.h>
7148dd3e0eeSmrg#include <stdlib.h>
7158dd3e0eeSmrg#include <stdio.h>
7168dd3e0eeSmrg#include <fcntl.h>
7178dd3e0eeSmrg#if defined(ISC)
7188dd3e0eeSmrg# define HAS_SVR3_MMAP
7198dd3e0eeSmrg# include <sys/types.h>
7208dd3e0eeSmrg# include <errno.h>
7218dd3e0eeSmrg
7228dd3e0eeSmrg# include <sys/at_ansi.h>
7238dd3e0eeSmrg# include <sys/kd.h>
7248dd3e0eeSmrg
7258dd3e0eeSmrg# include <sys/sysmacros.h>
7268dd3e0eeSmrg# include <sys/immu.h>
7278dd3e0eeSmrg# include <sys/region.h>
7288dd3e0eeSmrg
7298dd3e0eeSmrg# include <sys/mmap.h>
7308dd3e0eeSmrg#else
7318dd3e0eeSmrg# if defined(Lynx) && defined(NO_MMAP)
7328dd3e0eeSmrg#  include <sys/types.h>
7338dd3e0eeSmrg#  include <errno.h>
7348dd3e0eeSmrg#  include <smem.h>
7358dd3e0eeSmrg# else
7368dd3e0eeSmrg#  if !defined(__UNIXOS2__)
7378dd3e0eeSmrg#   include <sys/mman.h>
7388dd3e0eeSmrg#  endif
7398dd3e0eeSmrg# endif
7408dd3e0eeSmrg#endif
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
7678dd3e0eeSmrgDGAMapPhysical(int, 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;
8018dd3e0eeSmrg
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;
8228dd3e0eeSmrg   } else
8238dd3e0eeSmrg      Xfree(pMap);
8248dd3e0eeSmrg
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,
8598dd3e0eeSmrg   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) {
8668dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
8678dd3e0eeSmrg    struct kd_memloc mloc;
8688dd3e0eeSmrg#elif defined(__UNIXOS2__)
8698dd3e0eeSmrg    APIRET rc;
8708dd3e0eeSmrg    ULONG action;
8718dd3e0eeSmrg    HFILE hfd;
8728dd3e0eeSmrg#endif
8738dd3e0eeSmrg
8748dd3e0eeSmrg    base += offset;
8758dd3e0eeSmrg
8768dd3e0eeSmrg    pMap->screen = screen;
8778dd3e0eeSmrg    pMap->physical = base;
8788dd3e0eeSmrg    pMap->size = size;
8798dd3e0eeSmrg
8808dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
8818dd3e0eeSmrg    if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
8828dd3e0eeSmrg	return False;
8838dd3e0eeSmrg    mloc.vaddr = (char *)0;
8848dd3e0eeSmrg    mloc.physaddr = (char *)base;
8858dd3e0eeSmrg    mloc.length = size;
8868dd3e0eeSmrg    mloc.ioflg=1;
8878dd3e0eeSmrg
8888dd3e0eeSmrg    if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
8898dd3e0eeSmrg	return False;
8908dd3e0eeSmrg#elif defined (__UNIXOS2__)
8918dd3e0eeSmrg    /*
8928dd3e0eeSmrg     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
8938dd3e0eeSmrg     * Consecutive calling of this routine will make PMAP$ driver run out
8948dd3e0eeSmrg     * of memory handles. Some umap/close mechanism should be provided
8958dd3e0eeSmrg     */
8968dd3e0eeSmrg
8978dd3e0eeSmrg    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
8988dd3e0eeSmrg		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
8998dd3e0eeSmrg    if (rc != 0)
9008dd3e0eeSmrg	return False;
9018dd3e0eeSmrg    {
9028dd3e0eeSmrg	struct map_ioctl {
9038dd3e0eeSmrg		union {
9048dd3e0eeSmrg			ULONG phys;
9058dd3e0eeSmrg			void* user;
9068dd3e0eeSmrg		} a;
9078dd3e0eeSmrg		ULONG size;
9088dd3e0eeSmrg	} pmap,dmap;
9098dd3e0eeSmrg	ULONG plen,dlen;
9108dd3e0eeSmrg#define XFREE86_PMAP	0x76
9118dd3e0eeSmrg#define PMAP_MAP	0x44
9128dd3e0eeSmrg
9138dd3e0eeSmrg	pmap.a.phys = base;
9148dd3e0eeSmrg	pmap.size = size;
9158dd3e0eeSmrg	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
9168dd3e0eeSmrg			 (PULONG)&pmap, sizeof(pmap), &plen,
9178dd3e0eeSmrg			 (PULONG)&dmap, sizeof(dmap), &dlen);
9188dd3e0eeSmrg	if (rc == 0) {
9198dd3e0eeSmrg		pMap->virtual = dmap.a.user;
9208dd3e0eeSmrg	}
9218dd3e0eeSmrg   }
9228dd3e0eeSmrg   if (rc != 0)
9238dd3e0eeSmrg	return False;
9248dd3e0eeSmrg#elif defined (Lynx) && defined(NO_MMAP)
9258dd3e0eeSmrg    pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
9268dd3e0eeSmrg#else
9278dd3e0eeSmrg#ifndef MAP_FILE
9288dd3e0eeSmrg#define MAP_FILE 0
9298dd3e0eeSmrg#endif
9308dd3e0eeSmrg    if (!name)
9318dd3e0eeSmrg	    name = DEV_MEM;
9328dd3e0eeSmrg    if ((pMap->fd = open(name, O_RDWR)) < 0)
9338dd3e0eeSmrg	return False;
9348dd3e0eeSmrg    pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
9358dd3e0eeSmrg			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)base);
9368dd3e0eeSmrg    if (pMap->virtual == (void *)-1)
9378dd3e0eeSmrg	return False;
9388dd3e0eeSmrg    mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
9398dd3e0eeSmrg#endif
9408dd3e0eeSmrg
9418dd3e0eeSmrg    return True;
9428dd3e0eeSmrg}
9438dd3e0eeSmrg
9448dd3e0eeSmrg
9458dd3e0eeSmrg
9468dd3e0eeSmrgstatic void
9478dd3e0eeSmrgDGAUnmapPhysical(DGAMapPtr pMap)
9488dd3e0eeSmrg{
9498dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
9508dd3e0eeSmrg    /* XXX Add unmapping code here. */
9518dd3e0eeSmrg#elif defined (__UNIXOS2__)
9528dd3e0eeSmrg    /* XXX Add unmapping code here. */
9538dd3e0eeSmrg#elif defined(Lynx) && defined(NO_MMAP)
9548dd3e0eeSmrg	/* XXX this doesn't allow enable after disable */
9558dd3e0eeSmrg    smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
9568dd3e0eeSmrg    smem_remove("XF86DGA");
9578dd3e0eeSmrg#else
9588dd3e0eeSmrg    if (pMap->virtual && pMap->virtual != (void *)-1) {
9598dd3e0eeSmrg	mprotect(pMap->virtual,pMap->size, PROT_READ);
9608dd3e0eeSmrg	munmap(pMap->virtual, pMap->size);
9618dd3e0eeSmrg	pMap->virtual = 0;
9628dd3e0eeSmrg    }
9638dd3e0eeSmrg    if (pMap->fd >= 0) {
9648dd3e0eeSmrg	close(pMap->fd);
9658dd3e0eeSmrg	pMap->fd = -1;
9668dd3e0eeSmrg    }
9678dd3e0eeSmrg#endif
9688dd3e0eeSmrg}
969