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