XF86DGA2.c revision d5a688bc
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#ifdef __UNIXOS2__ /* needed here to override certain constants in X headers */
148dd3e0eeSmrg#define INCL_DOS
158dd3e0eeSmrg#define INCL_DOSIOCTL
168dd3e0eeSmrg#define I_NEED_OS2_H
178dd3e0eeSmrg#include <os2.h>
188dd3e0eeSmrg#endif
198dd3e0eeSmrg
208dd3e0eeSmrg#include <X11/Xlibint.h>
21329fdfe9Smrg#include <X11/extensions/Xxf86dga.h>
22329fdfe9Smrg#include <X11/extensions/xf86dgaproto.h>
238dd3e0eeSmrg#include <X11/extensions/Xext.h>
248dd3e0eeSmrg#include <X11/extensions/extutil.h>
258dd3e0eeSmrg#include <stdio.h>
268dd3e0eeSmrg
27d5a688bcSmrg#include <stdint.h>
28d5a688bcSmrg#include <limits.h>
29d5a688bcSmrg
30d5a688bcSmrg#ifndef HAVE__XEATDATAWORDS
31d5a688bcSmrgstatic inline void _XEatDataWords(Display *dpy, unsigned long n)
32d5a688bcSmrg{
33d5a688bcSmrg# ifndef LONG64
34d5a688bcSmrg    if (n >= (ULONG_MAX >> 2))
35d5a688bcSmrg        _XIOError(dpy);
36d5a688bcSmrg# endif
37d5a688bcSmrg    _XEatData (dpy, n << 2);
38d5a688bcSmrg}
39d5a688bcSmrg#endif
408dd3e0eeSmrg
418dd3e0eeSmrg/* If you change this, change the Bases[] array below as well */
428dd3e0eeSmrg#define MAX_HEADS 16
438dd3e0eeSmrg
44d5a688bcSmrgconst char *xdga_extension_name = XF86DGANAME;
458dd3e0eeSmrg
468dd3e0eeSmrgstatic XExtensionInfo _xdga_info_data;
478dd3e0eeSmrgstatic XExtensionInfo *xdga_info = &_xdga_info_data;
488dd3e0eeSmrg
49d5a688bcSmrg
508dd3e0eeSmrgBool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32);
518dd3e0eeSmrgvoid XDGAUnmapFramebuffer(int);
528dd3e0eeSmrgunsigned char* XDGAGetMappedMemory(int);
538dd3e0eeSmrg
548dd3e0eeSmrg#define XDGACheckExtension(dpy,i,val) \
558dd3e0eeSmrg  XextCheckExtension (dpy, i, xdga_extension_name, val)
568dd3e0eeSmrg
578dd3e0eeSmrg/*****************************************************************************
588dd3e0eeSmrg *                                                                           *
598dd3e0eeSmrg *			   private utility routines                          *
608dd3e0eeSmrg *                                                                           *
618dd3e0eeSmrg *****************************************************************************/
628dd3e0eeSmrg
638dd3e0eeSmrgstatic int xdga_close_display(Display *dpy, XExtCodes *codes);
648dd3e0eeSmrgstatic Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
658dd3e0eeSmrgstatic Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
668dd3e0eeSmrg
678dd3e0eeSmrgstatic XExtensionHooks xdga_extension_hooks = {
688dd3e0eeSmrg    NULL,				/* create_gc */
698dd3e0eeSmrg    NULL,				/* copy_gc */
708dd3e0eeSmrg    NULL,				/* flush_gc */
718dd3e0eeSmrg    NULL,				/* free_gc */
728dd3e0eeSmrg    NULL,				/* create_font */
738dd3e0eeSmrg    NULL,				/* free_font */
748dd3e0eeSmrg    xdga_close_display,			/* close_display */
758dd3e0eeSmrg    xdga_wire_to_event,			/* wire_to_event */
768dd3e0eeSmrg    xdga_event_to_wire,			/* event_to_wire */
778dd3e0eeSmrg    NULL,				/* error */
788dd3e0eeSmrg    NULL,				/* error_string */
798dd3e0eeSmrg};
808dd3e0eeSmrg
818dd3e0eeSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
828dd3e0eeSmrg
838dd3e0eeSmrg
848dd3e0eeSmrgXExtDisplayInfo* xdga_find_display(Display*);
85d5a688bcSmrgXEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info,
86d5a688bcSmrg				   "XFree86-DGA",
87d5a688bcSmrg				   &xdga_extension_hooks,
888dd3e0eeSmrg				   0, NULL)
898dd3e0eeSmrg
908dd3e0eeSmrg
918dd3e0eeSmrgstatic Status
928dd3e0eeSmrgxdga_event_to_wire(
938dd3e0eeSmrg  Display *dpy,
948dd3e0eeSmrg  XEvent *event,
958dd3e0eeSmrg  xEvent *wire_ev
968dd3e0eeSmrg){
978dd3e0eeSmrg    return True;
988dd3e0eeSmrg}
998dd3e0eeSmrg
1008dd3e0eeSmrgstatic Bool
1018dd3e0eeSmrgxdga_wire_to_event(
1028dd3e0eeSmrg  Display *dpy,
1038dd3e0eeSmrg  XEvent *event,
1048dd3e0eeSmrg  xEvent *wire_ev
1058dd3e0eeSmrg){
1068dd3e0eeSmrg  dgaEvent *wire = (dgaEvent *) wire_ev;
1078dd3e0eeSmrg  XDGAButtonEvent *bevent;
1088dd3e0eeSmrg  XDGAKeyEvent *kevent;
1098dd3e0eeSmrg  XDGAMotionEvent *mevent;
1108dd3e0eeSmrg  XExtDisplayInfo *info = xdga_find_display (dpy);
1118dd3e0eeSmrg
1128dd3e0eeSmrg  XDGACheckExtension (dpy, info, False);
1138dd3e0eeSmrg
1148dd3e0eeSmrg  switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
1158dd3e0eeSmrg  case MotionNotify:
1168dd3e0eeSmrg	mevent = (XDGAMotionEvent*)event;
1178dd3e0eeSmrg	mevent->type = wire->u.u.type & 0x7F;
1188dd3e0eeSmrg	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1198dd3e0eeSmrg	mevent->display = dpy;
1208dd3e0eeSmrg	mevent->screen = wire->u.event.screen;
1218dd3e0eeSmrg	mevent->time = wire->u.event.time;
1228dd3e0eeSmrg	mevent->state = wire->u.event.state;
1238dd3e0eeSmrg	mevent->dx = wire->u.event.dx;
1248dd3e0eeSmrg	mevent->dy = wire->u.event.dy;
1258dd3e0eeSmrg	return True;
1268dd3e0eeSmrg  case ButtonPress:
1278dd3e0eeSmrg  case ButtonRelease:
1288dd3e0eeSmrg	bevent = (XDGAButtonEvent*)event;
1298dd3e0eeSmrg	bevent->type = wire->u.u.type & 0x7F;
1308dd3e0eeSmrg	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1318dd3e0eeSmrg	bevent->display = dpy;
1328dd3e0eeSmrg	bevent->screen = wire->u.event.screen;
1338dd3e0eeSmrg	bevent->time = wire->u.event.time;
1348dd3e0eeSmrg	bevent->state = wire->u.event.state;
1358dd3e0eeSmrg	bevent->button = wire->u.u.detail;
1368dd3e0eeSmrg	return True;
1378dd3e0eeSmrg  case KeyPress:
1388dd3e0eeSmrg  case KeyRelease:
1398dd3e0eeSmrg	kevent = (XDGAKeyEvent*)event;
1408dd3e0eeSmrg	kevent->type = wire->u.u.type & 0x7F;
1418dd3e0eeSmrg	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
1428dd3e0eeSmrg	kevent->display = dpy;
1438dd3e0eeSmrg	kevent->screen = wire->u.event.screen;
1448dd3e0eeSmrg	kevent->time = wire->u.event.time;
1458dd3e0eeSmrg	kevent->state = wire->u.event.state;
1468dd3e0eeSmrg	kevent->keycode = wire->u.u.detail;
1478dd3e0eeSmrg	return True;
1488dd3e0eeSmrg  }
1498dd3e0eeSmrg
1508dd3e0eeSmrg  return False;
1518dd3e0eeSmrg}
1528dd3e0eeSmrg
1538dd3e0eeSmrg
1548dd3e0eeSmrgBool XDGAQueryExtension (
1558dd3e0eeSmrg    Display *dpy,
1568dd3e0eeSmrg    int *event_basep,
1578dd3e0eeSmrg    int *error_basep
1588dd3e0eeSmrg){
1598dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1608dd3e0eeSmrg
1618dd3e0eeSmrg    if (XextHasExtension(info)) {
1628dd3e0eeSmrg	*event_basep = info->codes->first_event;
1638dd3e0eeSmrg	*error_basep = info->codes->first_error;
1648dd3e0eeSmrg	return True;
1658dd3e0eeSmrg    } else {
1668dd3e0eeSmrg	return False;
1678dd3e0eeSmrg    }
1688dd3e0eeSmrg}
1698dd3e0eeSmrg
1708dd3e0eeSmrg
1718dd3e0eeSmrgBool XDGAQueryVersion(
1728dd3e0eeSmrg    Display *dpy,
173d5a688bcSmrg    int *majorVersion,
1748dd3e0eeSmrg    int *minorVersion
1758dd3e0eeSmrg){
1768dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1778dd3e0eeSmrg    xXDGAQueryVersionReply rep;
1788dd3e0eeSmrg    xXDGAQueryVersionReq *req;
1798dd3e0eeSmrg
1808dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
1818dd3e0eeSmrg
1828dd3e0eeSmrg    LockDisplay(dpy);
1838dd3e0eeSmrg    GetReq(XDGAQueryVersion, req);
1848dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1858dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryVersion;
1868dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1878dd3e0eeSmrg	UnlockDisplay(dpy);
1888dd3e0eeSmrg	SyncHandle();
1898dd3e0eeSmrg	return False;
1908dd3e0eeSmrg    }
1918dd3e0eeSmrg    *majorVersion = rep.majorVersion;
1928dd3e0eeSmrg    *minorVersion = rep.minorVersion;
1938dd3e0eeSmrg    UnlockDisplay(dpy);
1948dd3e0eeSmrg    SyncHandle();
1958dd3e0eeSmrg    if (*majorVersion >= 2)
1968dd3e0eeSmrg    {
1978dd3e0eeSmrg	int i, j;
1988dd3e0eeSmrg
1998dd3e0eeSmrg	for (i = 0, j = info->codes->first_event;
2008dd3e0eeSmrg	     i < XF86DGANumberEvents;
201d5a688bcSmrg	     i++, j++)
2028dd3e0eeSmrg	{
2038dd3e0eeSmrg	    XESetWireToEvent (dpy, j, xdga_wire_to_event);
2048dd3e0eeSmrg	    XESetEventToWire (dpy, j, xdga_event_to_wire);
2058dd3e0eeSmrg	}
2068dd3e0eeSmrg	XDGASetClientVersion(dpy);
2078dd3e0eeSmrg    }
2088dd3e0eeSmrg    return True;
2098dd3e0eeSmrg}
2108dd3e0eeSmrg
2118dd3e0eeSmrgBool XDGASetClientVersion(
2128dd3e0eeSmrg    Display	*dpy
2138dd3e0eeSmrg){
2148dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2158dd3e0eeSmrg    xXDGASetClientVersionReq *req;
2168dd3e0eeSmrg
2178dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2188dd3e0eeSmrg
2198dd3e0eeSmrg    LockDisplay(dpy);
2208dd3e0eeSmrg    GetReq(XDGASetClientVersion, req);
2218dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2228dd3e0eeSmrg    req->dgaReqType = X_XDGASetClientVersion;
2238dd3e0eeSmrg    req->major = XDGA_MAJOR_VERSION;
2248dd3e0eeSmrg    req->minor = XDGA_MINOR_VERSION;
2258dd3e0eeSmrg    UnlockDisplay(dpy);
2268dd3e0eeSmrg    SyncHandle();
2278dd3e0eeSmrg    return True;
2288dd3e0eeSmrg}
2298dd3e0eeSmrg
2308dd3e0eeSmrgBool XDGAOpenFramebuffer(
2318dd3e0eeSmrg    Display	*dpy,
2328dd3e0eeSmrg    int 	screen
2338dd3e0eeSmrg){
2348dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2358dd3e0eeSmrg    xXDGAOpenFramebufferReply rep;
2368dd3e0eeSmrg    xXDGAOpenFramebufferReq *req;
2378dd3e0eeSmrg    char *deviceName = NULL;
2388dd3e0eeSmrg    Bool ret;
2398dd3e0eeSmrg
2408dd3e0eeSmrg    XDGACheckExtension (dpy, info, False);
2418dd3e0eeSmrg
2428dd3e0eeSmrg    LockDisplay(dpy);
2438dd3e0eeSmrg    GetReq(XDGAOpenFramebuffer, req);
2448dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2458dd3e0eeSmrg    req->dgaReqType = X_XDGAOpenFramebuffer;
2468dd3e0eeSmrg    req->screen = screen;
2478dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2488dd3e0eeSmrg	UnlockDisplay(dpy);
2498dd3e0eeSmrg	SyncHandle();
2508dd3e0eeSmrg	return False;
2518dd3e0eeSmrg    }
2528dd3e0eeSmrg
253d5a688bcSmrg    if (rep.length) {
254d5a688bcSmrg	if (rep.length < (INT_MAX >> 2)) {
255d5a688bcSmrg	    unsigned long size = rep.length << 2;
256d5a688bcSmrg	    deviceName = Xmalloc(size);
257d5a688bcSmrg	    _XRead(dpy, deviceName, size);
258d5a688bcSmrg	    deviceName[size - 1] = '\0';
259d5a688bcSmrg	} else
260d5a688bcSmrg	    _XEatDataWords(dpy, rep.length);
2618dd3e0eeSmrg    }
2628dd3e0eeSmrg
2638dd3e0eeSmrg    ret = XDGAMapFramebuffer(screen, deviceName,
264d5a688bcSmrg				(unsigned char*)(long)rep.mem1,
2658dd3e0eeSmrg				rep.size, rep.offset, rep.extra);
2668dd3e0eeSmrg
2678dd3e0eeSmrg    if(deviceName)
268d5a688bcSmrg	Xfree(deviceName);
2698dd3e0eeSmrg
2708dd3e0eeSmrg    UnlockDisplay(dpy);
2718dd3e0eeSmrg    SyncHandle();
2728dd3e0eeSmrg    return ret;
2738dd3e0eeSmrg}
2748dd3e0eeSmrg
2758dd3e0eeSmrgvoid XDGACloseFramebuffer(
2768dd3e0eeSmrg    Display	*dpy,
2778dd3e0eeSmrg    int		screen
2788dd3e0eeSmrg){
2798dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2808dd3e0eeSmrg    xXDGACloseFramebufferReq *req;
2818dd3e0eeSmrg
2828dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
2838dd3e0eeSmrg
2848dd3e0eeSmrg    XDGAUnmapFramebuffer(screen);
2858dd3e0eeSmrg
2868dd3e0eeSmrg    LockDisplay(dpy);
2878dd3e0eeSmrg    GetReq(XDGACloseFramebuffer, req);
2888dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2898dd3e0eeSmrg    req->dgaReqType = X_XDGACloseFramebuffer;
2908dd3e0eeSmrg    req->screen = screen;
2918dd3e0eeSmrg    UnlockDisplay(dpy);
2928dd3e0eeSmrg    SyncHandle();
2938dd3e0eeSmrg}
2948dd3e0eeSmrg
2958dd3e0eeSmrg
2968dd3e0eeSmrg
2978dd3e0eeSmrgXDGAMode* XDGAQueryModes(
2988dd3e0eeSmrg    Display *dpy,
2998dd3e0eeSmrg    int screen,
3008dd3e0eeSmrg    int *num
3018dd3e0eeSmrg){
3028dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
3038dd3e0eeSmrg    xXDGAQueryModesReply rep;
3048dd3e0eeSmrg    xXDGAQueryModesReq *req;
3058dd3e0eeSmrg    XDGAMode *modes = NULL;
3068dd3e0eeSmrg
3078dd3e0eeSmrg    *num = 0;
3088dd3e0eeSmrg
3098dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
3108dd3e0eeSmrg
3118dd3e0eeSmrg    LockDisplay(dpy);
3128dd3e0eeSmrg    GetReq(XDGAQueryModes, req);
3138dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
3148dd3e0eeSmrg    req->dgaReqType = X_XDGAQueryModes;
3158dd3e0eeSmrg    req->screen = screen;
3168dd3e0eeSmrg
3178dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3188dd3e0eeSmrg	if(rep.length) {
3198dd3e0eeSmrg	   xXDGAModeInfo info;
320d5a688bcSmrg	   unsigned long size = 0;
3218dd3e0eeSmrg	   char *offset;
3228dd3e0eeSmrg
323d5a688bcSmrg	   if ((rep.length < (INT_MAX >> 2)) &&
324d5a688bcSmrg	       (rep.number < (INT_MAX / sizeof(XDGAMode)))) {
325d5a688bcSmrg	       size = rep.length << 2;
326d5a688bcSmrg	       if (size > (rep.number * sz_xXDGAModeInfo)) {
327d5a688bcSmrg		   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
328d5a688bcSmrg		   modes = Xmalloc((rep.number * sizeof(XDGAMode)) + size);
329d5a688bcSmrg		   offset = (char*)(&modes[rep.number]);  /* start of text */
330d5a688bcSmrg	       }
331d5a688bcSmrg	   }
332d5a688bcSmrg
333d5a688bcSmrg	   if (modes != NULL) {
334d5a688bcSmrg	      unsigned int i;
3358dd3e0eeSmrg	      for(i = 0; i < rep.number; i++) {
3368dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
3378dd3e0eeSmrg
3388dd3e0eeSmrg		modes[i].num = info.num;
339d5a688bcSmrg		modes[i].verticalRefresh =
3408dd3e0eeSmrg			(float)info.vsync_num / (float)info.vsync_den;
3418dd3e0eeSmrg		modes[i].flags = info.flags;
3428dd3e0eeSmrg		modes[i].imageWidth = info.image_width;
3438dd3e0eeSmrg		modes[i].imageHeight = info.image_height;
3448dd3e0eeSmrg		modes[i].pixmapWidth = info.pixmap_width;
3458dd3e0eeSmrg		modes[i].pixmapHeight = info.pixmap_height;
3468dd3e0eeSmrg		modes[i].bytesPerScanline = info.bytes_per_scanline;
3478dd3e0eeSmrg		modes[i].byteOrder = info.byte_order;
3488dd3e0eeSmrg		modes[i].depth = info.depth;
3498dd3e0eeSmrg		modes[i].bitsPerPixel = info.bpp;
3508dd3e0eeSmrg		modes[i].redMask = info.red_mask;
3518dd3e0eeSmrg		modes[i].greenMask = info.green_mask;
3528dd3e0eeSmrg		modes[i].blueMask = info.blue_mask;
3538dd3e0eeSmrg		modes[i].visualClass = info.visual_class;
3548dd3e0eeSmrg		modes[i].viewportWidth = info.viewport_width;
3558dd3e0eeSmrg		modes[i].viewportHeight = info.viewport_height;
3568dd3e0eeSmrg		modes[i].xViewportStep = info.viewport_xstep;
3578dd3e0eeSmrg		modes[i].yViewportStep = info.viewport_ystep;
3588dd3e0eeSmrg		modes[i].maxViewportX = info.viewport_xmax;
3598dd3e0eeSmrg		modes[i].maxViewportY = info.viewport_ymax;
3608dd3e0eeSmrg		modes[i].viewportFlags = info.viewport_flags;
3618dd3e0eeSmrg		modes[i].reserved1 = info.reserved1;
362d5a688bcSmrg		modes[i].reserved2 = info.reserved2;
363d5a688bcSmrg
364d5a688bcSmrg		if (info.name_size > 0 && info.name_size <= size) {
365d5a688bcSmrg		    _XRead(dpy, offset, info.name_size);
366d5a688bcSmrg		    modes[i].name = offset;
367d5a688bcSmrg		    modes[i].name[info.name_size - 1] = '\0';
368d5a688bcSmrg		    offset += info.name_size;
369d5a688bcSmrg		    size -= info.name_size;
370d5a688bcSmrg		} else {
371d5a688bcSmrg		    _XEatData(dpy, info.name_size);
372d5a688bcSmrg		    modes[i].name = NULL;
373d5a688bcSmrg		}
3748dd3e0eeSmrg	      }
3758dd3e0eeSmrg	      *num = rep.number;
3768dd3e0eeSmrg	   } else
377d5a688bcSmrg		_XEatDataWords(dpy, rep.length);
3788dd3e0eeSmrg	}
3798dd3e0eeSmrg    }
3808dd3e0eeSmrg
3818dd3e0eeSmrg    UnlockDisplay(dpy);
3828dd3e0eeSmrg    SyncHandle();
3838dd3e0eeSmrg
3848dd3e0eeSmrg    return modes;
3858dd3e0eeSmrg}
3868dd3e0eeSmrg
3878dd3e0eeSmrg
388d5a688bcSmrgXDGADevice *
3898dd3e0eeSmrgXDGASetMode(
3908dd3e0eeSmrg    Display	*dpy,
3918dd3e0eeSmrg    int		screen,
3928dd3e0eeSmrg    int		mode
3938dd3e0eeSmrg){
3948dd3e0eeSmrg    XExtDisplayInfo *dinfo = xdga_find_display (dpy);
3958dd3e0eeSmrg    xXDGASetModeReply rep;
3968dd3e0eeSmrg    xXDGASetModeReq *req;
3978dd3e0eeSmrg    XDGADevice *dev = NULL;
3988dd3e0eeSmrg    Pixmap pid;
3998dd3e0eeSmrg
4008dd3e0eeSmrg    XDGACheckExtension (dpy, dinfo, NULL);
4018dd3e0eeSmrg
4028dd3e0eeSmrg    LockDisplay(dpy);
4038dd3e0eeSmrg    GetReq(XDGASetMode, req);
4048dd3e0eeSmrg    req->reqType = dinfo->codes->major_opcode;
4058dd3e0eeSmrg    req->dgaReqType = X_XDGASetMode;
4068dd3e0eeSmrg    req->screen = screen;
4078dd3e0eeSmrg    req->mode = mode;
4088dd3e0eeSmrg    req->pid = pid = XAllocID(dpy);
409d5a688bcSmrg
4108dd3e0eeSmrg    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
4118dd3e0eeSmrg	if(rep.length) {
4128dd3e0eeSmrg	   xXDGAModeInfo info;
413d5a688bcSmrg	   unsigned long size;
414d5a688bcSmrg
415d5a688bcSmrg	   if ((rep.length < (INT_MAX >> 2)) &&
416d5a688bcSmrg	       (rep.length > (sz_xXDGAModeInfo >> 2))) {
417d5a688bcSmrg	       size = rep.length << 2;
418d5a688bcSmrg	       size -= sz_xXDGAModeInfo; /* get text size */
4198dd3e0eeSmrg
420d5a688bcSmrg	       dev = Xmalloc(sizeof(XDGADevice) + size);
421d5a688bcSmrg	   }
4228dd3e0eeSmrg
4238dd3e0eeSmrg	   if(dev) {
4248dd3e0eeSmrg		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
4258dd3e0eeSmrg
4268dd3e0eeSmrg		dev->mode.num = info.num;
427d5a688bcSmrg		dev->mode.verticalRefresh =
4288dd3e0eeSmrg				(float)info.vsync_num / (float)info.vsync_den;
4298dd3e0eeSmrg		dev->mode.flags = info.flags;
4308dd3e0eeSmrg		dev->mode.imageWidth = info.image_width;
4318dd3e0eeSmrg		dev->mode.imageHeight = info.image_height;
4328dd3e0eeSmrg		dev->mode.pixmapWidth = info.pixmap_width;
4338dd3e0eeSmrg		dev->mode.pixmapHeight = info.pixmap_height;
4348dd3e0eeSmrg		dev->mode.bytesPerScanline = info.bytes_per_scanline;
4358dd3e0eeSmrg		dev->mode.byteOrder = info.byte_order;
4368dd3e0eeSmrg		dev->mode.depth = info.depth;
4378dd3e0eeSmrg		dev->mode.bitsPerPixel = info.bpp;
4388dd3e0eeSmrg		dev->mode.redMask = info.red_mask;
4398dd3e0eeSmrg		dev->mode.greenMask = info.green_mask;
4408dd3e0eeSmrg		dev->mode.blueMask = info.blue_mask;
4418dd3e0eeSmrg		dev->mode.visualClass = info.visual_class;
4428dd3e0eeSmrg		dev->mode.viewportWidth = info.viewport_width;
4438dd3e0eeSmrg		dev->mode.viewportHeight = info.viewport_height;
4448dd3e0eeSmrg		dev->mode.xViewportStep = info.viewport_xstep;
4458dd3e0eeSmrg		dev->mode.yViewportStep = info.viewport_ystep;
4468dd3e0eeSmrg		dev->mode.maxViewportX = info.viewport_xmax;
4478dd3e0eeSmrg		dev->mode.maxViewportY = info.viewport_ymax;
4488dd3e0eeSmrg		dev->mode.viewportFlags = info.viewport_flags;
4498dd3e0eeSmrg		dev->mode.reserved1 = info.reserved1;
4508dd3e0eeSmrg		dev->mode.reserved2 = info.reserved2;
4518dd3e0eeSmrg
452d5a688bcSmrg		if (info.name_size > 0 && info.name_size <= size) {
453d5a688bcSmrg		    dev->mode.name = (char*)(&dev[1]);
454d5a688bcSmrg		    _XRead(dpy, dev->mode.name, info.name_size);
455d5a688bcSmrg		    dev->mode.name[info.name_size - 1] = '\0';
456d5a688bcSmrg		} else {
457d5a688bcSmrg		    dev->mode.name = NULL;
458d5a688bcSmrg		    _XEatDataWords(dpy, rep.length);
459d5a688bcSmrg		}
4608dd3e0eeSmrg
4618dd3e0eeSmrg		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
4628dd3e0eeSmrg		dev->data = XDGAGetMappedMemory(screen);
4638dd3e0eeSmrg
4648dd3e0eeSmrg		if(dev->data)
4658dd3e0eeSmrg		    dev->data += rep.offset;
466d5a688bcSmrg	   }
4678dd3e0eeSmrg	   /* not sure what to do if the allocation fails */
468d5a688bcSmrg	   else
469d5a688bcSmrg	       _XEatDataWords(dpy, rep.length);
4708dd3e0eeSmrg	}
4718dd3e0eeSmrg    }
4728dd3e0eeSmrg
4738dd3e0eeSmrg    UnlockDisplay(dpy);
4748dd3e0eeSmrg    SyncHandle();
4758dd3e0eeSmrg
4768dd3e0eeSmrg    return dev;
4778dd3e0eeSmrg}
4788dd3e0eeSmrg
4798dd3e0eeSmrg
4808dd3e0eeSmrgvoid XDGASetViewport(
4818dd3e0eeSmrg    Display	*dpy,
4828dd3e0eeSmrg    int		screen,
4838dd3e0eeSmrg    int		x,
4848dd3e0eeSmrg    int		y,
4858dd3e0eeSmrg    int		flags
4868dd3e0eeSmrg){
4878dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
4888dd3e0eeSmrg    xXDGASetViewportReq *req;
4898dd3e0eeSmrg
4908dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
4918dd3e0eeSmrg
4928dd3e0eeSmrg    LockDisplay(dpy);
4938dd3e0eeSmrg    GetReq(XDGASetViewport, req);
4948dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
4958dd3e0eeSmrg    req->dgaReqType = X_XDGASetViewport;
4968dd3e0eeSmrg    req->screen = screen;
4978dd3e0eeSmrg    req->x = x;
4988dd3e0eeSmrg    req->y = y;
4998dd3e0eeSmrg    req->flags = flags;
5008dd3e0eeSmrg    UnlockDisplay(dpy);
5018dd3e0eeSmrg    SyncHandle();
5028dd3e0eeSmrg}
5038dd3e0eeSmrg
5048dd3e0eeSmrg
5058dd3e0eeSmrgvoid XDGAInstallColormap(
5068dd3e0eeSmrg    Display	*dpy,
5078dd3e0eeSmrg    int		screen,
5088dd3e0eeSmrg    Colormap	cmap
5098dd3e0eeSmrg){
5108dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5118dd3e0eeSmrg    xXDGAInstallColormapReq *req;
5128dd3e0eeSmrg
5138dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5148dd3e0eeSmrg
5158dd3e0eeSmrg    LockDisplay(dpy);
5168dd3e0eeSmrg    GetReq(XDGAInstallColormap, req);
5178dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5188dd3e0eeSmrg    req->dgaReqType = X_XDGAInstallColormap;
5198dd3e0eeSmrg    req->screen = screen;
5208dd3e0eeSmrg    req->cmap = cmap;
5218dd3e0eeSmrg    UnlockDisplay(dpy);
5228dd3e0eeSmrg    SyncHandle();
5238dd3e0eeSmrg}
5248dd3e0eeSmrg
5258dd3e0eeSmrgvoid XDGASelectInput(
5268dd3e0eeSmrg    Display	*dpy,
5278dd3e0eeSmrg    int		screen,
5288dd3e0eeSmrg    long	mask
5298dd3e0eeSmrg){
5308dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5318dd3e0eeSmrg    xXDGASelectInputReq *req;
5328dd3e0eeSmrg
5338dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5348dd3e0eeSmrg
5358dd3e0eeSmrg    LockDisplay(dpy);
5368dd3e0eeSmrg    GetReq(XDGASelectInput, req);
5378dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5388dd3e0eeSmrg    req->dgaReqType = X_XDGASelectInput;
5398dd3e0eeSmrg    req->screen = screen;
5408dd3e0eeSmrg    req->mask = mask;
5418dd3e0eeSmrg    UnlockDisplay(dpy);
5428dd3e0eeSmrg    SyncHandle();
5438dd3e0eeSmrg}
5448dd3e0eeSmrg
5458dd3e0eeSmrgvoid XDGAFillRectangle(
5468dd3e0eeSmrg    Display	*dpy,
5478dd3e0eeSmrg    int		screen,
5488dd3e0eeSmrg    int		x,
5498dd3e0eeSmrg    int		y,
5508dd3e0eeSmrg    unsigned int	width,
5518dd3e0eeSmrg    unsigned int	height,
5528dd3e0eeSmrg    unsigned long	color
5538dd3e0eeSmrg){
5548dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5558dd3e0eeSmrg    xXDGAFillRectangleReq *req;
5568dd3e0eeSmrg
5578dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5588dd3e0eeSmrg
5598dd3e0eeSmrg    LockDisplay(dpy);
5608dd3e0eeSmrg    GetReq(XDGAFillRectangle, req);
5618dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5628dd3e0eeSmrg    req->dgaReqType = X_XDGAFillRectangle;
5638dd3e0eeSmrg    req->screen = screen;
5648dd3e0eeSmrg    req->x = x;
5658dd3e0eeSmrg    req->y = y;
5668dd3e0eeSmrg    req->width = width;
5678dd3e0eeSmrg    req->height = height;
5688dd3e0eeSmrg    req->color = color;
5698dd3e0eeSmrg    UnlockDisplay(dpy);
5708dd3e0eeSmrg    SyncHandle();
5718dd3e0eeSmrg}
5728dd3e0eeSmrg
5738dd3e0eeSmrgvoid XDGACopyArea(
5748dd3e0eeSmrg    Display	*dpy,
5758dd3e0eeSmrg    int		screen,
5768dd3e0eeSmrg    int		srcx,
5778dd3e0eeSmrg    int		srcy,
5788dd3e0eeSmrg    unsigned int	width,
5798dd3e0eeSmrg    unsigned int	height,
5808dd3e0eeSmrg    int		dstx,
5818dd3e0eeSmrg    int		dsty
5828dd3e0eeSmrg){
5838dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
5848dd3e0eeSmrg    xXDGACopyAreaReq *req;
5858dd3e0eeSmrg
5868dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
5878dd3e0eeSmrg
5888dd3e0eeSmrg    LockDisplay(dpy);
5898dd3e0eeSmrg    GetReq(XDGACopyArea, req);
5908dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
5918dd3e0eeSmrg    req->dgaReqType = X_XDGACopyArea;
5928dd3e0eeSmrg    req->screen = screen;
5938dd3e0eeSmrg    req->srcx = srcx;
5948dd3e0eeSmrg    req->srcy = srcy;
5958dd3e0eeSmrg    req->width = width;
5968dd3e0eeSmrg    req->height = height;
5978dd3e0eeSmrg    req->dstx = dstx;
5988dd3e0eeSmrg    req->dsty = dsty;
5998dd3e0eeSmrg    UnlockDisplay(dpy);
6008dd3e0eeSmrg    SyncHandle();
6018dd3e0eeSmrg}
6028dd3e0eeSmrg
6038dd3e0eeSmrgvoid XDGACopyTransparentArea(
6048dd3e0eeSmrg    Display	*dpy,
6058dd3e0eeSmrg    int		screen,
6068dd3e0eeSmrg    int		srcx,
6078dd3e0eeSmrg    int		srcy,
6088dd3e0eeSmrg    unsigned int	width,
6098dd3e0eeSmrg    unsigned int	height,
6108dd3e0eeSmrg    int		dstx,
6118dd3e0eeSmrg    int		dsty,
6128dd3e0eeSmrg    unsigned long key
6138dd3e0eeSmrg){
6148dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6158dd3e0eeSmrg    xXDGACopyTransparentAreaReq *req;
6168dd3e0eeSmrg
6178dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6188dd3e0eeSmrg
6198dd3e0eeSmrg    LockDisplay(dpy);
6208dd3e0eeSmrg    GetReq(XDGACopyTransparentArea, req);
6218dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6228dd3e0eeSmrg    req->dgaReqType = X_XDGACopyTransparentArea;
6238dd3e0eeSmrg    req->screen = screen;
6248dd3e0eeSmrg    req->srcx = srcx;
6258dd3e0eeSmrg    req->srcy = srcy;
6268dd3e0eeSmrg    req->width = width;
6278dd3e0eeSmrg    req->height = height;
6288dd3e0eeSmrg    req->dstx = dstx;
6298dd3e0eeSmrg    req->dsty = dsty;
6308dd3e0eeSmrg    req->key = key;
6318dd3e0eeSmrg    UnlockDisplay(dpy);
6328dd3e0eeSmrg    SyncHandle();
6338dd3e0eeSmrg}
6348dd3e0eeSmrg
6358dd3e0eeSmrg
6368dd3e0eeSmrgint XDGAGetViewportStatus(
6378dd3e0eeSmrg    Display *dpy,
638d5a688bcSmrg    int screen
6398dd3e0eeSmrg){
6408dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6418dd3e0eeSmrg    xXDGAGetViewportStatusReply rep;
6428dd3e0eeSmrg    xXDGAGetViewportStatusReq *req;
6438dd3e0eeSmrg    int status = 0;
6448dd3e0eeSmrg
6458dd3e0eeSmrg    XDGACheckExtension (dpy, info, 0);
6468dd3e0eeSmrg
6478dd3e0eeSmrg    LockDisplay(dpy);
6488dd3e0eeSmrg    GetReq(XDGAGetViewportStatus, req);
6498dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6508dd3e0eeSmrg    req->dgaReqType = X_XDGAGetViewportStatus;
6518dd3e0eeSmrg    req->screen = screen;
6528dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
6538dd3e0eeSmrg	status = rep.status;
6548dd3e0eeSmrg    UnlockDisplay(dpy);
6558dd3e0eeSmrg    SyncHandle();
6568dd3e0eeSmrg    return status;
6578dd3e0eeSmrg}
6588dd3e0eeSmrg
6598dd3e0eeSmrgvoid XDGASync(
6608dd3e0eeSmrg    Display *dpy,
661d5a688bcSmrg    int screen
6628dd3e0eeSmrg){
6638dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6648dd3e0eeSmrg    xXDGASyncReply rep;
6658dd3e0eeSmrg    xXDGASyncReq *req;
6668dd3e0eeSmrg
6678dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6688dd3e0eeSmrg
6698dd3e0eeSmrg    LockDisplay(dpy);
6708dd3e0eeSmrg    GetReq(XDGASync, req);
6718dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6728dd3e0eeSmrg    req->dgaReqType = X_XDGASync;
6738dd3e0eeSmrg    req->screen = screen;
6748dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
6758dd3e0eeSmrg    UnlockDisplay(dpy);
6768dd3e0eeSmrg    SyncHandle();
6778dd3e0eeSmrg}
6788dd3e0eeSmrg
6798dd3e0eeSmrg
6808dd3e0eeSmrgvoid XDGAChangePixmapMode(
6818dd3e0eeSmrg    Display *dpy,
6828dd3e0eeSmrg    int screen,
6838dd3e0eeSmrg    int *x,
6848dd3e0eeSmrg    int *y,
685d5a688bcSmrg    int mode
6868dd3e0eeSmrg){
6878dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
6888dd3e0eeSmrg    xXDGAChangePixmapModeReq *req;
6898dd3e0eeSmrg    xXDGAChangePixmapModeReply rep;
6908dd3e0eeSmrg
6918dd3e0eeSmrg    XextSimpleCheckExtension (dpy, info, xdga_extension_name);
6928dd3e0eeSmrg
6938dd3e0eeSmrg    LockDisplay(dpy);
6948dd3e0eeSmrg    GetReq(XDGAChangePixmapMode, req);
6958dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
6968dd3e0eeSmrg    req->dgaReqType = X_XDGAChangePixmapMode;
6978dd3e0eeSmrg    req->screen = screen;
6988dd3e0eeSmrg    req->x = *x;
6998dd3e0eeSmrg    req->y = *y;
7008dd3e0eeSmrg    req->flags = mode;
7018dd3e0eeSmrg    _XReply(dpy, (xReply *)&rep, 0, xFalse);
7028dd3e0eeSmrg    *x = rep.x;
7038dd3e0eeSmrg    *y = rep.y;
7048dd3e0eeSmrg    UnlockDisplay(dpy);
7058dd3e0eeSmrg    SyncHandle();
7068dd3e0eeSmrg}
7078dd3e0eeSmrg
7088dd3e0eeSmrgColormap XDGACreateColormap(
7098dd3e0eeSmrg    Display *dpy,
7108dd3e0eeSmrg    int screen,
7118dd3e0eeSmrg    XDGADevice *dev,
7128dd3e0eeSmrg    int	alloc
7138dd3e0eeSmrg){
7148dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
7158dd3e0eeSmrg    xXDGACreateColormapReq *req;
7168dd3e0eeSmrg    Colormap cid;
7178dd3e0eeSmrg
7188dd3e0eeSmrg    XDGACheckExtension (dpy, info, -1);
7198dd3e0eeSmrg
7208dd3e0eeSmrg    LockDisplay(dpy);
7218dd3e0eeSmrg    GetReq(XDGACreateColormap, req);
7228dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
7238dd3e0eeSmrg    req->dgaReqType = X_XDGACreateColormap;
7248dd3e0eeSmrg    req->screen = screen;
7258dd3e0eeSmrg    req->mode = dev->mode.num;
7268dd3e0eeSmrg    req->alloc = alloc;
7278dd3e0eeSmrg    cid = req->id = XAllocID(dpy);
7288dd3e0eeSmrg    UnlockDisplay(dpy);
7298dd3e0eeSmrg    SyncHandle();
7308dd3e0eeSmrg
7318dd3e0eeSmrg    return cid;
7328dd3e0eeSmrg}
7338dd3e0eeSmrg
7348dd3e0eeSmrg
7358dd3e0eeSmrgvoid XDGAKeyEventToXKeyEvent(
736d5a688bcSmrg    XDGAKeyEvent* dk,
7378dd3e0eeSmrg    XKeyEvent* xk
7388dd3e0eeSmrg){
7398dd3e0eeSmrg    xk->type = dk->type;
7408dd3e0eeSmrg    xk->serial = dk->serial;
7418dd3e0eeSmrg    xk->send_event = False;
7428dd3e0eeSmrg    xk->display = dk->display;
7438dd3e0eeSmrg    xk->window = RootWindow(dk->display, dk->screen);
7448dd3e0eeSmrg    xk->root = xk->window;
7458dd3e0eeSmrg    xk->subwindow = None;
7468dd3e0eeSmrg    xk->time = dk->time;
7478dd3e0eeSmrg    xk->x = xk->y = xk->x_root = xk->y_root = 0;
7488dd3e0eeSmrg    xk->state = dk->state;
7498dd3e0eeSmrg    xk->keycode = dk->keycode;
7508dd3e0eeSmrg    xk->same_screen = True;
7518dd3e0eeSmrg}
7528dd3e0eeSmrg
7538dd3e0eeSmrg#include <X11/Xmd.h>
7548dd3e0eeSmrg#include <stdlib.h>
7558dd3e0eeSmrg#include <stdio.h>
7568dd3e0eeSmrg#include <fcntl.h>
757d5a688bcSmrg#if defined(ISC)
7588dd3e0eeSmrg# define HAS_SVR3_MMAP
7598dd3e0eeSmrg# include <sys/types.h>
7608dd3e0eeSmrg# include <errno.h>
7618dd3e0eeSmrg
7628dd3e0eeSmrg# include <sys/at_ansi.h>
7638dd3e0eeSmrg# include <sys/kd.h>
7648dd3e0eeSmrg
7658dd3e0eeSmrg# include <sys/sysmacros.h>
7668dd3e0eeSmrg# include <sys/immu.h>
7678dd3e0eeSmrg# include <sys/region.h>
7688dd3e0eeSmrg
7698dd3e0eeSmrg# include <sys/mmap.h>
7708dd3e0eeSmrg#else
7718dd3e0eeSmrg# if defined(Lynx) && defined(NO_MMAP)
7728dd3e0eeSmrg#  include <sys/types.h>
7738dd3e0eeSmrg#  include <errno.h>
7748dd3e0eeSmrg#  include <smem.h>
7758dd3e0eeSmrg# else
7768dd3e0eeSmrg#  if !defined(__UNIXOS2__)
7778dd3e0eeSmrg#   include <sys/mman.h>
7788dd3e0eeSmrg#  endif
7798dd3e0eeSmrg# endif
7808dd3e0eeSmrg#endif
7818dd3e0eeSmrg#include <sys/wait.h>
7828dd3e0eeSmrg#include <signal.h>
7838dd3e0eeSmrg#include <unistd.h>
7848dd3e0eeSmrg
7858dd3e0eeSmrg#if defined(SVR4) && !defined(sun)
7868dd3e0eeSmrg#define DEV_MEM "/dev/pmem"
7878dd3e0eeSmrg#elif defined(SVR4) && defined(sun)
7888dd3e0eeSmrg#define DEV_MEM "/dev/xsvc"
7898dd3e0eeSmrg#elif defined(HAS_APERTURE_DRV)
7908dd3e0eeSmrg#define DEV_MEM "/dev/xf86"
7918dd3e0eeSmrg#else
7928dd3e0eeSmrg#define DEV_MEM "/dev/mem"
7938dd3e0eeSmrg#endif
7948dd3e0eeSmrg
7958dd3e0eeSmrg
7968dd3e0eeSmrg
7978dd3e0eeSmrgtypedef struct _DGAMapRec{
7988dd3e0eeSmrg  unsigned char *physical;
7998dd3e0eeSmrg  unsigned char *virtual;
8008dd3e0eeSmrg  CARD32 size;
8018dd3e0eeSmrg  int fd;
8028dd3e0eeSmrg  int screen;
8038dd3e0eeSmrg  struct _DGAMapRec *next;
8048dd3e0eeSmrg} DGAMapRec, *DGAMapPtr;
8058dd3e0eeSmrg
8068dd3e0eeSmrgstatic Bool
807d5a688bcSmrgDGAMapPhysical(int, const char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
8088dd3e0eeSmrgstatic void DGAUnmapPhysical(DGAMapPtr);
8098dd3e0eeSmrg
8108dd3e0eeSmrgstatic DGAMapPtr _Maps = NULL;
8118dd3e0eeSmrg
8128dd3e0eeSmrg
8138dd3e0eeSmrgunsigned char*
8148dd3e0eeSmrgXDGAGetMappedMemory(int screen)
8158dd3e0eeSmrg{
8168dd3e0eeSmrg    DGAMapPtr pMap = _Maps;
8178dd3e0eeSmrg    unsigned char *pntr = NULL;
8188dd3e0eeSmrg
8198dd3e0eeSmrg    while(pMap != NULL) {
8208dd3e0eeSmrg	if(pMap->screen == screen) {
8218dd3e0eeSmrg	    pntr = pMap->virtual;
8228dd3e0eeSmrg	    break;
8238dd3e0eeSmrg	}
8248dd3e0eeSmrg	pMap = pMap->next;
8258dd3e0eeSmrg    }
8268dd3e0eeSmrg
8278dd3e0eeSmrg    return pntr;
8288dd3e0eeSmrg}
8298dd3e0eeSmrg
8308dd3e0eeSmrgBool
8318dd3e0eeSmrgXDGAMapFramebuffer(
8328dd3e0eeSmrg   int screen,
8338dd3e0eeSmrg   char *name,			/* optional device name */
8348dd3e0eeSmrg   unsigned char* base,		/* physical memory */
8358dd3e0eeSmrg   CARD32 size,			/* size */
8368dd3e0eeSmrg   CARD32 offset,		/* optional offset */
8378dd3e0eeSmrg   CARD32 extra			/* optional extra data */
8388dd3e0eeSmrg){
8398dd3e0eeSmrg   DGAMapPtr pMap = _Maps;
8408dd3e0eeSmrg   Bool result;
841d5a688bcSmrg
8428dd3e0eeSmrg   /* is it already mapped ? */
8438dd3e0eeSmrg   while(pMap != NULL) {
8448dd3e0eeSmrg     if(pMap->screen == screen)
8458dd3e0eeSmrg	return True;
8468dd3e0eeSmrg     pMap = pMap->next;
8478dd3e0eeSmrg   }
8488dd3e0eeSmrg
8498dd3e0eeSmrg   if(extra & XDGANeedRoot) {
8508dd3e0eeSmrg    /* we should probably check if we have root permissions and
8518dd3e0eeSmrg       return False here */
8528dd3e0eeSmrg
8538dd3e0eeSmrg   }
8548dd3e0eeSmrg
8558dd3e0eeSmrg   pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
8568dd3e0eeSmrg
8578dd3e0eeSmrg   result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
8588dd3e0eeSmrg
8598dd3e0eeSmrg   if(result) {
8608dd3e0eeSmrg      pMap->next = _Maps;
8618dd3e0eeSmrg      _Maps = pMap;
862d5a688bcSmrg   } else
8638dd3e0eeSmrg      Xfree(pMap);
864d5a688bcSmrg
8658dd3e0eeSmrg   return result;
8668dd3e0eeSmrg}
8678dd3e0eeSmrg
8688dd3e0eeSmrgvoid
8698dd3e0eeSmrgXDGAUnmapFramebuffer(int screen)
8708dd3e0eeSmrg{
8718dd3e0eeSmrg   DGAMapPtr pMap = _Maps;
8728dd3e0eeSmrg   DGAMapPtr pPrev = NULL;
8738dd3e0eeSmrg
8748dd3e0eeSmrg   /* is it already mapped */
8758dd3e0eeSmrg    while(pMap != NULL) {
8768dd3e0eeSmrg	if(pMap->screen == screen)
8778dd3e0eeSmrg	    break;
8788dd3e0eeSmrg	pPrev = pMap;
8798dd3e0eeSmrg	pMap = pMap->next;
8808dd3e0eeSmrg    }
8818dd3e0eeSmrg
8828dd3e0eeSmrg    if(!pMap)
8838dd3e0eeSmrg	return;
8848dd3e0eeSmrg
8858dd3e0eeSmrg    DGAUnmapPhysical(pMap);
8868dd3e0eeSmrg
8878dd3e0eeSmrg    if(!pPrev)
8888dd3e0eeSmrg	_Maps = pMap->next;
8898dd3e0eeSmrg    else
8908dd3e0eeSmrg	pPrev->next = pMap->next;
8918dd3e0eeSmrg
8928dd3e0eeSmrg    Xfree(pMap);
8938dd3e0eeSmrg}
8948dd3e0eeSmrg
8958dd3e0eeSmrg
8968dd3e0eeSmrgstatic Bool
8978dd3e0eeSmrgDGAMapPhysical(
8988dd3e0eeSmrg   int screen,
899d5a688bcSmrg   const char *name,		/* optional device name */
9008dd3e0eeSmrg   unsigned char* base,		/* physical memory */
9018dd3e0eeSmrg   CARD32 size,			/* size */
9028dd3e0eeSmrg   CARD32 offset,		/* optional offset */
9038dd3e0eeSmrg   CARD32 extra,		/* optional extra data */
9048dd3e0eeSmrg   DGAMapPtr pMap
9058dd3e0eeSmrg) {
9068dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
9078dd3e0eeSmrg    struct kd_memloc mloc;
9088dd3e0eeSmrg#elif defined(__UNIXOS2__)
9098dd3e0eeSmrg    APIRET rc;
9108dd3e0eeSmrg    ULONG action;
9118dd3e0eeSmrg    HFILE hfd;
9128dd3e0eeSmrg#endif
913d5a688bcSmrg
9148dd3e0eeSmrg    base += offset;
9158dd3e0eeSmrg
9168dd3e0eeSmrg    pMap->screen = screen;
9178dd3e0eeSmrg    pMap->physical = base;
9188dd3e0eeSmrg    pMap->size = size;
9198dd3e0eeSmrg
9208dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
9218dd3e0eeSmrg    if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
9228dd3e0eeSmrg	return False;
9238dd3e0eeSmrg    mloc.vaddr = (char *)0;
9248dd3e0eeSmrg    mloc.physaddr = (char *)base;
9258dd3e0eeSmrg    mloc.length = size;
9268dd3e0eeSmrg    mloc.ioflg=1;
9278dd3e0eeSmrg
9288dd3e0eeSmrg    if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
9298dd3e0eeSmrg	return False;
9308dd3e0eeSmrg#elif defined (__UNIXOS2__)
9318dd3e0eeSmrg    /*
9328dd3e0eeSmrg     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
9338dd3e0eeSmrg     * Consecutive calling of this routine will make PMAP$ driver run out
9348dd3e0eeSmrg     * of memory handles. Some umap/close mechanism should be provided
9358dd3e0eeSmrg     */
9368dd3e0eeSmrg
9378dd3e0eeSmrg    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
9388dd3e0eeSmrg		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
9398dd3e0eeSmrg    if (rc != 0)
9408dd3e0eeSmrg	return False;
9418dd3e0eeSmrg    {
9428dd3e0eeSmrg	struct map_ioctl {
9438dd3e0eeSmrg		union {
9448dd3e0eeSmrg			ULONG phys;
9458dd3e0eeSmrg			void* user;
9468dd3e0eeSmrg		} a;
9478dd3e0eeSmrg		ULONG size;
9488dd3e0eeSmrg	} pmap,dmap;
9498dd3e0eeSmrg	ULONG plen,dlen;
9508dd3e0eeSmrg#define XFREE86_PMAP	0x76
9518dd3e0eeSmrg#define PMAP_MAP	0x44
9528dd3e0eeSmrg
9538dd3e0eeSmrg	pmap.a.phys = base;
9548dd3e0eeSmrg	pmap.size = size;
9558dd3e0eeSmrg	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
9568dd3e0eeSmrg			 (PULONG)&pmap, sizeof(pmap), &plen,
9578dd3e0eeSmrg			 (PULONG)&dmap, sizeof(dmap), &dlen);
9588dd3e0eeSmrg	if (rc == 0) {
9598dd3e0eeSmrg		pMap->virtual = dmap.a.user;
9608dd3e0eeSmrg	}
9618dd3e0eeSmrg   }
9628dd3e0eeSmrg   if (rc != 0)
9638dd3e0eeSmrg	return False;
9648dd3e0eeSmrg#elif defined (Lynx) && defined(NO_MMAP)
9658dd3e0eeSmrg    pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
9668dd3e0eeSmrg#else
9678dd3e0eeSmrg#ifndef MAP_FILE
9688dd3e0eeSmrg#define MAP_FILE 0
9698dd3e0eeSmrg#endif
9708dd3e0eeSmrg    if (!name)
9718dd3e0eeSmrg	    name = DEV_MEM;
9728dd3e0eeSmrg    if ((pMap->fd = open(name, O_RDWR)) < 0)
9738dd3e0eeSmrg	return False;
974d5a688bcSmrg    pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
975d5a688bcSmrg			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)(uintptr_t)base);
9768dd3e0eeSmrg    if (pMap->virtual == (void *)-1)
9778dd3e0eeSmrg	return False;
9788dd3e0eeSmrg    mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
9798dd3e0eeSmrg#endif
9808dd3e0eeSmrg
9818dd3e0eeSmrg    return True;
9828dd3e0eeSmrg}
9838dd3e0eeSmrg
9848dd3e0eeSmrg
9858dd3e0eeSmrg
9868dd3e0eeSmrgstatic void
9878dd3e0eeSmrgDGAUnmapPhysical(DGAMapPtr pMap)
9888dd3e0eeSmrg{
9898dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
9908dd3e0eeSmrg    /* XXX Add unmapping code here. */
9918dd3e0eeSmrg#elif defined (__UNIXOS2__)
9928dd3e0eeSmrg    /* XXX Add unmapping code here. */
9938dd3e0eeSmrg#elif defined(Lynx) && defined(NO_MMAP)
9948dd3e0eeSmrg	/* XXX this doesn't allow enable after disable */
9958dd3e0eeSmrg    smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
9968dd3e0eeSmrg    smem_remove("XF86DGA");
9978dd3e0eeSmrg#else
9988dd3e0eeSmrg    if (pMap->virtual && pMap->virtual != (void *)-1) {
9998dd3e0eeSmrg	mprotect(pMap->virtual,pMap->size, PROT_READ);
10008dd3e0eeSmrg	munmap(pMap->virtual, pMap->size);
10018dd3e0eeSmrg	pMap->virtual = 0;
10028dd3e0eeSmrg    }
10038dd3e0eeSmrg    if (pMap->fd >= 0) {
10048dd3e0eeSmrg	close(pMap->fd);
10058dd3e0eeSmrg	pMap->fd = -1;
10068dd3e0eeSmrg    }
10078dd3e0eeSmrg#endif
10088dd3e0eeSmrg}
1009