1 /* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 dawes Exp $ */
4 Copyright (c) 1995 Jon Tombs
5 Copyright (c) 1995,1996 The XFree86 Project, Inc
9 /* THIS IS NOT AN X CONSORTIUM STANDARD */
11 #ifdef __EMX__ /* needed here to override certain constants in X headers */
20 /* Apparently some X11 systems can't include this multiple times... */
21 #ifndef SDL_INCLUDED_XLIBINT_H
22 #define SDL_INCLUDED_XLIBINT_H 1
23 #include <X11/Xlibint.h>
26 #include "../extensions/xf86dga.h"
27 #include "../extensions/xf86dgastr.h"
28 #include "../extensions/Xext.h"
29 #include "../extensions/extutil.h"
32 #if defined(ENABLE_FBCON) /* Needed for framebuffer console support */
33 #include <sys/ioctl.h>
37 /* If you change this, change the Bases[] array below as well */
40 char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
42 static XExtensionInfo _xdga_info_data;
43 static XExtensionInfo *xdga_info = &_xdga_info_data;
46 Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32);
47 void SDL_NAME(XDGAUnmapFramebuffer)(int);
48 unsigned char* SDL_NAME(XDGAGetMappedMemory)(int);
50 #define XDGACheckExtension(dpy,i,val) \
51 XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
53 /*****************************************************************************
55 * private utility routines *
57 *****************************************************************************/
59 static int xdga_close_display(Display *dpy, XExtCodes *codes);
60 static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
61 static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
63 static XExtensionHooks xdga_extension_hooks = {
68 NULL, /* create_font */
70 xdga_close_display, /* close_display */
71 xdga_wire_to_event, /* wire_to_event */
72 xdga_event_to_wire, /* event_to_wire */
74 NULL, /* error_string */
77 static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
80 XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info,
82 &xdga_extension_hooks,
101 dgaEvent *wire = (dgaEvent *) wire_ev;
102 SDL_NAME(XDGAButtonEvent) *bevent;
103 SDL_NAME(XDGAKeyEvent) *kevent;
104 SDL_NAME(XDGAMotionEvent) *mevent;
105 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
107 XDGACheckExtension (dpy, info, False);
109 switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
111 mevent = (SDL_NAME(XDGAMotionEvent)*)event;
112 mevent->type = wire->u.u.type & 0x7F;
113 mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
114 mevent->display = dpy;
115 mevent->screen = wire->u.event.screen;
116 mevent->time = wire->u.event.time;
117 mevent->state = wire->u.event.state;
118 mevent->dx = wire->u.event.dx;
119 mevent->dy = wire->u.event.dy;
123 bevent = (SDL_NAME(XDGAButtonEvent)*)event;
124 bevent->type = wire->u.u.type & 0x7F;
125 bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
126 bevent->display = dpy;
127 bevent->screen = wire->u.event.screen;
128 bevent->time = wire->u.event.time;
129 bevent->state = wire->u.event.state;
130 bevent->button = wire->u.u.detail;
134 kevent = (SDL_NAME(XDGAKeyEvent)*)event;
135 kevent->type = wire->u.u.type & 0x7F;
136 kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
137 kevent->display = dpy;
138 kevent->screen = wire->u.event.screen;
139 kevent->time = wire->u.event.time;
140 kevent->state = wire->u.event.state;
141 kevent->keycode = wire->u.u.detail;
149 Bool SDL_NAME(XDGAQueryExtension) (
154 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
156 if (XextHasExtension(info)) {
157 *event_basep = info->codes->first_event;
158 *error_basep = info->codes->first_error;
166 Bool SDL_NAME(XDGAQueryVersion)(
171 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
172 xXDGAQueryVersionReply rep;
173 xXDGAQueryVersionReq *req;
175 XDGACheckExtension (dpy, info, False);
178 GetReq(XDGAQueryVersion, req);
179 req->reqType = info->codes->major_opcode;
180 req->dgaReqType = X_XDGAQueryVersion;
181 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
186 *majorVersion = rep.majorVersion;
187 *minorVersion = rep.minorVersion;
190 if (*majorVersion >= 2)
194 for (i = 0, j = info->codes->first_event;
195 i < XF86DGANumberEvents;
198 XESetWireToEvent(dpy, j, xdga_wire_to_event);
199 XESetEventToWire(dpy, j, xdga_event_to_wire);
201 SDL_NAME(XDGASetClientVersion)(dpy);
206 Bool SDL_NAME(XDGASetClientVersion)(
209 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
210 xXDGASetClientVersionReq *req;
212 XDGACheckExtension (dpy, info, False);
215 GetReq(XDGASetClientVersion, req);
216 req->reqType = info->codes->major_opcode;
217 req->dgaReqType = X_XDGASetClientVersion;
218 req->major = XDGA_MAJOR_VERSION;
219 req->minor = XDGA_MINOR_VERSION;
225 Bool SDL_NAME(XDGAOpenFramebuffer)(
229 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
230 xXDGAOpenFramebufferReply rep;
231 xXDGAOpenFramebufferReq *req;
232 char *deviceName = NULL;
235 XDGACheckExtension (dpy, info, False);
238 GetReq(XDGAOpenFramebuffer, req);
239 req->reqType = info->codes->major_opcode;
240 req->dgaReqType = X_XDGAOpenFramebuffer;
241 req->screen = screen;
242 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
249 deviceName = Xmalloc(rep.length << 2);
250 _XRead(dpy, deviceName, rep.length << 2);
253 ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName,
254 (unsigned char*)(long)rep.mem1,
255 rep.size, rep.offset, rep.extra);
265 void SDL_NAME(XDGACloseFramebuffer)(
269 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
270 xXDGACloseFramebufferReq *req;
272 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
274 SDL_NAME(XDGAUnmapFramebuffer)(screen);
277 GetReq(XDGACloseFramebuffer, req);
278 req->reqType = info->codes->major_opcode;
279 req->dgaReqType = X_XDGACloseFramebuffer;
280 req->screen = screen;
287 SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
292 XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
293 xXDGAQueryModesReply rep;
294 xXDGAQueryModesReq *req;
295 SDL_NAME(XDGAMode) *modes = NULL;
299 XDGACheckExtension (dpy, dinfo, NULL);
302 GetReq(XDGAQueryModes, req);
303 req->reqType = dinfo->codes->major_opcode;
304 req->dgaReqType = X_XDGAQueryModes;
305 req->screen = screen;
307 if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
313 size = rep.length << 2;
314 size -= rep.number * sz_xXDGAModeInfo; /* find text size */
315 modes = (SDL_NAME(XDGAMode)*)Xmalloc((rep.number * sizeof(SDL_NAME(XDGAMode))) + size);
316 offset = (char*)(&modes[rep.number]); /* start of text */
320 for(i = 0; i < rep.number; i++) {
321 _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
323 modes[i].num = info.num;
324 modes[i].verticalRefresh =
325 (float)info.vsync_num / (float)info.vsync_den;
326 modes[i].flags = info.flags;
327 modes[i].imageWidth = info.image_width;
328 modes[i].imageHeight = info.image_height;
329 modes[i].pixmapWidth = info.pixmap_width;
330 modes[i].pixmapHeight = info.pixmap_height;
331 modes[i].bytesPerScanline = info.bytes_per_scanline;
332 modes[i].byteOrder = info.byte_order;
333 modes[i].depth = info.depth;
334 modes[i].bitsPerPixel = info.bpp;
335 modes[i].redMask = info.red_mask;
336 modes[i].greenMask = info.green_mask;
337 modes[i].blueMask = info.blue_mask;
338 modes[i].visualClass = info.visual_class;
339 modes[i].viewportWidth = info.viewport_width;
340 modes[i].viewportHeight = info.viewport_height;
341 modes[i].xViewportStep = info.viewport_xstep;
342 modes[i].yViewportStep = info.viewport_ystep;
343 modes[i].maxViewportX = info.viewport_xmax;
344 modes[i].maxViewportY = info.viewport_ymax;
345 modes[i].viewportFlags = info.viewport_flags;
346 modes[i].reserved1 = info.reserved1;
347 modes[i].reserved2 = info.reserved2;
349 _XRead(dpy, offset, info.name_size);
350 modes[i].name = offset;
351 offset += info.name_size;
355 _XEatData(dpy, rep.length << 2);
366 SDL_NAME(XDGADevice) *
367 SDL_NAME(XDGASetMode)(
372 XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
373 xXDGASetModeReply rep;
374 xXDGASetModeReq *req;
375 SDL_NAME(XDGADevice) *dev = NULL;
378 XDGACheckExtension (dpy, dinfo, NULL);
381 GetReq(XDGASetMode, req);
382 req->reqType = dinfo->codes->major_opcode;
383 req->dgaReqType = X_XDGASetMode;
384 req->screen = screen;
386 req->pid = pid = XAllocID(dpy);
388 if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
393 size = rep.length << 2;
394 size -= sz_xXDGAModeInfo; /* get text size */
396 dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size);
399 _XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
401 dev->mode.num = info.num;
402 dev->mode.verticalRefresh =
403 (float)info.vsync_num / (float)info.vsync_den;
404 dev->mode.flags = info.flags;
405 dev->mode.imageWidth = info.image_width;
406 dev->mode.imageHeight = info.image_height;
407 dev->mode.pixmapWidth = info.pixmap_width;
408 dev->mode.pixmapHeight = info.pixmap_height;
409 dev->mode.bytesPerScanline = info.bytes_per_scanline;
410 dev->mode.byteOrder = info.byte_order;
411 dev->mode.depth = info.depth;
412 dev->mode.bitsPerPixel = info.bpp;
413 dev->mode.redMask = info.red_mask;
414 dev->mode.greenMask = info.green_mask;
415 dev->mode.blueMask = info.blue_mask;
416 dev->mode.visualClass = info.visual_class;
417 dev->mode.viewportWidth = info.viewport_width;
418 dev->mode.viewportHeight = info.viewport_height;
419 dev->mode.xViewportStep = info.viewport_xstep;
420 dev->mode.yViewportStep = info.viewport_ystep;
421 dev->mode.maxViewportX = info.viewport_xmax;
422 dev->mode.maxViewportY = info.viewport_ymax;
423 dev->mode.viewportFlags = info.viewport_flags;
424 dev->mode.reserved1 = info.reserved1;
425 dev->mode.reserved2 = info.reserved2;
427 dev->mode.name = (char*)(&dev[1]);
428 _XRead(dpy, dev->mode.name, info.name_size);
430 dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
431 dev->data = SDL_NAME(XDGAGetMappedMemory)(screen);
434 dev->data += rep.offset;
436 /* not sure what to do if the allocation fails */
447 void SDL_NAME(XDGASetViewport)(
454 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
455 xXDGASetViewportReq *req;
457 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
460 GetReq(XDGASetViewport, req);
461 req->reqType = info->codes->major_opcode;
462 req->dgaReqType = X_XDGASetViewport;
463 req->screen = screen;
472 void SDL_NAME(XDGAInstallColormap)(
477 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
478 xXDGAInstallColormapReq *req;
480 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
483 GetReq(XDGAInstallColormap, req);
484 req->reqType = info->codes->major_opcode;
485 req->dgaReqType = X_XDGAInstallColormap;
486 req->screen = screen;
492 void SDL_NAME(XDGASelectInput)(
497 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
498 xXDGASelectInputReq *req;
500 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
503 GetReq(XDGASelectInput, req);
504 req->reqType = info->codes->major_opcode;
505 req->dgaReqType = X_XDGASelectInput;
506 req->screen = screen;
512 void SDL_NAME(XDGAFillRectangle)(
521 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
522 xXDGAFillRectangleReq *req;
524 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
527 GetReq(XDGAFillRectangle, req);
528 req->reqType = info->codes->major_opcode;
529 req->dgaReqType = X_XDGAFillRectangle;
530 req->screen = screen;
534 req->height = height;
540 void SDL_NAME(XDGACopyArea)(
550 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
551 xXDGACopyAreaReq *req;
553 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
556 GetReq(XDGACopyArea, req);
557 req->reqType = info->codes->major_opcode;
558 req->dgaReqType = X_XDGACopyArea;
559 req->screen = screen;
563 req->height = height;
570 void SDL_NAME(XDGACopyTransparentArea)(
581 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
582 xXDGACopyTransparentAreaReq *req;
584 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
587 GetReq(XDGACopyTransparentArea, req);
588 req->reqType = info->codes->major_opcode;
589 req->dgaReqType = X_XDGACopyTransparentArea;
590 req->screen = screen;
594 req->height = height;
603 int SDL_NAME(XDGAGetViewportStatus)(
607 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
608 xXDGAGetViewportStatusReply rep;
609 xXDGAGetViewportStatusReq *req;
612 XDGACheckExtension (dpy, info, 0);
615 GetReq(XDGAGetViewportStatus, req);
616 req->reqType = info->codes->major_opcode;
617 req->dgaReqType = X_XDGAGetViewportStatus;
618 req->screen = screen;
619 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
626 void SDL_NAME(XDGASync)(
630 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
634 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
637 GetReq(XDGASync, req);
638 req->reqType = info->codes->major_opcode;
639 req->dgaReqType = X_XDGASync;
640 req->screen = screen;
641 _XReply(dpy, (xReply *)&rep, 0, xFalse);
647 void SDL_NAME(XDGAChangePixmapMode)(
654 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
655 xXDGAChangePixmapModeReq *req;
656 xXDGAChangePixmapModeReply rep;
658 XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
661 GetReq(XDGAChangePixmapMode, req);
662 req->reqType = info->codes->major_opcode;
663 req->dgaReqType = X_XDGAChangePixmapMode;
664 req->screen = screen;
668 _XReply(dpy, (xReply *)&rep, 0, xFalse);
675 Colormap SDL_NAME(XDGACreateColormap)(
678 SDL_NAME(XDGADevice) *dev,
681 XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
682 xXDGACreateColormapReq *req;
685 XDGACheckExtension (dpy, info, -1);
688 GetReq(XDGACreateColormap, req);
689 req->reqType = info->codes->major_opcode;
690 req->dgaReqType = X_XDGACreateColormap;
691 req->screen = screen;
692 req->mode = dev->mode.num;
694 cid = req->id = XAllocID(dpy);
702 void SDL_NAME(XDGAKeyEventToXKeyEvent)(
703 SDL_NAME(XDGAKeyEvent)* dk,
707 xk->serial = dk->serial;
708 xk->send_event = False;
709 xk->display = dk->display;
710 xk->window = RootWindow(dk->display, dk->screen);
711 xk->root = xk->window;
712 xk->subwindow = None;
714 xk->x = xk->y = xk->x_root = xk->y_root = 0;
715 xk->state = dk->state;
716 xk->keycode = dk->keycode;
717 xk->same_screen = True;
725 # define HAS_SVR3_MMAP
726 # include <sys/types.h>
729 # include <sys/at_ansi.h>
732 # include <sys/sysmacros.h>
733 # include <sys/immu.h>
734 # include <sys/region.h>
736 # include <sys/mmap.h>
739 # if !defined(__EMX__)
740 # include <sys/mman.h>
743 # include <sys/types.h>
748 #include <sys/wait.h>
752 #if defined(SVR4) && !defined(sun) && !defined(SCO325)
753 #define DEV_MEM "/dev/pmem"
754 #elif defined(SVR4) && defined(sun)
755 #define DEV_MEM "/dev/xsvc"
757 #define DEV_MEM "/dev/mem"
762 typedef struct _DGAMapRec{
763 unsigned char *physical;
764 unsigned char *virtual;
768 struct _DGAMapRec *next;
769 } DGAMapRec, *DGAMapPtr;
772 DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
773 static void DGAUnmapPhysical(DGAMapPtr);
775 static DGAMapPtr _Maps = NULL;
779 SDL_NAME(XDGAGetMappedMemory)(int screen)
781 DGAMapPtr pMap = _Maps;
782 unsigned char *pntr = NULL;
784 while(pMap != NULL) {
785 if(pMap->screen == screen) {
786 pntr = pMap->virtual;
796 SDL_NAME(XDGAMapFramebuffer)(
798 char *name, /* optional device name */
799 unsigned char* base, /* physical memory */
800 CARD32 size, /* size */
801 CARD32 offset, /* optional offset */
802 CARD32 extra /* optional extra data */
804 DGAMapPtr pMap = _Maps;
807 /* is it already mapped ? */
808 while(pMap != NULL) {
809 if(pMap->screen == screen)
814 if(extra & XDGANeedRoot) {
815 /* we should probably check if we have root permissions and
820 pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
822 result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
834 SDL_NAME(XDGAUnmapFramebuffer)(int screen)
836 DGAMapPtr pMap = _Maps;
837 DGAMapPtr pPrev = NULL;
839 /* is it already mapped */
840 while(pMap != NULL) {
841 if(pMap->screen == screen)
850 DGAUnmapPhysical(pMap);
855 pPrev->next = pMap->next;
864 char *name, /* optional device name */
865 unsigned char* base, /* physical memory */
866 CARD32 size, /* size */
867 CARD32 offset, /* optional offset */
868 CARD32 extra, /* optional extra data */
871 #if defined(ISC) && defined(HAS_SVR3_MMAP)
872 struct kd_memloc mloc;
873 #elif defined(__EMX__)
881 pMap->screen = screen;
882 pMap->physical = base;
885 #if defined(ISC) && defined(HAS_SVR3_MMAP)
886 if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
888 mloc.vaddr = (char *)0;
889 mloc.physaddr = (char *)base;
893 if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
895 #elif defined (__EMX__)
897 * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
898 * Consecutive calling of this routine will make PMAP$ driver run out
899 * of memory handles. Some umap/close mechanism should be provided
902 rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
903 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
915 #define XFREE86_PMAP 0x76
916 #define PMAP_MAP 0x44
920 rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
921 (PULONG)&pmap, sizeof(pmap), &plen,
922 (PULONG)&dmap, sizeof(dmap), &dlen);
924 pMap->virtual = dmap.a.user;
930 pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
937 if ((pMap->fd = open(name, O_RDWR)) < 0)
938 #if defined(ENABLE_FBCON)
939 { /* /dev/fb0 fallback added by Sam Lantinga <hercules@lokigames.com> */
940 /* Try to fall back to /dev/fb on Linux - FIXME: verify the device */
941 struct fb_fix_screeninfo finfo;
943 if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) {
946 /* The useable framebuffer console memory may not be the whole
947 framebuffer that X has access to. :-(
949 if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
953 /* Warning: On PPC, the size and virtual need to be offset by:
954 (((long)finfo.smem_start) -
955 (((long)finfo.smem_start)&~(PAGE_SIZE-1)))
958 size = pMap->size = finfo.smem_len;
963 pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
964 MAP_FILE | MAP_SHARED, pMap->fd, (off_t)base);
965 if (pMap->virtual == (void *)-1)
969 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
971 mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
980 DGAUnmapPhysical(DGAMapPtr pMap)
982 #if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
984 mprotect(pMap->virtual,pMap->size, PROT_READ);
986 /* XXX this doesn't allow enable after disable */
987 smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
988 smem_remove("XF86DGA");
992 /* We need to unmap and close too !!!!!!!!!!*/