diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:49 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:49 +0000 |
commit | ca572cb2f331b374c246b4435f5aeb036392e16f (patch) | |
tree | 674ffa9b790828cb9951585a75881df6ea6dfbe3 |
Initial revisionXORG-STABLE
-rw-r--r-- | src/XF86DGA.c | 718 | ||||
-rw-r--r-- | src/XF86DGA2.c | 962 |
2 files changed, 1680 insertions, 0 deletions
diff --git a/src/XF86DGA.c b/src/XF86DGA.c new file mode 100644 index 0000000..ceff6b3 --- /dev/null +++ b/src/XF86DGA.c @@ -0,0 +1,718 @@ +/* $XFree86: xc/lib/Xxf86dga/XF86DGA.c,v 3.22 2002/12/14 04:41:12 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995,1996 The XFree86 Project, Inc + +*/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef __UNIXOS2__ /* needed here to override certain constants in X headers */ +#define INCL_DOS +#define INCL_DOSIOCTL +#include <os2.h> +#endif + +#if defined(linux) +#define HAS_MMAP_ANON +#include <sys/types.h> +#include <sys/mman.h> +#include <asm/page.h> /* PAGE_SIZE */ +#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */ +#define HAS_GETPAGESIZE +#endif /* linux */ + +#if defined(CSRG_BASED) +#define HAS_MMAP_ANON +#define HAS_GETPAGESIZE +#include <sys/types.h> +#include <sys/mman.h> +#endif /* CSRG_BASED */ + +#if defined(DGUX) +#define HAS_GETPAGESIZE +#define MMAP_DEV_ZERO +#include <sys/types.h> +#include <sys/mman.h> +#include <unistd.h> +#endif /* DGUX */ + +#if defined(SVR4) && !defined(DGUX) +#define MMAP_DEV_ZERO +#include <sys/types.h> +#include <sys/mman.h> +#include <unistd.h> +#endif /* SVR4 && !DGUX */ + +#if defined(sun) && !defined(SVR4) /* SunOS */ +#define MMAP_DEV_ZERO /* doesn't SunOS have MAP_ANON ?? */ +#define HAS_GETPAGESIZE +#include <sys/types.h> +#include <sys/mman.h> +#endif /* sun && !SVR4 */ + +#ifdef XNO_SYSCONF +#undef _SC_PAGESIZE +#endif + + +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/xf86dga.h> +#include <X11/extensions/xf86dgastr.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> + +extern XExtDisplayInfo* xdga_find_display(Display*); +extern char *xdga_extension_name; + +#define XF86DGACheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xdga_extension_name, val) + +/***************************************************************************** + * * + * public XFree86-DGA Extension routines * + * * + *****************************************************************************/ + +Bool XF86DGAQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + return XDGAQueryExtension(dpy, event_basep, error_basep); +} + +Bool XF86DGAQueryVersion( + Display* dpy, + int* majorVersion, + int* minorVersion +){ + return XDGAQueryVersion(dpy, majorVersion, minorVersion); +} + +Bool XF86DGAGetVideoLL( + Display* dpy, + int screen, + int *offset, + int *width, + int *bank_size, + int *ram_size +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAGetVideoLLReply rep; + xXF86DGAGetVideoLLReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetVideoLL, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetVideoLL; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *offset = /*(char *)*/rep.offset; + *width = rep.width; + *bank_size = rep.bank_size; + *ram_size = rep.ram_size; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool XF86DGADirectVideoLL( + Display* dpy, + int screen, + int enable +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGADirectVideoReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGADirectVideo, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGADirectVideo; + req->screen = screen; + req->enable = enable; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool XF86DGAGetViewPortSize( + Display* dpy, + int screen, + int *width, + int *height +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAGetViewPortSizeReply rep; + xXF86DGAGetViewPortSizeReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetViewPortSize, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetViewPortSize; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *width = rep.width; + *height = rep.height; + + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool XF86DGASetViewPort( + Display* dpy, + int screen, + int x, + int y +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGASetViewPortReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGASetViewPort, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGASetViewPort; + req->screen = screen; + req->x = x; + req->y = y; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + + +Bool XF86DGAGetVidPage( + Display* dpy, + int screen, + int *vpage +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAGetVidPageReply rep; + xXF86DGAGetVidPageReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAGetVidPage, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAGetVidPage; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *vpage = rep.vpage; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + + +Bool XF86DGASetVidPage( + Display* dpy, + int screen, + int vpage +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGASetVidPageReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGASetVidPage, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGASetVidPage; + req->screen = screen; + req->vpage = vpage; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool XF86DGAInstallColormap( + Display* dpy, + int screen, + Colormap cmap +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAInstallColormapReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAInstallColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAInstallColormap; + req->screen = screen; + req->id = cmap; + UnlockDisplay(dpy); + SyncHandle(); + XSync(dpy,False); + return True; +} + +Bool XF86DGAQueryDirectVideo( + Display *dpy, + int screen, + int *flags +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAQueryDirectVideoReply rep; + xXF86DGAQueryDirectVideoReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAQueryDirectVideo, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAQueryDirectVideo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *flags = rep.flags; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XF86DGAViewPortChanged( + Display *dpy, + int screen, + int n +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXF86DGAViewPortChangedReply rep; + xXF86DGAViewPortChangedReq *req; + + XF86DGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XF86DGAViewPortChanged, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XF86DGAViewPortChanged; + req->screen = screen; + req->n = n; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.result; +} + + + +/* Helper functions */ + +#include <X11/Xmd.h> +#include <X11/extensions/xf86dga.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#if defined(ISC) +# define HAS_SVR3_MMAP +# include <sys/types.h> +# include <errno.h> + +# include <sys/at_ansi.h> +# include <sys/kd.h> + +# include <sys/sysmacros.h> +# include <sys/immu.h> +# include <sys/region.h> + +# include <sys/mmap.h> +#else +# if defined(Lynx) && defined(NO_MMAP) +# include <sys/types.h> +# include <errno.h> +# include <smem.h> +# else +# if !defined(__UNIXOS2__) +# include <sys/mman.h> +# endif +# 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" +#endif + +typedef 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 MapPtr +AddMap(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 ScrPtr +AddScr(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 MapPtr +FindMap(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 ScrPtr +FindScr(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(__UNIXOS2__) + 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 (__UNIXOS2__) + /* + * 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) && defined(NO_MMAP) + 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. + */ + +int +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]; + XF86DGADirectVideoLL(sp->display, sp->screen, 0); + XSync(sp->display, False); + } + if (WIFEXITED(status)) + _exit(0); + else + _exit(-1); + } + return pid; +} + + +Bool +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(NO_MMAP)) \ + && !defined(__UNIXOS2__) + 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(NO_MMAP)) \ + && !defined(__UNIXOS2__) + if (mp && mp->vaddr) + mprotect(mp->vaddr, mp->size + mp->delta, PROT_READ); +#elif defined(Lynx) && defined(NO_MMAP) + /* XXX this doesn't allow enable after disable */ + smem_create(NULL, mp->vaddr, mp->size + mp->delta, SM_DETACH); + smem_remove("XF86DGA"); +#endif + } + + XF86DGADirectVideoLL(dis, screen, enable); + return 1; +} + + +static void +XF86cleanup(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]; + XF86DGADirectVideo(sp->display, sp->screen, 0); + XSync(sp->display, False); + } + _exit(3); +} + +Bool +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; + } + + 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; +} + diff --git a/src/XF86DGA2.c b/src/XF86DGA2.c new file mode 100644 index 0000000..c3bd960 --- /dev/null +++ b/src/XF86DGA2.c @@ -0,0 +1,962 @@ +/* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.21 2002/12/14 04:41:12 dawes Exp $ */ +/* + +Copyright (c) 1995 Jon Tombs +Copyright (c) 1995,1996 The XFree86 Project, Inc + +*/ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#ifdef __UNIXOS2__ /* needed here to override certain constants in X headers */ +#define INCL_DOS +#define INCL_DOSIOCTL +#include <os2.h> +#endif + +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/xf86dga.h> +#include <X11/extensions/xf86dgastr.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include <stdio.h> + + +/* If you change this, change the Bases[] array below as well */ +#define MAX_HEADS 16 + +char *xdga_extension_name = XF86DGANAME; + +static XExtensionInfo _xdga_info_data; +static XExtensionInfo *xdga_info = &_xdga_info_data; + + +Bool XDGAMapFramebuffer(int, char *, unsigned char*, CARD32, CARD32, CARD32); +void XDGAUnmapFramebuffer(int); +unsigned char* XDGAGetMappedMemory(int); + +#define XDGACheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, xdga_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int xdga_close_display(Display *dpy, XExtCodes *codes); +static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev); +static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev); + +static XExtensionHooks xdga_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + xdga_close_display, /* close_display */ + xdga_wire_to_event, /* wire_to_event */ + xdga_event_to_wire, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info) + + +XEXT_GENERATE_FIND_DISPLAY (xdga_find_display, xdga_info, + "XFree86-DGA", + &xdga_extension_hooks, + 0, NULL) + + +static Status +xdga_event_to_wire( + Display *dpy, + XEvent *event, + xEvent *wire_ev +){ + return True; +} + +static Bool +xdga_wire_to_event( + Display *dpy, + XEvent *event, + xEvent *wire_ev +){ + dgaEvent *wire = (dgaEvent *) wire_ev; + XDGAButtonEvent *bevent; + XDGAKeyEvent *kevent; + XDGAMotionEvent *mevent; + XExtDisplayInfo *info = xdga_find_display (dpy); + + XDGACheckExtension (dpy, info, False); + + switch((wire->u.u.type & 0x7f) - info->codes->first_event) { + case MotionNotify: + mevent = (XDGAMotionEvent*)event; + mevent->type = wire->u.u.type & 0x7F; + mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + mevent->display = dpy; + mevent->screen = wire->u.event.screen; + mevent->time = wire->u.event.time; + mevent->state = wire->u.event.state; + mevent->dx = wire->u.event.dx; + mevent->dy = wire->u.event.dy; + return True; + case ButtonPress: + case ButtonRelease: + bevent = (XDGAButtonEvent*)event; + bevent->type = wire->u.u.type & 0x7F; + bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + bevent->display = dpy; + bevent->screen = wire->u.event.screen; + bevent->time = wire->u.event.time; + bevent->state = wire->u.event.state; + bevent->button = wire->u.u.detail; + return True; + case KeyPress: + case KeyRelease: + kevent = (XDGAKeyEvent*)event; + kevent->type = wire->u.u.type & 0x7F; + kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire); + kevent->display = dpy; + kevent->screen = wire->u.event.screen; + kevent->time = wire->u.event.time; + kevent->state = wire->u.event.state; + kevent->keycode = wire->u.u.detail; + return True; + } + + return False; +} + + +Bool XDGAQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Bool XDGAQueryVersion( + Display *dpy, + int *majorVersion, + int *minorVersion +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAQueryVersionReply rep; + xXDGAQueryVersionReq *req; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGAQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + if (*majorVersion >= 2) + { + int i, j; + + for (i = 0, j = info->codes->first_event; + i < XF86DGANumberEvents; + i++, j++) + { + XESetWireToEvent (dpy, j, xdga_wire_to_event); + XESetEventToWire (dpy, j, xdga_event_to_wire); + } + XDGASetClientVersion(dpy); + } + return True; +} + +Bool XDGASetClientVersion( + Display *dpy +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGASetClientVersionReq *req; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGASetClientVersion, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASetClientVersion; + req->major = XDGA_MAJOR_VERSION; + req->minor = XDGA_MINOR_VERSION; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XDGAOpenFramebuffer( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAOpenFramebufferReply rep; + xXDGAOpenFramebufferReq *req; + char *deviceName = NULL; + Bool ret; + + XDGACheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(XDGAOpenFramebuffer, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAOpenFramebuffer; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + if(rep.length) { + deviceName = Xmalloc(rep.length << 2); + _XRead(dpy, deviceName, rep.length << 2); + } + + ret = XDGAMapFramebuffer(screen, deviceName, + (unsigned char*)(long)rep.mem1, + rep.size, rep.offset, rep.extra); + + if(deviceName) + Xfree(deviceName); + + UnlockDisplay(dpy); + SyncHandle(); + return ret; +} + +void XDGACloseFramebuffer( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGACloseFramebufferReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + XDGAUnmapFramebuffer(screen); + + LockDisplay(dpy); + GetReq(XDGACloseFramebuffer, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACloseFramebuffer; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); +} + + + +XDGAMode* XDGAQueryModes( + Display *dpy, + int screen, + int *num +){ + XExtDisplayInfo *dinfo = xdga_find_display (dpy); + xXDGAQueryModesReply rep; + xXDGAQueryModesReq *req; + XDGAMode *modes = NULL; + + *num = 0; + + XDGACheckExtension (dpy, dinfo, NULL); + + LockDisplay(dpy); + GetReq(XDGAQueryModes, req); + req->reqType = dinfo->codes->major_opcode; + req->dgaReqType = X_XDGAQueryModes; + req->screen = screen; + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + if(rep.length) { + xXDGAModeInfo info; + int i, size; + char *offset; + + size = rep.length << 2; + size -= rep.number * sz_xXDGAModeInfo; /* find text size */ + modes = (XDGAMode*)Xmalloc((rep.number * sizeof(XDGAMode)) + size); + offset = (char*)(&modes[rep.number]); /* start of text */ + + + if(modes) { + for(i = 0; i < rep.number; i++) { + _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); + + modes[i].num = info.num; + modes[i].verticalRefresh = + (float)info.vsync_num / (float)info.vsync_den; + modes[i].flags = info.flags; + modes[i].imageWidth = info.image_width; + modes[i].imageHeight = info.image_height; + modes[i].pixmapWidth = info.pixmap_width; + modes[i].pixmapHeight = info.pixmap_height; + modes[i].bytesPerScanline = info.bytes_per_scanline; + modes[i].byteOrder = info.byte_order; + modes[i].depth = info.depth; + modes[i].bitsPerPixel = info.bpp; + modes[i].redMask = info.red_mask; + modes[i].greenMask = info.green_mask; + modes[i].blueMask = info.blue_mask; + modes[i].visualClass = info.visual_class; + modes[i].viewportWidth = info.viewport_width; + modes[i].viewportHeight = info.viewport_height; + modes[i].xViewportStep = info.viewport_xstep; + modes[i].yViewportStep = info.viewport_ystep; + modes[i].maxViewportX = info.viewport_xmax; + modes[i].maxViewportY = info.viewport_ymax; + modes[i].viewportFlags = info.viewport_flags; + modes[i].reserved1 = info.reserved1; + modes[i].reserved2 = info.reserved2; + + _XRead(dpy, offset, info.name_size); + modes[i].name = offset; + offset += info.name_size; + } + *num = rep.number; + } else + _XEatData(dpy, rep.length << 2); + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + return modes; +} + + +XDGADevice * +XDGASetMode( + Display *dpy, + int screen, + int mode +){ + XExtDisplayInfo *dinfo = xdga_find_display (dpy); + xXDGASetModeReply rep; + xXDGASetModeReq *req; + XDGADevice *dev = NULL; + Pixmap pid; + + XDGACheckExtension (dpy, dinfo, NULL); + + LockDisplay(dpy); + GetReq(XDGASetMode, req); + req->reqType = dinfo->codes->major_opcode; + req->dgaReqType = X_XDGASetMode; + req->screen = screen; + req->mode = mode; + req->pid = pid = XAllocID(dpy); + + if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + if(rep.length) { + xXDGAModeInfo info; + int size; + + size = rep.length << 2; + size -= sz_xXDGAModeInfo; /* get text size */ + + dev = (XDGADevice*)Xmalloc(sizeof(XDGADevice) + size); + + if(dev) { + _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo); + + dev->mode.num = info.num; + dev->mode.verticalRefresh = + (float)info.vsync_num / (float)info.vsync_den; + dev->mode.flags = info.flags; + dev->mode.imageWidth = info.image_width; + dev->mode.imageHeight = info.image_height; + dev->mode.pixmapWidth = info.pixmap_width; + dev->mode.pixmapHeight = info.pixmap_height; + dev->mode.bytesPerScanline = info.bytes_per_scanline; + dev->mode.byteOrder = info.byte_order; + dev->mode.depth = info.depth; + dev->mode.bitsPerPixel = info.bpp; + dev->mode.redMask = info.red_mask; + dev->mode.greenMask = info.green_mask; + dev->mode.blueMask = info.blue_mask; + dev->mode.visualClass = info.visual_class; + dev->mode.viewportWidth = info.viewport_width; + dev->mode.viewportHeight = info.viewport_height; + dev->mode.xViewportStep = info.viewport_xstep; + dev->mode.yViewportStep = info.viewport_ystep; + dev->mode.maxViewportX = info.viewport_xmax; + dev->mode.maxViewportY = info.viewport_ymax; + dev->mode.viewportFlags = info.viewport_flags; + dev->mode.reserved1 = info.reserved1; + dev->mode.reserved2 = info.reserved2; + + dev->mode.name = (char*)(&dev[1]); + _XRead(dpy, dev->mode.name, info.name_size); + + dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0; + dev->data = XDGAGetMappedMemory(screen); + + if(dev->data) + dev->data += rep.offset; + } + /* not sure what to do if the allocation fails */ + } + } + + UnlockDisplay(dpy); + SyncHandle(); + + return dev; +} + + +void XDGASetViewport( + Display *dpy, + int screen, + int x, + int y, + int flags +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGASetViewportReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGASetViewport, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASetViewport; + req->screen = screen; + req->x = x; + req->y = y; + req->flags = flags; + UnlockDisplay(dpy); + SyncHandle(); +} + + +void XDGAInstallColormap( + Display *dpy, + int screen, + Colormap cmap +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAInstallColormapReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGAInstallColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAInstallColormap; + req->screen = screen; + req->cmap = cmap; + UnlockDisplay(dpy); + SyncHandle(); +} + +void XDGASelectInput( + Display *dpy, + int screen, + long mask +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGASelectInputReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGASelectInput, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASelectInput; + req->screen = screen; + req->mask = mask; + UnlockDisplay(dpy); + SyncHandle(); +} + +void XDGAFillRectangle( + Display *dpy, + int screen, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned long color +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAFillRectangleReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGAFillRectangle, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAFillRectangle; + req->screen = screen; + req->x = x; + req->y = y; + req->width = width; + req->height = height; + req->color = color; + UnlockDisplay(dpy); + SyncHandle(); +} + +void XDGACopyArea( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGACopyAreaReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGACopyArea, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACopyArea; + req->screen = screen; + req->srcx = srcx; + req->srcy = srcy; + req->width = width; + req->height = height; + req->dstx = dstx; + req->dsty = dsty; + UnlockDisplay(dpy); + SyncHandle(); +} + +void XDGACopyTransparentArea( + Display *dpy, + int screen, + int srcx, + int srcy, + unsigned int width, + unsigned int height, + int dstx, + int dsty, + unsigned long key +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGACopyTransparentAreaReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGACopyTransparentArea, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACopyTransparentArea; + req->screen = screen; + req->srcx = srcx; + req->srcy = srcy; + req->width = width; + req->height = height; + req->dstx = dstx; + req->dsty = dsty; + req->key = key; + UnlockDisplay(dpy); + SyncHandle(); +} + + +int XDGAGetViewportStatus( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAGetViewportStatusReply rep; + xXDGAGetViewportStatusReq *req; + int status = 0; + + XDGACheckExtension (dpy, info, 0); + + LockDisplay(dpy); + GetReq(XDGAGetViewportStatus, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAGetViewportStatus; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) + status = rep.status; + UnlockDisplay(dpy); + SyncHandle(); + return status; +} + +void XDGASync( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGASyncReply rep; + xXDGASyncReq *req; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGASync, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGASync; + req->screen = screen; + _XReply(dpy, (xReply *)&rep, 0, xFalse); + UnlockDisplay(dpy); + SyncHandle(); +} + + +void XDGAChangePixmapMode( + Display *dpy, + int screen, + int *x, + int *y, + int mode +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGAChangePixmapModeReq *req; + xXDGAChangePixmapModeReply rep; + + XextSimpleCheckExtension (dpy, info, xdga_extension_name); + + LockDisplay(dpy); + GetReq(XDGAChangePixmapMode, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGAChangePixmapMode; + req->screen = screen; + req->x = *x; + req->y = *y; + req->flags = mode; + _XReply(dpy, (xReply *)&rep, 0, xFalse); + *x = rep.x; + *y = rep.y; + UnlockDisplay(dpy); + SyncHandle(); +} + +Colormap XDGACreateColormap( + Display *dpy, + int screen, + XDGADevice *dev, + int alloc +){ + XExtDisplayInfo *info = xdga_find_display (dpy); + xXDGACreateColormapReq *req; + Colormap cid; + + XDGACheckExtension (dpy, info, -1); + + LockDisplay(dpy); + GetReq(XDGACreateColormap, req); + req->reqType = info->codes->major_opcode; + req->dgaReqType = X_XDGACreateColormap; + req->screen = screen; + req->mode = dev->mode.num; + req->alloc = alloc; + cid = req->id = XAllocID(dpy); + UnlockDisplay(dpy); + SyncHandle(); + + return cid; +} + + +void XDGAKeyEventToXKeyEvent( + XDGAKeyEvent* dk, + XKeyEvent* xk +){ + xk->type = dk->type; + xk->serial = dk->serial; + xk->send_event = False; + xk->display = dk->display; + xk->window = RootWindow(dk->display, dk->screen); + xk->root = xk->window; + xk->subwindow = None; + xk->time = dk->time; + xk->x = xk->y = xk->x_root = xk->y_root = 0; + xk->state = dk->state; + xk->keycode = dk->keycode; + xk->same_screen = True; +} + +#include <X11/Xmd.h> +#include <X11/extensions/xf86dga.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#if defined(ISC) +# define HAS_SVR3_MMAP +# include <sys/types.h> +# include <errno.h> + +# include <sys/at_ansi.h> +# include <sys/kd.h> + +# include <sys/sysmacros.h> +# include <sys/immu.h> +# include <sys/region.h> + +# include <sys/mmap.h> +#else +# if defined(Lynx) && defined(NO_MMAP) +# include <sys/types.h> +# include <errno.h> +# include <smem.h> +# else +# if !defined(__UNIXOS2__) +# include <sys/mman.h> +# endif +# 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" +#endif + + + +typedef struct _DGAMapRec{ + unsigned char *physical; + unsigned char *virtual; + CARD32 size; + int fd; + int screen; + struct _DGAMapRec *next; +} DGAMapRec, *DGAMapPtr; + +static Bool +DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr); +static void DGAUnmapPhysical(DGAMapPtr); + +static DGAMapPtr _Maps = NULL; + + +unsigned char* +XDGAGetMappedMemory(int screen) +{ + DGAMapPtr pMap = _Maps; + unsigned char *pntr = NULL; + + while(pMap != NULL) { + if(pMap->screen == screen) { + pntr = pMap->virtual; + break; + } + pMap = pMap->next; + } + + return pntr; +} + +Bool +XDGAMapFramebuffer( + int screen, + char *name, /* optional device name */ + unsigned char* base, /* physical memory */ + CARD32 size, /* size */ + CARD32 offset, /* optional offset */ + CARD32 extra /* optional extra data */ +){ + DGAMapPtr pMap = _Maps; + Bool result; + + /* is it already mapped ? */ + while(pMap != NULL) { + if(pMap->screen == screen) + return True; + pMap = pMap->next; + } + + if(extra & XDGANeedRoot) { + /* we should probably check if we have root permissions and + return False here */ + + } + + pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec)); + + result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap); + + if(result) { + pMap->next = _Maps; + _Maps = pMap; + } else + Xfree(pMap); + + return result; +} + +void +XDGAUnmapFramebuffer(int screen) +{ + DGAMapPtr pMap = _Maps; + DGAMapPtr pPrev = NULL; + + /* is it already mapped */ + while(pMap != NULL) { + if(pMap->screen == screen) + break; + pPrev = pMap; + pMap = pMap->next; + } + + if(!pMap) + return; + + DGAUnmapPhysical(pMap); + + if(!pPrev) + _Maps = pMap->next; + else + pPrev->next = pMap->next; + + Xfree(pMap); +} + + +static Bool +DGAMapPhysical( + int screen, + char *name, /* optional device name */ + unsigned char* base, /* physical memory */ + CARD32 size, /* size */ + CARD32 offset, /* optional offset */ + CARD32 extra, /* optional extra data */ + DGAMapPtr pMap +) { +#if defined(ISC) && defined(HAS_SVR3_MMAP) + struct kd_memloc mloc; +#elif defined(__UNIXOS2__) + APIRET rc; + ULONG action; + HFILE hfd; +#endif + + base += offset; + + pMap->screen = screen; + pMap->physical = base; + pMap->size = size; + +#if defined(ISC) && defined(HAS_SVR3_MMAP) + if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0) + return False; + mloc.vaddr = (char *)0; + mloc.physaddr = (char *)base; + mloc.length = size; + mloc.ioflg=1; + + if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1) + return False; +#elif defined (__UNIXOS2__) + /* + * 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 False; + { + 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 = base; + pmap.size = size; + rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP, + (PULONG)&pmap, sizeof(pmap), &plen, + (PULONG)&dmap, sizeof(dmap), &dlen); + if (rc == 0) { + pMap->virtual = dmap.a.user; + } + } + if (rc != 0) + return False; +#elif defined (Lynx) && defined(NO_MMAP) + pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE); +#else +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + if (!name) + name = DEV_MEM; + if ((pMap->fd = open(name, O_RDWR)) < 0) + return False; + pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, pMap->fd, (off_t)base); + if (pMap->virtual == (void *)-1) + return False; +#endif + +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) \ + && !(defined(Lynx) && defined(NO_MMAP)) \ + && !defined(__UNIXOS2__) + mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE); +#endif + + return True; +} + + + +static void +DGAUnmapPhysical(DGAMapPtr pMap) +{ +#if !defined(ISC) && !defined(HAS_SVR3_MMAP) \ + && !(defined(Lynx) && defined(NO_MMAP)) \ + && !defined(__UNIXOS2__) + mprotect(pMap->virtual,pMap->size, PROT_READ); +#elif defined(Lynx) && defined(NO_MMAP) + /* XXX this doesn't allow enable after disable */ + smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH); + smem_remove("XF86DGA"); +#endif + + + /* We need to unmap and close too !!!!!!!!!!*/ +} |