📄 xf86dga.c
字号:
#else# if !defined(Lynx)# if !defined(__EMX__)# include <sys/mman.h># endif# else# include <sys/types.h># include <errno.h># include <smem.h># endif#endif#include <sys/wait.h>#include <signal.h>#include <unistd.h>#if defined(SVR4) && !defined(sun) && !defined(SCO325)#define DEV_MEM "/dev/pmem"#elif defined(SVR4) && defined(sun)#define DEV_MEM "/dev/xsvc"#else#define DEV_MEM "/dev/mem"#endiftypedef struct { unsigned long physaddr; /* actual requested physical address */ unsigned long size; /* actual requested map size */ unsigned long delta; /* delta to account for page alignment */ void * vaddr; /* mapped address, without the delta */ int refcount; /* reference count */} MapRec, *MapPtr;typedef struct { Display * display; int screen; MapPtr map;} ScrRec, *ScrPtr;static int mapFd = -1;static int numMaps = 0;static int numScrs = 0;static MapPtr *mapList = NULL;static ScrPtr *scrList = NULL;static MapPtrAddMap(void){ MapPtr *old; old = mapList; mapList = realloc(mapList, sizeof(MapPtr) * (numMaps + 1)); if (!mapList) { mapList = old; return NULL; } mapList[numMaps] = malloc(sizeof(MapRec)); if (!mapList[numMaps]) return NULL; return mapList[numMaps++];}static ScrPtrAddScr(void){ ScrPtr *old; old = scrList; scrList = realloc(scrList, sizeof(ScrPtr) * (numScrs + 1)); if (!scrList) { scrList = old; return NULL; } scrList[numScrs] = malloc(sizeof(ScrRec)); if (!scrList[numScrs]) return NULL; return scrList[numScrs++];}static MapPtrFindMap(unsigned long address, unsigned long size){ int i; for (i = 0; i < numMaps; i++) { if (mapList[i]->physaddr == address && mapList[i]->size == size) return mapList[i]; } return NULL;}static ScrPtrFindScr(Display *display, int screen){ int i; for (i = 0; i < numScrs; i++) { if (scrList[i]->display == display && scrList[i]->screen == screen) return scrList[i]; } return NULL;}static void *MapPhysAddress(unsigned long address, unsigned long size){ unsigned long offset, delta; int pagesize = -1; void *vaddr; MapPtr mp;#if defined(ISC) && defined(HAS_SVR3_MMAP) struct kd_memloc mloc;#elif defined(__EMX__) APIRET rc; ULONG action; HFILE hfd;#endif if ((mp = FindMap(address, size))) { mp->refcount++; return (void *)((unsigned long)mp->vaddr + mp->delta); }#if defined(_SC_PAGESIZE) && defined(HAS_SC_PAGESIZE) pagesize = sysconf(_SC_PAGESIZE);#endif#ifdef _SC_PAGE_SIZE if (pagesize == -1) pagesize = sysconf(_SC_PAGE_SIZE);#endif#ifdef HAS_GETPAGESIZE if (pagesize == -1) pagesize = getpagesize();#endif#ifdef PAGE_SIZE if (pagesize == -1) pagesize = PAGE_SIZE;#endif if (pagesize == -1) pagesize = 4096; delta = address % pagesize; offset = address - delta;#if defined(ISC) && defined(HAS_SVR3_MMAP) if (mapFd < 0) { if ((mapFd = open("/dev/mmap", O_RDWR)) < 0) return NULL; } mloc.vaddr = (char *)0; mloc.physaddr = (char *)offset; mloc.length = size + delta; mloc.ioflg=1; if ((vaddr = (void *)ioctl(mapFd, MAP, &mloc)) == (void *)-1) return NULL;#elif defined (__EMX__) /* * Dragon warning here! /dev/pmap$ is never closed, except on progam exit. * Consecutive calling of this routine will make PMAP$ driver run out * of memory handles. Some umap/close mechanism should be provided */ rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL); if (rc != 0) return NULL; { struct map_ioctl { union { ULONG phys; void* user; } a; ULONG size; } pmap,dmap; ULONG plen,dlen;#define XFREE86_PMAP 0x76#define PMAP_MAP 0x44 pmap.a.phys = offset; pmap.size = size + delta; rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP, (PULONG)&pmap, sizeof(pmap), &plen, (PULONG)&dmap, sizeof(dmap), &dlen); if (rc == 0) { vaddr = dmap.a.user; } } if (rc != 0) return NULL;#elif defined (Lynx) vaddr = (void *)smem_create("XF86DGA", (char *)offset, size + delta, SM_READ|SM_WRITE);#else#ifndef MAP_FILE#define MAP_FILE 0#endif if (mapFd < 0) { if ((mapFd = open(DEV_MEM, O_RDWR)) < 0) return NULL; } vaddr = (void *)mmap(NULL, size + delta, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, mapFd, (off_t)offset); if (vaddr == (void *)-1) return NULL;#endif if (!vaddr) { if (!(mp = AddMap())) return NULL; mp->physaddr = address; mp->size = size; mp->delta = delta; mp->vaddr = vaddr; mp->refcount = 1; } return (void *)((unsigned long)vaddr + delta);}/* * Still need to find a clean way of detecting the death of a DGA app * and returning things to normal - Jon * This is here to help debugging without rebooting... Also C-A-BS * should restore text mode. */intSDL_NAME(XF86DGAForkApp)(int screen){ pid_t pid; int status; int i; /* fork the app, parent hangs around to clean up */ if ((pid = fork()) > 0) { ScrPtr sp; waitpid(pid, &status, 0); for (i = 0; i < numScrs; i++) { sp = scrList[i]; SDL_NAME(XF86DGADirectVideoLL)(sp->display, sp->screen, 0); XSync(sp->display, False); } if (WIFEXITED(status)) _exit(0); else _exit(-1); } return pid;}BoolSDL_NAME(XF86DGADirectVideo)( Display *dis, int screen, int enable){ ScrPtr sp; MapPtr mp = NULL; if ((sp = FindScr(dis, screen))) mp = sp->map; if (enable & XF86DGADirectGraphics) {#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ && !defined(__EMX__) if (mp && mp->vaddr) mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ | PROT_WRITE);#endif } else {#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \ && !defined(__EMX__) if (mp && mp->vaddr) mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ);#elif defined(Lynx) /* XXX this doesn't allow enable after disable */ smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH); smem_remove("XF86DGA");#endif } SDL_NAME(XF86DGADirectVideoLL)(dis, screen, enable); return 1;}static voidXF86cleanup(int sig){ ScrPtr sp; int i; static char beenhere = 0; if (beenhere) _exit(3); beenhere = 1; for (i = 0; i < numScrs; i++) { sp = scrList[i]; SDL_NAME(XF86DGADirectVideo)(sp->display, sp->screen, 0); XSync(sp->display, False); } _exit(3);}BoolSDL_NAME(XF86DGAGetVideo)( Display *dis, int screen, char **addr, int *width, int *bank, int *ram){ /*unsigned long*/ int offset; static int beenHere = 0; ScrPtr sp; MapPtr mp; if (!(sp = FindScr(dis, screen))) { if (!(sp = AddScr())) { fprintf(stderr, "XF86DGAGetVideo: malloc failure\n"); exit(-2); } sp->display = dis; sp->screen = screen; sp->map = NULL; } SDL_NAME(XF86DGAGetVideoLL)(dis, screen , &offset, width, bank, ram); *addr = MapPhysAddress(offset, *bank); if (*addr == NULL) { fprintf(stderr, "XF86DGAGetVideo: failed to map video memory (%s)\n", strerror(errno)); exit(-2); } if ((mp = FindMap(offset, *bank))) sp->map = mp; if (!beenHere) { beenHere = 1; atexit((void(*)(void))XF86cleanup); /* one shot XF86cleanup attempts */ signal(SIGSEGV, XF86cleanup);#ifdef SIGBUS signal(SIGBUS, XF86cleanup);#endif signal(SIGHUP, XF86cleanup); signal(SIGFPE, XF86cleanup); } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -