XF86DGA.c revision da01b833
18dd3e0eeSmrg/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.23tsi 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#if defined(linux)
198dd3e0eeSmrg#define HAS_MMAP_ANON
208dd3e0eeSmrg#include <sys/types.h>
218dd3e0eeSmrg#include <sys/mman.h>
228dd3e0eeSmrg/* kernel header doesn't work with -ansi */
238dd3e0eeSmrg/* #include <asm/page.h> */   /* PAGE_SIZE */
248dd3e0eeSmrg#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
258dd3e0eeSmrg#define HAS_GETPAGESIZE
268dd3e0eeSmrg#endif /* linux */
278dd3e0eeSmrg
288dd3e0eeSmrg#if defined(CSRG_BASED)
298dd3e0eeSmrg#define HAS_MMAP_ANON
308dd3e0eeSmrg#define HAS_GETPAGESIZE
318dd3e0eeSmrg#include <sys/types.h>
328dd3e0eeSmrg#include <sys/mman.h>
338dd3e0eeSmrg#endif /* CSRG_BASED */
348dd3e0eeSmrg
358dd3e0eeSmrg#if defined(DGUX)
368dd3e0eeSmrg#define HAS_GETPAGESIZE
378dd3e0eeSmrg#define MMAP_DEV_ZERO
388dd3e0eeSmrg#include <sys/types.h>
398dd3e0eeSmrg#include <sys/mman.h>
408dd3e0eeSmrg#include <unistd.h>
418dd3e0eeSmrg#endif /* DGUX */
428dd3e0eeSmrg
438dd3e0eeSmrg#if defined(SVR4) && !defined(DGUX)
448dd3e0eeSmrg#define MMAP_DEV_ZERO
458dd3e0eeSmrg#include <sys/types.h>
468dd3e0eeSmrg#include <sys/mman.h>
478dd3e0eeSmrg#include <unistd.h>
488dd3e0eeSmrg#endif /* SVR4 && !DGUX */
498dd3e0eeSmrg
508dd3e0eeSmrg#if defined(sun) && !defined(SVR4) /* SunOS */
518dd3e0eeSmrg#define MMAP_DEV_ZERO   /* doesn't SunOS have MAP_ANON ?? */
528dd3e0eeSmrg#define HAS_GETPAGESIZE
538dd3e0eeSmrg#include <sys/types.h>
548dd3e0eeSmrg#include <sys/mman.h>
558dd3e0eeSmrg#endif /* sun && !SVR4 */
568dd3e0eeSmrg
578dd3e0eeSmrg#ifdef XNO_SYSCONF
588dd3e0eeSmrg#undef _SC_PAGESIZE
598dd3e0eeSmrg#endif
608dd3e0eeSmrg
618dd3e0eeSmrg#include <X11/Xlibint.h>
62329fdfe9Smrg#include <X11/extensions/Xxf86dga.h>
63329fdfe9Smrg#include <X11/extensions/xf86dgaproto.h>
648dd3e0eeSmrg#include <X11/extensions/Xext.h>
658dd3e0eeSmrg#include <X11/extensions/extutil.h>
668dd3e0eeSmrg
678dd3e0eeSmrgextern XExtDisplayInfo* xdga_find_display(Display*);
68d5a688bcSmrgextern const char *xdga_extension_name;
698dd3e0eeSmrg
708dd3e0eeSmrg#define XF86DGACheckExtension(dpy,i,val) \
718dd3e0eeSmrg  XextCheckExtension (dpy, i, xdga_extension_name, val)
728dd3e0eeSmrg
738dd3e0eeSmrg/*****************************************************************************
748dd3e0eeSmrg *                                                                           *
758dd3e0eeSmrg *		    public XFree86-DGA Extension routines                    *
768dd3e0eeSmrg *                                                                           *
778dd3e0eeSmrg *****************************************************************************/
788dd3e0eeSmrg
798dd3e0eeSmrgBool XF86DGAQueryExtension (
808dd3e0eeSmrg    Display *dpy,
818dd3e0eeSmrg    int *event_basep,
828dd3e0eeSmrg    int *error_basep
838dd3e0eeSmrg){
848dd3e0eeSmrg    return XDGAQueryExtension(dpy, event_basep, error_basep);
858dd3e0eeSmrg}
868dd3e0eeSmrg
878dd3e0eeSmrgBool XF86DGAQueryVersion(
888dd3e0eeSmrg    Display* dpy,
89d5a688bcSmrg    int* majorVersion,
908dd3e0eeSmrg    int* minorVersion
918dd3e0eeSmrg){
928dd3e0eeSmrg    return XDGAQueryVersion(dpy, majorVersion, minorVersion);
938dd3e0eeSmrg}
948dd3e0eeSmrg
958dd3e0eeSmrgBool XF86DGAGetVideoLL(
968dd3e0eeSmrg    Display* dpy,
978dd3e0eeSmrg    int screen,
988dd3e0eeSmrg    unsigned int *offset,
99d5a688bcSmrg    int *width,
100d5a688bcSmrg    int *bank_size,
1018dd3e0eeSmrg    int *ram_size
1028dd3e0eeSmrg){
1038dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1048dd3e0eeSmrg    xXF86DGAGetVideoLLReply rep;
1058dd3e0eeSmrg    xXF86DGAGetVideoLLReq *req;
1068dd3e0eeSmrg
1078dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
1088dd3e0eeSmrg
1098dd3e0eeSmrg    LockDisplay(dpy);
1108dd3e0eeSmrg    GetReq(XF86DGAGetVideoLL, req);
1118dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1128dd3e0eeSmrg    req->dgaReqType = X_XF86DGAGetVideoLL;
1138dd3e0eeSmrg    req->screen = screen;
1148dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1158dd3e0eeSmrg	UnlockDisplay(dpy);
1168dd3e0eeSmrg	SyncHandle();
1178dd3e0eeSmrg	return False;
1188dd3e0eeSmrg    }
1198dd3e0eeSmrg
1208dd3e0eeSmrg    *offset = rep.offset;
1218dd3e0eeSmrg    *width = rep.width;
1228dd3e0eeSmrg    *bank_size = rep.bank_size;
1238dd3e0eeSmrg    *ram_size = rep.ram_size;
124d5a688bcSmrg
1258dd3e0eeSmrg    UnlockDisplay(dpy);
1268dd3e0eeSmrg    SyncHandle();
1278dd3e0eeSmrg    return True;
1288dd3e0eeSmrg}
1298dd3e0eeSmrg
130d5a688bcSmrg
1318dd3e0eeSmrgBool XF86DGADirectVideoLL(
1328dd3e0eeSmrg    Display* dpy,
1338dd3e0eeSmrg    int screen,
1348dd3e0eeSmrg    int enable
1358dd3e0eeSmrg){
1368dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1378dd3e0eeSmrg    xXF86DGADirectVideoReq *req;
1388dd3e0eeSmrg
1398dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
1408dd3e0eeSmrg
1418dd3e0eeSmrg    LockDisplay(dpy);
1428dd3e0eeSmrg    GetReq(XF86DGADirectVideo, req);
1438dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1448dd3e0eeSmrg    req->dgaReqType = X_XF86DGADirectVideo;
1458dd3e0eeSmrg    req->screen = screen;
1468dd3e0eeSmrg    req->enable = enable;
1478dd3e0eeSmrg    UnlockDisplay(dpy);
1488dd3e0eeSmrg    SyncHandle();
1498dd3e0eeSmrg    XSync(dpy,False);
1508dd3e0eeSmrg    return True;
1518dd3e0eeSmrg}
1528dd3e0eeSmrg
1538dd3e0eeSmrgBool XF86DGAGetViewPortSize(
1548dd3e0eeSmrg    Display* dpy,
1558dd3e0eeSmrg    int screen,
156d5a688bcSmrg    int *width,
1578dd3e0eeSmrg    int *height
1588dd3e0eeSmrg){
1598dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1608dd3e0eeSmrg    xXF86DGAGetViewPortSizeReply rep;
1618dd3e0eeSmrg    xXF86DGAGetViewPortSizeReq *req;
1628dd3e0eeSmrg
1638dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
1648dd3e0eeSmrg
1658dd3e0eeSmrg    LockDisplay(dpy);
1668dd3e0eeSmrg    GetReq(XF86DGAGetViewPortSize, req);
1678dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1688dd3e0eeSmrg    req->dgaReqType = X_XF86DGAGetViewPortSize;
1698dd3e0eeSmrg    req->screen = screen;
1708dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1718dd3e0eeSmrg	UnlockDisplay(dpy);
1728dd3e0eeSmrg	SyncHandle();
1738dd3e0eeSmrg	return False;
1748dd3e0eeSmrg    }
1758dd3e0eeSmrg
1768dd3e0eeSmrg    *width = rep.width;
1778dd3e0eeSmrg    *height = rep.height;
178d5a688bcSmrg
1798dd3e0eeSmrg    UnlockDisplay(dpy);
1808dd3e0eeSmrg    SyncHandle();
1818dd3e0eeSmrg    return True;
1828dd3e0eeSmrg}
183d5a688bcSmrg
184d5a688bcSmrg
1858dd3e0eeSmrgBool XF86DGASetViewPort(
1868dd3e0eeSmrg    Display* dpy,
1878dd3e0eeSmrg    int screen,
188d5a688bcSmrg    int x,
1898dd3e0eeSmrg    int y
1908dd3e0eeSmrg){
1918dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
1928dd3e0eeSmrg    xXF86DGASetViewPortReq *req;
1938dd3e0eeSmrg
1948dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
1958dd3e0eeSmrg
1968dd3e0eeSmrg    LockDisplay(dpy);
1978dd3e0eeSmrg    GetReq(XF86DGASetViewPort, req);
1988dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
1998dd3e0eeSmrg    req->dgaReqType = X_XF86DGASetViewPort;
2008dd3e0eeSmrg    req->screen = screen;
2018dd3e0eeSmrg    req->x = x;
2028dd3e0eeSmrg    req->y = y;
2038dd3e0eeSmrg    UnlockDisplay(dpy);
2048dd3e0eeSmrg    SyncHandle();
2058dd3e0eeSmrg    XSync(dpy,False);
2068dd3e0eeSmrg    return True;
2078dd3e0eeSmrg}
2088dd3e0eeSmrg
209d5a688bcSmrg
2108dd3e0eeSmrgBool XF86DGAGetVidPage(
2118dd3e0eeSmrg    Display* dpy,
2128dd3e0eeSmrg    int screen,
2138dd3e0eeSmrg    int *vpage
2148dd3e0eeSmrg){
2158dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2168dd3e0eeSmrg    xXF86DGAGetVidPageReply rep;
2178dd3e0eeSmrg    xXF86DGAGetVidPageReq *req;
2188dd3e0eeSmrg
2198dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
2208dd3e0eeSmrg
2218dd3e0eeSmrg    LockDisplay(dpy);
2228dd3e0eeSmrg    GetReq(XF86DGAGetVidPage, req);
2238dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2248dd3e0eeSmrg    req->dgaReqType = X_XF86DGAGetVidPage;
2258dd3e0eeSmrg    req->screen = screen;
2268dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
2278dd3e0eeSmrg	UnlockDisplay(dpy);
2288dd3e0eeSmrg	SyncHandle();
2298dd3e0eeSmrg	return False;
2308dd3e0eeSmrg    }
2318dd3e0eeSmrg
2328dd3e0eeSmrg    *vpage = rep.vpage;
2338dd3e0eeSmrg    UnlockDisplay(dpy);
2348dd3e0eeSmrg    SyncHandle();
2358dd3e0eeSmrg    return True;
2368dd3e0eeSmrg}
2378dd3e0eeSmrg
238d5a688bcSmrg
2398dd3e0eeSmrgBool XF86DGASetVidPage(
2408dd3e0eeSmrg    Display* dpy,
2418dd3e0eeSmrg    int screen,
2428dd3e0eeSmrg    int vpage
2438dd3e0eeSmrg){
2448dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2458dd3e0eeSmrg    xXF86DGASetVidPageReq *req;
2468dd3e0eeSmrg
2478dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
2488dd3e0eeSmrg
2498dd3e0eeSmrg    LockDisplay(dpy);
2508dd3e0eeSmrg    GetReq(XF86DGASetVidPage, req);
2518dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2528dd3e0eeSmrg    req->dgaReqType = X_XF86DGASetVidPage;
2538dd3e0eeSmrg    req->screen = screen;
2548dd3e0eeSmrg    req->vpage = vpage;
2558dd3e0eeSmrg    UnlockDisplay(dpy);
2568dd3e0eeSmrg    SyncHandle();
2578dd3e0eeSmrg    XSync(dpy,False);
2588dd3e0eeSmrg    return True;
2598dd3e0eeSmrg}
2608dd3e0eeSmrg
2618dd3e0eeSmrgBool XF86DGAInstallColormap(
2628dd3e0eeSmrg    Display* dpy,
2638dd3e0eeSmrg    int screen,
2648dd3e0eeSmrg    Colormap cmap
2658dd3e0eeSmrg){
2668dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2678dd3e0eeSmrg    xXF86DGAInstallColormapReq *req;
2688dd3e0eeSmrg
2698dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
2708dd3e0eeSmrg
2718dd3e0eeSmrg    LockDisplay(dpy);
2728dd3e0eeSmrg    GetReq(XF86DGAInstallColormap, req);
2738dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2748dd3e0eeSmrg    req->dgaReqType = X_XF86DGAInstallColormap;
2758dd3e0eeSmrg    req->screen = screen;
2768dd3e0eeSmrg    req->id = cmap;
2778dd3e0eeSmrg    UnlockDisplay(dpy);
2788dd3e0eeSmrg    SyncHandle();
2798dd3e0eeSmrg    XSync(dpy,False);
2808dd3e0eeSmrg    return True;
2818dd3e0eeSmrg}
2828dd3e0eeSmrg
2838dd3e0eeSmrgBool XF86DGAQueryDirectVideo(
2848dd3e0eeSmrg    Display *dpy,
2858dd3e0eeSmrg    int screen,
2868dd3e0eeSmrg    int *flags
2878dd3e0eeSmrg){
2888dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
2898dd3e0eeSmrg    xXF86DGAQueryDirectVideoReply rep;
2908dd3e0eeSmrg    xXF86DGAQueryDirectVideoReq *req;
2918dd3e0eeSmrg
2928dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
2938dd3e0eeSmrg
2948dd3e0eeSmrg    LockDisplay(dpy);
2958dd3e0eeSmrg    GetReq(XF86DGAQueryDirectVideo, req);
2968dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
2978dd3e0eeSmrg    req->dgaReqType = X_XF86DGAQueryDirectVideo;
2988dd3e0eeSmrg    req->screen = screen;
2998dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3008dd3e0eeSmrg	UnlockDisplay(dpy);
3018dd3e0eeSmrg	SyncHandle();
3028dd3e0eeSmrg	return False;
3038dd3e0eeSmrg    }
3048dd3e0eeSmrg    *flags = rep.flags;
3058dd3e0eeSmrg    UnlockDisplay(dpy);
3068dd3e0eeSmrg    SyncHandle();
3078dd3e0eeSmrg    return True;
3088dd3e0eeSmrg}
3098dd3e0eeSmrg
3108dd3e0eeSmrgBool XF86DGAViewPortChanged(
3118dd3e0eeSmrg    Display *dpy,
3128dd3e0eeSmrg    int screen,
3138dd3e0eeSmrg    int n
3148dd3e0eeSmrg){
3158dd3e0eeSmrg    XExtDisplayInfo *info = xdga_find_display (dpy);
3168dd3e0eeSmrg    xXF86DGAViewPortChangedReply rep;
3178dd3e0eeSmrg    xXF86DGAViewPortChangedReq *req;
3188dd3e0eeSmrg
3198dd3e0eeSmrg    XF86DGACheckExtension (dpy, info, False);
3208dd3e0eeSmrg
3218dd3e0eeSmrg    LockDisplay(dpy);
3228dd3e0eeSmrg    GetReq(XF86DGAViewPortChanged, req);
3238dd3e0eeSmrg    req->reqType = info->codes->major_opcode;
3248dd3e0eeSmrg    req->dgaReqType = X_XF86DGAViewPortChanged;
3258dd3e0eeSmrg    req->screen = screen;
3268dd3e0eeSmrg    req->n = n;
3278dd3e0eeSmrg    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
3288dd3e0eeSmrg	UnlockDisplay(dpy);
3298dd3e0eeSmrg	SyncHandle();
3308dd3e0eeSmrg	return False;
3318dd3e0eeSmrg    }
3328dd3e0eeSmrg    UnlockDisplay(dpy);
3338dd3e0eeSmrg    SyncHandle();
3348dd3e0eeSmrg    return rep.result;
3358dd3e0eeSmrg}
3368dd3e0eeSmrg
3378dd3e0eeSmrg
3388dd3e0eeSmrg
3398dd3e0eeSmrg/* Helper functions */
3408dd3e0eeSmrg
3418dd3e0eeSmrg#include <X11/Xmd.h>
3428dd3e0eeSmrg#include <stdlib.h>
3438dd3e0eeSmrg#include <stdio.h>
3448dd3e0eeSmrg#include <fcntl.h>
345d5a688bcSmrg#if defined(ISC)
3468dd3e0eeSmrg# define HAS_SVR3_MMAP
3478dd3e0eeSmrg# include <sys/types.h>
3488dd3e0eeSmrg# include <errno.h>
3498dd3e0eeSmrg
3508dd3e0eeSmrg# include <sys/at_ansi.h>
3518dd3e0eeSmrg# include <sys/kd.h>
3528dd3e0eeSmrg
3538dd3e0eeSmrg# include <sys/sysmacros.h>
3548dd3e0eeSmrg# include <sys/immu.h>
3558dd3e0eeSmrg# include <sys/region.h>
3568dd3e0eeSmrg
3578dd3e0eeSmrg# include <sys/mmap.h>
3588dd3e0eeSmrg#else
3598dd3e0eeSmrg# if defined(Lynx) && defined(NO_MMAP)
3608dd3e0eeSmrg#  include <sys/types.h>
3618dd3e0eeSmrg#  include <errno.h>
3628dd3e0eeSmrg#  include <smem.h>
3638dd3e0eeSmrg# else
3648dd3e0eeSmrg#  if !defined(__UNIXOS2__)
3658dd3e0eeSmrg#   include <sys/mman.h>
3668dd3e0eeSmrg#  endif
3678dd3e0eeSmrg# endif
3688dd3e0eeSmrg#endif
3698dd3e0eeSmrg#include <sys/wait.h>
3708dd3e0eeSmrg#include <signal.h>
3718dd3e0eeSmrg#include <unistd.h>
3728dd3e0eeSmrg
3738dd3e0eeSmrg#if defined(SVR4) && !defined(sun)
3748dd3e0eeSmrg#define DEV_MEM "/dev/pmem"
3758dd3e0eeSmrg#elif defined(SVR4) && defined(sun)
3768dd3e0eeSmrg#define DEV_MEM "/dev/xsvc"
3778dd3e0eeSmrg#elif defined(HAS_APERTURE_DRV)
3788dd3e0eeSmrg#define DEV_MEM "/dev/xf86"
3798dd3e0eeSmrg#else
3808dd3e0eeSmrg#define DEV_MEM "/dev/mem"
3818dd3e0eeSmrg#endif
3828dd3e0eeSmrg
3838dd3e0eeSmrgtypedef struct {
3848dd3e0eeSmrg    unsigned long physaddr;	/* actual requested physical address */
3858dd3e0eeSmrg    unsigned long size;		/* actual requested map size */
3868dd3e0eeSmrg    unsigned long delta;	/* delta to account for page alignment */
3878dd3e0eeSmrg    void *	  vaddr;	/* mapped address, without the delta */
3888dd3e0eeSmrg    int		  refcount;	/* reference count */
3898dd3e0eeSmrg} MapRec, *MapPtr;
3908dd3e0eeSmrg
3918dd3e0eeSmrgtypedef struct {
3928dd3e0eeSmrg    Display *	display;
3938dd3e0eeSmrg    int		screen;
3948dd3e0eeSmrg    MapPtr	map;
3958dd3e0eeSmrg} ScrRec, *ScrPtr;
3968dd3e0eeSmrg
3978dd3e0eeSmrgstatic int mapFd = -1;
3988dd3e0eeSmrgstatic int numMaps = 0;
3998dd3e0eeSmrgstatic int numScrs = 0;
4008dd3e0eeSmrgstatic MapPtr *mapList = NULL;
4018dd3e0eeSmrgstatic ScrPtr *scrList = NULL;
4028dd3e0eeSmrg
4038dd3e0eeSmrgstatic MapPtr
4048dd3e0eeSmrgAddMap(void)
4058dd3e0eeSmrg{
4068dd3e0eeSmrg    MapPtr *old;
4078dd3e0eeSmrg
4088dd3e0eeSmrg    old = mapList;
4098dd3e0eeSmrg    mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1));
4108dd3e0eeSmrg    if (!mapList) {
4118dd3e0eeSmrg	mapList = old;
4128dd3e0eeSmrg	return NULL;
4138dd3e0eeSmrg    }
4148dd3e0eeSmrg    mapList[numMaps] = malloc(sizeof(MapRec));
4158dd3e0eeSmrg    if (!mapList[numMaps])
4168dd3e0eeSmrg	return NULL;
4178dd3e0eeSmrg    return mapList[numMaps++];
4188dd3e0eeSmrg}
4198dd3e0eeSmrg
4208dd3e0eeSmrgstatic ScrPtr
4218dd3e0eeSmrgAddScr(void)
4228dd3e0eeSmrg{
4238dd3e0eeSmrg    ScrPtr *old;
4248dd3e0eeSmrg
4258dd3e0eeSmrg    old = scrList;
4268dd3e0eeSmrg    scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1));
4278dd3e0eeSmrg    if (!scrList) {
4288dd3e0eeSmrg	scrList = old;
4298dd3e0eeSmrg	return NULL;
4308dd3e0eeSmrg    }
4318dd3e0eeSmrg    scrList[numScrs] = malloc(sizeof(ScrRec));
4328dd3e0eeSmrg    if (!scrList[numScrs])
4338dd3e0eeSmrg	return NULL;
4348dd3e0eeSmrg    return scrList[numScrs++];
4358dd3e0eeSmrg}
4368dd3e0eeSmrg
4378dd3e0eeSmrgstatic MapPtr
4388dd3e0eeSmrgFindMap(unsigned long address, unsigned long size)
4398dd3e0eeSmrg{
4408dd3e0eeSmrg    int i;
4418dd3e0eeSmrg
4428dd3e0eeSmrg    for (i = 0; i < numMaps; i++) {
4438dd3e0eeSmrg	if (mapList[i]->physaddr == address &&
4448dd3e0eeSmrg	    mapList[i]->size == size)
4458dd3e0eeSmrg	    return mapList[i];
4468dd3e0eeSmrg    }
4478dd3e0eeSmrg    return NULL;
4488dd3e0eeSmrg}
4498dd3e0eeSmrg
4508dd3e0eeSmrgstatic ScrPtr
4518dd3e0eeSmrgFindScr(Display *display, int screen)
4528dd3e0eeSmrg{
4538dd3e0eeSmrg    int i;
4548dd3e0eeSmrg
4558dd3e0eeSmrg    for (i = 0; i < numScrs; i++) {
4568dd3e0eeSmrg	if (scrList[i]->display == display &&
4578dd3e0eeSmrg	    scrList[i]->screen == screen)
4588dd3e0eeSmrg	    return scrList[i];
4598dd3e0eeSmrg    }
4608dd3e0eeSmrg    return NULL;
4618dd3e0eeSmrg}
4628dd3e0eeSmrg
4638dd3e0eeSmrgstatic void *
4648dd3e0eeSmrgMapPhysAddress(unsigned long address, unsigned long size)
4658dd3e0eeSmrg{
4668dd3e0eeSmrg    unsigned long offset, delta;
4678dd3e0eeSmrg    int pagesize = -1;
4688dd3e0eeSmrg    void *vaddr;
4698dd3e0eeSmrg    MapPtr mp;
4708dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
4718dd3e0eeSmrg    struct kd_memloc mloc;
4728dd3e0eeSmrg#elif defined(__UNIXOS2__)
4738dd3e0eeSmrg    APIRET rc;
4748dd3e0eeSmrg    ULONG action;
4758dd3e0eeSmrg    HFILE hfd;
4768dd3e0eeSmrg#endif
4778dd3e0eeSmrg
4788dd3e0eeSmrg    if ((mp = FindMap(address, size))) {
4798dd3e0eeSmrg	mp->refcount++;
4808dd3e0eeSmrg	return (void *)((unsigned long)mp->vaddr + mp->delta);
4818dd3e0eeSmrg    }
4828dd3e0eeSmrg
4838dd3e0eeSmrg#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE)
4848dd3e0eeSmrg    pagesize = sysconf(_SC_PAGESIZE);
4858dd3e0eeSmrg#endif
4868dd3e0eeSmrg#ifdef _SC_PAGE_SIZE
4878dd3e0eeSmrg    if (pagesize == -1)
4888dd3e0eeSmrg	pagesize = sysconf(_SC_PAGE_SIZE);
4898dd3e0eeSmrg#endif
4908dd3e0eeSmrg#ifdef HAS_GETPAGESIZE
4918dd3e0eeSmrg    if (pagesize == -1)
4928dd3e0eeSmrg	pagesize = getpagesize();
4938dd3e0eeSmrg#endif
4948dd3e0eeSmrg#ifdef PAGE_SIZE
4958dd3e0eeSmrg    if (pagesize == -1)
4968dd3e0eeSmrg	pagesize = PAGE_SIZE;
4978dd3e0eeSmrg#endif
4988dd3e0eeSmrg    if (pagesize == -1)
4998dd3e0eeSmrg	pagesize = 4096;
5008dd3e0eeSmrg
5018dd3e0eeSmrg   delta = address % pagesize;
5028dd3e0eeSmrg   offset = address - delta;
5038dd3e0eeSmrg
5048dd3e0eeSmrg#if defined(ISC) && defined(HAS_SVR3_MMAP)
5058dd3e0eeSmrg    if (mapFd < 0) {
5068dd3e0eeSmrg	if ((mapFd = open("/dev/mmap", O_RDWR)) < 0)
5078dd3e0eeSmrg	    return NULL;
5088dd3e0eeSmrg    }
5098dd3e0eeSmrg    mloc.vaddr = (char *)0;
5108dd3e0eeSmrg    mloc.physaddr = (char *)offset;
5118dd3e0eeSmrg    mloc.length = size + delta;
5128dd3e0eeSmrg    mloc.ioflg=1;
5138dd3e0eeSmrg
5148dd3e0eeSmrg    if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1)
5158dd3e0eeSmrg	return NULL;
5168dd3e0eeSmrg#elif defined (__UNIXOS2__)
5178dd3e0eeSmrg    /*
5188dd3e0eeSmrg     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
5198dd3e0eeSmrg     * Consecutive calling of this routine will make PMAP$ driver run out
5208dd3e0eeSmrg     * of memory handles. Some umap/close mechanism should be provided
5218dd3e0eeSmrg     */
5228dd3e0eeSmrg
5238dd3e0eeSmrg    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
5248dd3e0eeSmrg		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
5258dd3e0eeSmrg    if (rc != 0)
5268dd3e0eeSmrg	return NULL;
5278dd3e0eeSmrg    {
5288dd3e0eeSmrg	struct map_ioctl {
5298dd3e0eeSmrg		union {
5308dd3e0eeSmrg			ULONG phys;
5318dd3e0eeSmrg			void* user;
5328dd3e0eeSmrg		} a;
5338dd3e0eeSmrg		ULONG size;
5348dd3e0eeSmrg	} pmap,dmap;
5358dd3e0eeSmrg	ULONG plen,dlen;
5368dd3e0eeSmrg#define XFREE86_PMAP	0x76
5378dd3e0eeSmrg#define PMAP_MAP	0x44
5388dd3e0eeSmrg
5398dd3e0eeSmrg	pmap.a.phys = offset;
5408dd3e0eeSmrg	pmap.size = size + delta;
5418dd3e0eeSmrg	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
5428dd3e0eeSmrg			 (PULONG)&pmap, sizeof(pmap), &plen,
5438dd3e0eeSmrg			 (PULONG)&dmap, sizeof(dmap), &dlen);
5448dd3e0eeSmrg	if (rc == 0) {
5458dd3e0eeSmrg		vaddr = dmap.a.user;
5468dd3e0eeSmrg	}
5478dd3e0eeSmrg   }
5488dd3e0eeSmrg   if (rc != 0)
5498dd3e0eeSmrg	return NULL;
5508dd3e0eeSmrg#elif defined(Lynx) && defined(NO_MMAP)
551d5a688bcSmrg    vaddr = (void *)smem_create("XF86DGA", (char *)offset,
5528dd3e0eeSmrg				size + delta, SM_READ|SM_WRITE);
5538dd3e0eeSmrg#else
5548dd3e0eeSmrg#ifndef MAP_FILE
5558dd3e0eeSmrg#define MAP_FILE 0
5568dd3e0eeSmrg#endif
5578dd3e0eeSmrg    if (mapFd < 0) {
5588dd3e0eeSmrg	if ((mapFd = open(DEV_MEM, O_RDWR)) < 0)
5598dd3e0eeSmrg	    return NULL;
5608dd3e0eeSmrg    }
5618dd3e0eeSmrg    vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE,
5628dd3e0eeSmrg                        MAP_FILE | MAP_SHARED, mapFd, (off_t)offset);
5638dd3e0eeSmrg    if (vaddr == (void *)-1)
5648dd3e0eeSmrg	return NULL;
5658dd3e0eeSmrg#endif
5668dd3e0eeSmrg
5678dd3e0eeSmrg    if (!vaddr) {
5688dd3e0eeSmrg	if (!(mp = AddMap()))
5698dd3e0eeSmrg	    return NULL;
5708dd3e0eeSmrg	mp->physaddr = address;
5718dd3e0eeSmrg	mp->size = size;
5728dd3e0eeSmrg	mp->delta = delta;
5738dd3e0eeSmrg	mp->vaddr = vaddr;
5748dd3e0eeSmrg	mp->refcount = 1;
5758dd3e0eeSmrg    }
5768dd3e0eeSmrg    return (void *)((unsigned long)vaddr + delta);
5778dd3e0eeSmrg}
5788dd3e0eeSmrg
5798dd3e0eeSmrg/*
5808dd3e0eeSmrg * Still need to find a clean way of detecting the death of a DGA app
5818dd3e0eeSmrg * and returning things to normal - Jon
5828dd3e0eeSmrg * This is here to help debugging without rebooting... Also C-A-BS
5838dd3e0eeSmrg * should restore text mode.
5848dd3e0eeSmrg */
5858dd3e0eeSmrg
5868dd3e0eeSmrgint
5878dd3e0eeSmrgXF86DGAForkApp(int screen)
5888dd3e0eeSmrg{
5898dd3e0eeSmrg    pid_t pid;
5908dd3e0eeSmrg    int status;
5918dd3e0eeSmrg    int i;
5928dd3e0eeSmrg
5938dd3e0eeSmrg     /* fork the app, parent hangs around to clean up */
5948dd3e0eeSmrg    if ((pid = fork()) > 0) {
5958dd3e0eeSmrg	ScrPtr sp;
5968dd3e0eeSmrg
5978dd3e0eeSmrg	waitpid(pid, &status, 0);
5988dd3e0eeSmrg	for (i = 0; i < numScrs; i++) {
5998dd3e0eeSmrg	    sp = scrList[i];
6008dd3e0eeSmrg	    XF86DGADirectVideoLL(sp->display, sp->screen, 0);
6018dd3e0eeSmrg	    XSync(sp->display, False);
6028dd3e0eeSmrg	}
6038dd3e0eeSmrg        if (WIFEXITED(status))
6048dd3e0eeSmrg	    _exit(0);
6058dd3e0eeSmrg	else
6068dd3e0eeSmrg	    _exit(-1);
6078dd3e0eeSmrg    }
6088dd3e0eeSmrg    return pid;
6098dd3e0eeSmrg}
6108dd3e0eeSmrg
6118dd3e0eeSmrg
6128dd3e0eeSmrgBool
6138dd3e0eeSmrgXF86DGADirectVideo(
6148dd3e0eeSmrg    Display *dis,
6158dd3e0eeSmrg    int screen,
6168dd3e0eeSmrg    int enable
6178dd3e0eeSmrg){
6188dd3e0eeSmrg    ScrPtr sp;
6198dd3e0eeSmrg    MapPtr mp = NULL;
6208dd3e0eeSmrg
6218dd3e0eeSmrg    if ((sp = FindScr(dis, screen)))
6228dd3e0eeSmrg	mp = sp->map;
6238dd3e0eeSmrg
6248dd3e0eeSmrg    if (enable & XF86DGADirectGraphics) {
6258dd3e0eeSmrg#if !defined(ISC) && !defined(HAS_SVR3_MMAP) \
6268dd3e0eeSmrg	&& !(defined(Lynx) && defined(NO_MMAP)) \
6278dd3e0eeSmrg	&& !defined(__UNIXOS2__)
6288dd3e0eeSmrg	if (mp && mp->vaddr)
6298dd3e0eeSmrg	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);
6308dd3e0eeSmrg#endif
6318dd3e0eeSmrg    } else {
6328dd3e0eeSmrg#if !defined(ISC) && !defined(HAS_SVR3_MMAP) \
6338dd3e0eeSmrg	&& !(defined(Lynx) && defined(NO_MMAP)) \
6348dd3e0eeSmrg	&& !defined(__UNIXOS2__)
6358dd3e0eeSmrg	if (mp && mp->vaddr)
6368dd3e0eeSmrg	    mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);
6378dd3e0eeSmrg#elif defined(Lynx) && defined(NO_MMAP)
6388dd3e0eeSmrg	/* XXX this doesn't allow enable after disable */
6398dd3e0eeSmrg	smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH);
6408dd3e0eeSmrg	smem_remove("XF86DGA");
6418dd3e0eeSmrg#endif
6428dd3e0eeSmrg    }
6438dd3e0eeSmrg
6448dd3e0eeSmrg    XF86DGADirectVideoLL(dis, screen, enable);
6458dd3e0eeSmrg    return 1;
6468dd3e0eeSmrg}
6478dd3e0eeSmrg
6488dd3e0eeSmrg
6498dd3e0eeSmrgstatic void
650da01b833Schristos#ifdef __NetBSD__
651da01b833Schristos__attribute__ ((__destructor__))
652da01b833Schristos#endif
6538dd3e0eeSmrgXF86cleanup(int sig)
6548dd3e0eeSmrg{
6558dd3e0eeSmrg    ScrPtr sp;
6568dd3e0eeSmrg    int i;
6578dd3e0eeSmrg    static char beenhere = 0;
6588dd3e0eeSmrg
6598dd3e0eeSmrg    if (beenhere)
6608dd3e0eeSmrg	_exit(3);
6618dd3e0eeSmrg    beenhere = 1;
6628dd3e0eeSmrg
6638dd3e0eeSmrg    for (i = 0; i < numScrs; i++) {
6648dd3e0eeSmrg	sp = scrList[i];
6658dd3e0eeSmrg	XF86DGADirectVideo(sp->display, sp->screen, 0);
6668dd3e0eeSmrg	XSync(sp->display, False);
6678dd3e0eeSmrg    }
6688dd3e0eeSmrg    _exit(3);
6698dd3e0eeSmrg}
6708dd3e0eeSmrg
6718dd3e0eeSmrgBool
6728dd3e0eeSmrgXF86DGAGetVideo(
6738dd3e0eeSmrg    Display *dis,
6748dd3e0eeSmrg    int screen,
6758dd3e0eeSmrg    char **addr,
676d5a688bcSmrg    int *width,
677d5a688bcSmrg    int *bank,
6788dd3e0eeSmrg    int *ram
6798dd3e0eeSmrg){
6808dd3e0eeSmrg    unsigned int offset;
6818dd3e0eeSmrg    static int beenHere = 0;
6828dd3e0eeSmrg    ScrPtr sp;
6838dd3e0eeSmrg    MapPtr mp;
6848dd3e0eeSmrg
6858dd3e0eeSmrg    if (!(sp = FindScr(dis, screen))) {
6868dd3e0eeSmrg	if (!(sp = AddScr())) {
6878dd3e0eeSmrg	    fprintf(stderr, "XF86DGAGetVideo: malloc failure\n");
6888dd3e0eeSmrg	    exit(-2);
6898dd3e0eeSmrg	}
6908dd3e0eeSmrg	sp->display = dis;
6918dd3e0eeSmrg	sp->screen = screen;
6928dd3e0eeSmrg	sp->map = NULL;
6938dd3e0eeSmrg    }
6948dd3e0eeSmrg
6958dd3e0eeSmrg    XF86DGAGetVideoLL(dis, screen , &offset, width, bank, ram);
6968dd3e0eeSmrg
6978dd3e0eeSmrg    *addr = MapPhysAddress(offset, *bank);
6988dd3e0eeSmrg    if (*addr == NULL) {
6998dd3e0eeSmrg	fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n",
7008dd3e0eeSmrg		strerror(errno));
7018dd3e0eeSmrg	exit(-2);
7028dd3e0eeSmrg    }
7038dd3e0eeSmrg
7048dd3e0eeSmrg    if ((mp = FindMap(offset, *bank)))
7058dd3e0eeSmrg	sp->map = mp;
7068dd3e0eeSmrg
7078dd3e0eeSmrg    if (!beenHere) {
7088dd3e0eeSmrg	beenHere = 1;
709da01b833Schristos#ifndef __NetBSD__
7108dd3e0eeSmrg	atexit((void(*)(void))XF86cleanup);
711da01b833Schristos#endif
7128dd3e0eeSmrg	/* one shot XF86cleanup attempts */
7138dd3e0eeSmrg	signal(SIGSEGV, XF86cleanup);
7148dd3e0eeSmrg#ifdef SIGBUS
7158dd3e0eeSmrg	signal(SIGBUS, XF86cleanup);
7168dd3e0eeSmrg#endif
7178dd3e0eeSmrg	signal(SIGHUP, XF86cleanup);
718d5a688bcSmrg	signal(SIGFPE, XF86cleanup);
7198dd3e0eeSmrg    }
7208dd3e0eeSmrg
7218dd3e0eeSmrg    return 1;
7228dd3e0eeSmrg}
7238dd3e0eeSmrg
724