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