1/* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 dawes Exp $ */
2/*
3
4Copyright (c) 1995  Jon Tombs
5Copyright (c) 1995,1996  The XFree86 Project, Inc
6
7*/
8
9/* THIS IS NOT AN X CONSORTIUM STANDARD */
10
11#ifdef __EMX__ /* needed here to override certain constants in X headers */
12#define INCL_DOS
13#define INCL_DOSIOCTL
14#include <os2.h>
15#endif
16
17#define NEED_EVENTS
18#define NEED_REPLIES
19
20#include <X11/Xlibint.h>
21#include "../extensions/xf86dga.h"
22#include "../extensions/xf86dgastr.h"
23#include "../extensions/Xext.h"
24#include "../extensions/extutil.h"
25#include <stdio.h>
26
27#if defined(ENABLE_FBCON)  /* Needed for framebuffer console support */
28#include <sys/ioctl.h>
29#include <linux/fb.h>
30#endif
31
32/* If you change this, change the Bases[] array below as well */
33#define MAX_HEADS 16
34
35char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
36
37static XExtensionInfo _xdga_info_data;
38static XExtensionInfo *xdga_info = &_xdga_info_data;
39
40
41Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32);
42void SDL_NAME(XDGAUnmapFramebuffer)(int);
43unsigned char* SDL_NAME(XDGAGetMappedMemory)(int);
44
45#define XDGACheckExtension(dpy,i,val) \
46  XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
47
48/*****************************************************************************
49 *                                                                           *
50 *			   private utility routines                          *
51 *                                                                           *
52 *****************************************************************************/
53
54static int xdga_close_display(Display *dpy, XExtCodes *codes);
55static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
56static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
57
58static XExtensionHooks xdga_extension_hooks = {
59    NULL,				/* create_gc */
60    NULL,				/* copy_gc */
61    NULL,				/* flush_gc */
62    NULL,				/* free_gc */
63    NULL,				/* create_font */
64    NULL,				/* free_font */
65    xdga_close_display,			/* close_display */
66    xdga_wire_to_event,			/* wire_to_event */
67    xdga_event_to_wire,			/* event_to_wire */
68    NULL,				/* error */
69    NULL,				/* error_string */
70};
71
72static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
73
74
75XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info,
76				   "XFree86-DGA",
77				   &xdga_extension_hooks,
78				   0, NULL)
79
80
81static Status
82xdga_event_to_wire(
83  Display *dpy,
84  XEvent *event,
85  xEvent *wire_ev
86){
87    return True;
88}
89
90static Bool
91xdga_wire_to_event(
92  Display *dpy,
93  XEvent *event,
94  xEvent *wire_ev
95){
96  dgaEvent *wire = (dgaEvent *) wire_ev;
97  SDL_NAME(XDGAButtonEvent) *bevent;
98  SDL_NAME(XDGAKeyEvent) *kevent;
99  SDL_NAME(XDGAMotionEvent) *mevent;
100  XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
101
102  XDGACheckExtension (dpy, info, False);
103
104  switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
105  case MotionNotify:
106	mevent = (SDL_NAME(XDGAMotionEvent)*)event;
107	mevent->type = wire->u.u.type & 0x7F;
108	mevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
109	mevent->display = dpy;
110	mevent->screen = wire->u.event.screen;
111	mevent->time = wire->u.event.time;
112	mevent->state = wire->u.event.state;
113	mevent->dx = wire->u.event.dx;
114	mevent->dy = wire->u.event.dy;
115	return True;
116  case ButtonPress:
117  case ButtonRelease:
118	bevent = (SDL_NAME(XDGAButtonEvent)*)event;
119	bevent->type = wire->u.u.type & 0x7F;
120	bevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
121	bevent->display = dpy;
122	bevent->screen = wire->u.event.screen;
123	bevent->time = wire->u.event.time;
124	bevent->state = wire->u.event.state;
125	bevent->button = wire->u.u.detail;
126	return True;
127  case KeyPress:
128  case KeyRelease:
129	kevent = (SDL_NAME(XDGAKeyEvent)*)event;
130	kevent->type = wire->u.u.type & 0x7F;
131	kevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *)wire);
132	kevent->display = dpy;
133	kevent->screen = wire->u.event.screen;
134	kevent->time = wire->u.event.time;
135	kevent->state = wire->u.event.state;
136	kevent->keycode = wire->u.u.detail;
137	return True;
138  }
139
140  return False;
141}
142
143
144Bool SDL_NAME(XDGAQueryExtension) (
145    Display *dpy,
146    int *event_basep,
147    int *error_basep
148){
149    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
150
151    if (XextHasExtension(info)) {
152	*event_basep = info->codes->first_event;
153	*error_basep = info->codes->first_error;
154	return True;
155    } else {
156	return False;
157    }
158}
159
160
161Bool SDL_NAME(XDGAQueryVersion)(
162    Display *dpy,
163    int *majorVersion,
164    int *minorVersion
165){
166    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
167    xXDGAQueryVersionReply rep;
168    xXDGAQueryVersionReq *req;
169
170    XDGACheckExtension (dpy, info, False);
171
172    LockDisplay(dpy);
173    GetReq(XDGAQueryVersion, req);
174    req->reqType = info->codes->major_opcode;
175    req->dgaReqType = X_XDGAQueryVersion;
176    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
177	UnlockDisplay(dpy);
178	SyncHandle();
179	return False;
180    }
181    *majorVersion = rep.majorVersion;
182    *minorVersion = rep.minorVersion;
183    UnlockDisplay(dpy);
184    SyncHandle();
185    if (*majorVersion >= 2)
186    {
187	int i, j;
188
189	for (i = 0, j = info->codes->first_event;
190	     i < XF86DGANumberEvents;
191	     i++, j++)
192	{
193	    XESetWireToEvent(dpy, j, xdga_wire_to_event);
194	    XESetEventToWire(dpy, j, xdga_event_to_wire);
195	}
196	SDL_NAME(XDGASetClientVersion)(dpy);
197    }
198    return True;
199}
200
201Bool SDL_NAME(XDGASetClientVersion)(
202    Display	*dpy
203){
204    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
205    xXDGASetClientVersionReq *req;
206
207    XDGACheckExtension (dpy, info, False);
208
209    LockDisplay(dpy);
210    GetReq(XDGASetClientVersion, req);
211    req->reqType = info->codes->major_opcode;
212    req->dgaReqType = X_XDGASetClientVersion;
213    req->major = XDGA_MAJOR_VERSION;
214    req->minor = XDGA_MINOR_VERSION;
215    UnlockDisplay(dpy);
216    SyncHandle();
217    return True;
218}
219
220Bool SDL_NAME(XDGAOpenFramebuffer)(
221    Display	*dpy,
222    int 	screen
223){
224    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
225    xXDGAOpenFramebufferReply rep;
226    xXDGAOpenFramebufferReq *req;
227    char *deviceName = NULL;
228    Bool ret;
229
230    XDGACheckExtension (dpy, info, False);
231
232    LockDisplay(dpy);
233    GetReq(XDGAOpenFramebuffer, req);
234    req->reqType = info->codes->major_opcode;
235    req->dgaReqType = X_XDGAOpenFramebuffer;
236    req->screen = screen;
237    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
238	UnlockDisplay(dpy);
239	SyncHandle();
240	return False;
241    }
242
243    if(rep.length) {
244	deviceName = Xmalloc(rep.length << 2);
245	_XRead(dpy, deviceName, rep.length << 2);
246    }
247
248    ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName,
249				(unsigned char*)(long)rep.mem1,
250				rep.size, rep.offset, rep.extra);
251
252    if(deviceName)
253	Xfree(deviceName);
254
255    UnlockDisplay(dpy);
256    SyncHandle();
257    return ret;
258}
259
260void SDL_NAME(XDGACloseFramebuffer)(
261    Display	*dpy,
262    int		screen
263){
264    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
265    xXDGACloseFramebufferReq *req;
266
267    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
268
269    SDL_NAME(XDGAUnmapFramebuffer)(screen);
270
271    LockDisplay(dpy);
272    GetReq(XDGACloseFramebuffer, req);
273    req->reqType = info->codes->major_opcode;
274    req->dgaReqType = X_XDGACloseFramebuffer;
275    req->screen = screen;
276    UnlockDisplay(dpy);
277    SyncHandle();
278}
279
280
281
282SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
283    Display *dpy,
284    int screen,
285    int *num
286){
287    XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
288    xXDGAQueryModesReply rep;
289    xXDGAQueryModesReq *req;
290    SDL_NAME(XDGAMode) *modes = NULL;
291
292    *num = 0;
293
294    XDGACheckExtension (dpy, dinfo, NULL);
295
296    LockDisplay(dpy);
297    GetReq(XDGAQueryModes, req);
298    req->reqType = dinfo->codes->major_opcode;
299    req->dgaReqType = X_XDGAQueryModes;
300    req->screen = screen;
301
302    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
303	if(rep.length) {
304	   xXDGAModeInfo info;
305	   int i, size;
306	   char *offset;
307
308	   size = rep.length << 2;
309	   size -= rep.number * sz_xXDGAModeInfo; /* find text size */
310	   modes = (SDL_NAME(XDGAMode)*)Xmalloc((rep.number * sizeof(SDL_NAME(XDGAMode))) + size);
311	   offset = (char*)(&modes[rep.number]); /* start of text */
312
313
314	   if(modes) {
315	      for(i = 0; i < rep.number; i++) {
316		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
317
318		modes[i].num = info.num;
319		modes[i].verticalRefresh =
320			(float)info.vsync_num / (float)info.vsync_den;
321		modes[i].flags = info.flags;
322		modes[i].imageWidth = info.image_width;
323		modes[i].imageHeight = info.image_height;
324		modes[i].pixmapWidth = info.pixmap_width;
325		modes[i].pixmapHeight = info.pixmap_height;
326		modes[i].bytesPerScanline = info.bytes_per_scanline;
327		modes[i].byteOrder = info.byte_order;
328		modes[i].depth = info.depth;
329		modes[i].bitsPerPixel = info.bpp;
330		modes[i].redMask = info.red_mask;
331		modes[i].greenMask = info.green_mask;
332		modes[i].blueMask = info.blue_mask;
333		modes[i].visualClass = info.visual_class;
334		modes[i].viewportWidth = info.viewport_width;
335		modes[i].viewportHeight = info.viewport_height;
336		modes[i].xViewportStep = info.viewport_xstep;
337		modes[i].yViewportStep = info.viewport_ystep;
338		modes[i].maxViewportX = info.viewport_xmax;
339		modes[i].maxViewportY = info.viewport_ymax;
340		modes[i].viewportFlags = info.viewport_flags;
341		modes[i].reserved1 = info.reserved1;
342		modes[i].reserved2 = info.reserved2;
343
344		_XRead(dpy, offset, info.name_size);
345		modes[i].name = offset;
346		offset += info.name_size;
347	      }
348	      *num = rep.number;
349	   } else
350		_XEatData(dpy, rep.length << 2);
351	}
352    }
353
354    UnlockDisplay(dpy);
355    SyncHandle();
356
357    return modes;
358}
359
360
361SDL_NAME(XDGADevice) *
362SDL_NAME(XDGASetMode)(
363    Display	*dpy,
364    int		screen,
365    int		mode
366){
367    XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
368    xXDGASetModeReply rep;
369    xXDGASetModeReq *req;
370    SDL_NAME(XDGADevice) *dev = NULL;
371    Pixmap pid;
372
373    XDGACheckExtension (dpy, dinfo, NULL);
374
375    LockDisplay(dpy);
376    GetReq(XDGASetMode, req);
377    req->reqType = dinfo->codes->major_opcode;
378    req->dgaReqType = X_XDGASetMode;
379    req->screen = screen;
380    req->mode = mode;
381    req->pid = pid = XAllocID(dpy);
382
383    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
384	if(rep.length) {
385	   xXDGAModeInfo info;
386	   int size;
387
388	   size = rep.length << 2;
389	   size -= sz_xXDGAModeInfo; /* get text size */
390
391	   dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size);
392
393	   if(dev) {
394		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
395
396		dev->mode.num = info.num;
397		dev->mode.verticalRefresh =
398				(float)info.vsync_num / (float)info.vsync_den;
399		dev->mode.flags = info.flags;
400		dev->mode.imageWidth = info.image_width;
401		dev->mode.imageHeight = info.image_height;
402		dev->mode.pixmapWidth = info.pixmap_width;
403		dev->mode.pixmapHeight = info.pixmap_height;
404		dev->mode.bytesPerScanline = info.bytes_per_scanline;
405		dev->mode.byteOrder = info.byte_order;
406		dev->mode.depth = info.depth;
407		dev->mode.bitsPerPixel = info.bpp;
408		dev->mode.redMask = info.red_mask;
409		dev->mode.greenMask = info.green_mask;
410		dev->mode.blueMask = info.blue_mask;
411		dev->mode.visualClass = info.visual_class;
412		dev->mode.viewportWidth = info.viewport_width;
413		dev->mode.viewportHeight = info.viewport_height;
414		dev->mode.xViewportStep = info.viewport_xstep;
415		dev->mode.yViewportStep = info.viewport_ystep;
416		dev->mode.maxViewportX = info.viewport_xmax;
417		dev->mode.maxViewportY = info.viewport_ymax;
418		dev->mode.viewportFlags = info.viewport_flags;
419		dev->mode.reserved1 = info.reserved1;
420		dev->mode.reserved2 = info.reserved2;
421
422		dev->mode.name = (char*)(&dev[1]);
423		_XRead(dpy, dev->mode.name, info.name_size);
424
425		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
426		dev->data = SDL_NAME(XDGAGetMappedMemory)(screen);
427
428		if(dev->data)
429		    dev->data += rep.offset;
430	   }
431	   /* not sure what to do if the allocation fails */
432	}
433    }
434
435    UnlockDisplay(dpy);
436    SyncHandle();
437
438    return dev;
439}
440
441
442void SDL_NAME(XDGASetViewport)(
443    Display	*dpy,
444    int		screen,
445    int		x,
446    int		y,
447    int		flags
448){
449    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
450    xXDGASetViewportReq *req;
451
452    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
453
454    LockDisplay(dpy);
455    GetReq(XDGASetViewport, req);
456    req->reqType = info->codes->major_opcode;
457    req->dgaReqType = X_XDGASetViewport;
458    req->screen = screen;
459    req->x = x;
460    req->y = y;
461    req->flags = flags;
462    UnlockDisplay(dpy);
463    SyncHandle();
464}
465
466
467void SDL_NAME(XDGAInstallColormap)(
468    Display	*dpy,
469    int		screen,
470    Colormap	cmap
471){
472    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
473    xXDGAInstallColormapReq *req;
474
475    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
476
477    LockDisplay(dpy);
478    GetReq(XDGAInstallColormap, req);
479    req->reqType = info->codes->major_opcode;
480    req->dgaReqType = X_XDGAInstallColormap;
481    req->screen = screen;
482    req->cmap = cmap;
483    UnlockDisplay(dpy);
484    SyncHandle();
485}
486
487void SDL_NAME(XDGASelectInput)(
488    Display	*dpy,
489    int		screen,
490    long	mask
491){
492    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
493    xXDGASelectInputReq *req;
494
495    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
496
497    LockDisplay(dpy);
498    GetReq(XDGASelectInput, req);
499    req->reqType = info->codes->major_opcode;
500    req->dgaReqType = X_XDGASelectInput;
501    req->screen = screen;
502    req->mask = mask;
503    UnlockDisplay(dpy);
504    SyncHandle();
505}
506
507void SDL_NAME(XDGAFillRectangle)(
508    Display	*dpy,
509    int		screen,
510    int		x,
511    int		y,
512    unsigned int	width,
513    unsigned int	height,
514    unsigned long	color
515){
516    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
517    xXDGAFillRectangleReq *req;
518
519    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
520
521    LockDisplay(dpy);
522    GetReq(XDGAFillRectangle, req);
523    req->reqType = info->codes->major_opcode;
524    req->dgaReqType = X_XDGAFillRectangle;
525    req->screen = screen;
526    req->x = x;
527    req->y = y;
528    req->width = width;
529    req->height = height;
530    req->color = color;
531    UnlockDisplay(dpy);
532    SyncHandle();
533}
534
535void SDL_NAME(XDGACopyArea)(
536    Display	*dpy,
537    int		screen,
538    int		srcx,
539    int		srcy,
540    unsigned int	width,
541    unsigned int	height,
542    int		dstx,
543    int		dsty
544){
545    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
546    xXDGACopyAreaReq *req;
547
548    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
549
550    LockDisplay(dpy);
551    GetReq(XDGACopyArea, req);
552    req->reqType = info->codes->major_opcode;
553    req->dgaReqType = X_XDGACopyArea;
554    req->screen = screen;
555    req->srcx = srcx;
556    req->srcy = srcy;
557    req->width = width;
558    req->height = height;
559    req->dstx = dstx;
560    req->dsty = dsty;
561    UnlockDisplay(dpy);
562    SyncHandle();
563}
564
565void SDL_NAME(XDGACopyTransparentArea)(
566    Display	*dpy,
567    int		screen,
568    int		srcx,
569    int		srcy,
570    unsigned int	width,
571    unsigned int	height,
572    int		dstx,
573    int		dsty,
574    unsigned long key
575){
576    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
577    xXDGACopyTransparentAreaReq *req;
578
579    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
580
581    LockDisplay(dpy);
582    GetReq(XDGACopyTransparentArea, req);
583    req->reqType = info->codes->major_opcode;
584    req->dgaReqType = X_XDGACopyTransparentArea;
585    req->screen = screen;
586    req->srcx = srcx;
587    req->srcy = srcy;
588    req->width = width;
589    req->height = height;
590    req->dstx = dstx;
591    req->dsty = dsty;
592    req->key = key;
593    UnlockDisplay(dpy);
594    SyncHandle();
595}
596
597
598int SDL_NAME(XDGAGetViewportStatus)(
599    Display *dpy,
600    int screen
601){
602    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
603    xXDGAGetViewportStatusReply rep;
604    xXDGAGetViewportStatusReq *req;
605    int status = 0;
606
607    XDGACheckExtension (dpy, info, 0);
608
609    LockDisplay(dpy);
610    GetReq(XDGAGetViewportStatus, req);
611    req->reqType = info->codes->major_opcode;
612    req->dgaReqType = X_XDGAGetViewportStatus;
613    req->screen = screen;
614    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
615	status = rep.status;
616    UnlockDisplay(dpy);
617    SyncHandle();
618    return status;
619}
620
621void SDL_NAME(XDGASync)(
622    Display *dpy,
623    int screen
624){
625    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
626    xXDGASyncReply rep;
627    xXDGASyncReq *req;
628
629    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
630
631    LockDisplay(dpy);
632    GetReq(XDGASync, req);
633    req->reqType = info->codes->major_opcode;
634    req->dgaReqType = X_XDGASync;
635    req->screen = screen;
636    _XReply(dpy, (xReply *)&rep, 0, xFalse);
637    UnlockDisplay(dpy);
638    SyncHandle();
639}
640
641
642void SDL_NAME(XDGAChangePixmapMode)(
643    Display *dpy,
644    int screen,
645    int *x,
646    int *y,
647    int mode
648){
649    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
650    xXDGAChangePixmapModeReq *req;
651    xXDGAChangePixmapModeReply rep;
652
653    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
654
655    LockDisplay(dpy);
656    GetReq(XDGAChangePixmapMode, req);
657    req->reqType = info->codes->major_opcode;
658    req->dgaReqType = X_XDGAChangePixmapMode;
659    req->screen = screen;
660    req->x = *x;
661    req->y = *y;
662    req->flags = mode;
663    _XReply(dpy, (xReply *)&rep, 0, xFalse);
664    *x = rep.x;
665    *y = rep.y;
666    UnlockDisplay(dpy);
667    SyncHandle();
668}
669
670Colormap SDL_NAME(XDGACreateColormap)(
671    Display *dpy,
672    int screen,
673    SDL_NAME(XDGADevice) *dev,
674    int	alloc
675){
676    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
677    xXDGACreateColormapReq *req;
678    Colormap cid;
679
680    XDGACheckExtension (dpy, info, -1);
681
682    LockDisplay(dpy);
683    GetReq(XDGACreateColormap, req);
684    req->reqType = info->codes->major_opcode;
685    req->dgaReqType = X_XDGACreateColormap;
686    req->screen = screen;
687    req->mode = dev->mode.num;
688    req->alloc = alloc;
689    cid = req->id = XAllocID(dpy);
690    UnlockDisplay(dpy);
691    SyncHandle();
692
693    return cid;
694}
695
696
697void SDL_NAME(XDGAKeyEventToXKeyEvent)(
698    SDL_NAME(XDGAKeyEvent)* dk,
699    XKeyEvent* xk
700){
701    xk->type = dk->type;
702    xk->serial = dk->serial;
703    xk->send_event = False;
704    xk->display = dk->display;
705    xk->window = RootWindow(dk->display, dk->screen);
706    xk->root = xk->window;
707    xk->subwindow = None;
708    xk->time = dk->time;
709    xk->x = xk->y = xk->x_root = xk->y_root = 0;
710    xk->state = dk->state;
711    xk->keycode = dk->keycode;
712    xk->same_screen = True;
713}
714
715#include <X11/Xmd.h>
716#include <stdlib.h>
717#include <stdio.h>
718#include <fcntl.h>
719#if defined(ISC)
720# define HAS_SVR3_MMAP
721# include <sys/types.h>
722# include <errno.h>
723
724# include <sys/at_ansi.h>
725# include <sys/kd.h>
726
727# include <sys/sysmacros.h>
728# include <sys/immu.h>
729# include <sys/region.h>
730
731# include <sys/mmap.h>
732#else
733# if !defined(Lynx)
734#  if !defined(__EMX__)
735#   include <sys/mman.h>
736#  endif
737# else
738#  include <sys/types.h>
739#  include <errno.h>
740#  include <smem.h>
741# endif
742#endif
743#include <sys/wait.h>
744#include <signal.h>
745#include <unistd.h>
746
747#if defined(SVR4) && !defined(sun) && !defined(SCO325)
748#define DEV_MEM "/dev/pmem"
749#elif defined(SVR4) && defined(sun)
750#define DEV_MEM "/dev/xsvc"
751#else
752#define DEV_MEM "/dev/mem"
753#endif
754
755
756
757typedef struct _DGAMapRec{
758  unsigned char *physical;
759  unsigned char *virtual;
760  CARD32 size;
761  int fd;
762  int screen;
763  struct _DGAMapRec *next;
764} DGAMapRec, *DGAMapPtr;
765
766static Bool
767DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
768static void DGAUnmapPhysical(DGAMapPtr);
769
770static DGAMapPtr _Maps = NULL;
771
772
773unsigned char*
774SDL_NAME(XDGAGetMappedMemory)(int screen)
775{
776    DGAMapPtr pMap = _Maps;
777    unsigned char *pntr = NULL;
778
779    while(pMap != NULL) {
780	if(pMap->screen == screen) {
781	    pntr = pMap->virtual;
782	    break;
783	}
784	pMap = pMap->next;
785    }
786
787    return pntr;
788}
789
790Bool
791SDL_NAME(XDGAMapFramebuffer)(
792   int screen,
793   char *name,			/* optional device name */
794   unsigned char* base,		/* physical memory */
795   CARD32 size,			/* size */
796   CARD32 offset,		/* optional offset */
797   CARD32 extra			/* optional extra data */
798){
799   DGAMapPtr pMap = _Maps;
800   Bool result;
801
802   /* is it already mapped ? */
803   while(pMap != NULL) {
804     if(pMap->screen == screen)
805	return True;
806     pMap = pMap->next;
807   }
808
809   if(extra & XDGANeedRoot) {
810    /* we should probably check if we have root permissions and
811       return False here */
812
813   }
814
815   pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
816
817   result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
818
819   if(result) {
820      pMap->next = _Maps;
821      _Maps = pMap;
822   } else
823      Xfree(pMap);
824
825   return result;
826}
827
828void
829SDL_NAME(XDGAUnmapFramebuffer)(int screen)
830{
831   DGAMapPtr pMap = _Maps;
832   DGAMapPtr pPrev = NULL;
833
834   /* is it already mapped */
835    while(pMap != NULL) {
836	if(pMap->screen == screen)
837	    break;
838	pPrev = pMap;
839	pMap = pMap->next;
840    }
841
842    if(!pMap)
843	return;
844
845    DGAUnmapPhysical(pMap);
846
847    if(!pPrev)
848	_Maps = pMap->next;
849    else
850	pPrev->next = pMap->next;
851
852    Xfree(pMap);
853}
854
855
856static Bool
857DGAMapPhysical(
858   int screen,
859   char *name,			/* optional device name */
860   unsigned char* base,		/* physical memory */
861   CARD32 size,			/* size */
862   CARD32 offset,		/* optional offset */
863   CARD32 extra,		/* optional extra data */
864   DGAMapPtr pMap
865) {
866#if defined(ISC) && defined(HAS_SVR3_MMAP)
867    struct kd_memloc mloc;
868#elif defined(__EMX__)
869    APIRET rc;
870    ULONG action;
871    HFILE hfd;
872#endif
873
874    base += offset;
875
876    pMap->screen = screen;
877    pMap->physical = base;
878    pMap->size = size;
879
880#if defined(ISC) && defined(HAS_SVR3_MMAP)
881    if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
882	return False;
883    mloc.vaddr = (char *)0;
884    mloc.physaddr = (char *)base;
885    mloc.length = size;
886    mloc.ioflg=1;
887
888    if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
889	return False;
890#elif defined (__EMX__)
891    /*
892     * Dragon warning here! /dev/pmap$ is never closed, except on progam exit.
893     * Consecutive calling of this routine will make PMAP$ driver run out
894     * of memory handles. Some umap/close mechanism should be provided
895     */
896
897    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
898		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
899    if (rc != 0)
900	return False;
901    {
902	struct map_ioctl {
903		union {
904			ULONG phys;
905			void* user;
906		} a;
907		ULONG size;
908	} pmap,dmap;
909	ULONG plen,dlen;
910#define XFREE86_PMAP	0x76
911#define PMAP_MAP	0x44
912
913	pmap.a.phys = base;
914	pmap.size = size;
915	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
916			 (PULONG)&pmap, sizeof(pmap), &plen,
917			 (PULONG)&dmap, sizeof(dmap), &dlen);
918	if (rc == 0) {
919		pMap->virtual = dmap.a.user;
920	}
921   }
922   if (rc != 0)
923	return False;
924#elif defined (Lynx)
925    pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
926#else
927#ifndef MAP_FILE
928#define MAP_FILE 0
929#endif
930    if (!name)
931	    name = DEV_MEM;
932    if ((pMap->fd = open(name, O_RDWR)) < 0)
933#if defined(ENABLE_FBCON)
934    { /* /dev/fb0 fallback added by Sam Lantinga <hercules@lokigames.com> */
935        /* Try to fall back to /dev/fb on Linux - FIXME: verify the device */
936        struct fb_fix_screeninfo finfo;
937
938        if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) {
939            return False;
940        }
941        /* The useable framebuffer console memory may not be the whole
942           framebuffer that X has access to. :-(
943         */
944        if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
945            close(pMap->fd);
946            return False;
947        }
948        /* Warning: On PPC, the size and virtual need to be offset by:
949           (((long)finfo.smem_start) -
950           (((long)finfo.smem_start)&~(PAGE_SIZE-1)))
951         */
952        base = 0;
953        size = pMap->size = finfo.smem_len;
954    }
955#else
956	return False;
957#endif
958    pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
959			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)base);
960    if (pMap->virtual == (void *)-1)
961	return False;
962#endif
963
964#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
965	&& !defined(__EMX__)
966    mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
967#endif
968
969    return True;
970}
971
972
973
974static void
975DGAUnmapPhysical(DGAMapPtr pMap)
976{
977#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
978	&& !defined(__EMX__)
979    mprotect(pMap->virtual,pMap->size, PROT_READ);
980#elif defined(Lynx)
981	/* XXX this doesn't allow enable after disable */
982    smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
983    smem_remove("XF86DGA");
984#endif
985
986
987   /* We need to unmap and close too !!!!!!!!!!*/
988}
989