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/* 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>
24#endif
25
26#include "../extensions/xf86dga.h"
27#include "../extensions/xf86dgastr.h"
28#include "../extensions/Xext.h"
29#include "../extensions/extutil.h"
30#include <stdio.h>
31
32#if defined(ENABLE_FBCON)  /* Needed for framebuffer console support */
33#include <sys/ioctl.h>
34#include <linux/fb.h>
35#endif
36
37/* If you change this, change the Bases[] array below as well */
38#define MAX_HEADS 16
39
40char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
41
42static XExtensionInfo _xdga_info_data;
43static XExtensionInfo *xdga_info = &_xdga_info_data;
44
45
46Bool SDL_NAME(XDGAMapFramebuffer)(int, char *, unsigned char*, CARD32, CARD32, CARD32);
47void SDL_NAME(XDGAUnmapFramebuffer)(int);
48unsigned char* SDL_NAME(XDGAGetMappedMemory)(int);
49
50#define XDGACheckExtension(dpy,i,val) \
51  XextCheckExtension (dpy, i, SDL_NAME(xdga_extension_name), val)
52
53/*****************************************************************************
54 *                                                                           *
55 *			   private utility routines                          *
56 *                                                                           *
57 *****************************************************************************/
58
59static int xdga_close_display(Display *dpy, XExtCodes *codes);
60static Bool xdga_wire_to_event(Display *dpy, XEvent *event, xEvent *wire_ev);
61static Status xdga_event_to_wire(Display *dpy, XEvent *event, xEvent *wire_ev);
62
63static XExtensionHooks xdga_extension_hooks = {
64    NULL,				/* create_gc */
65    NULL,				/* copy_gc */
66    NULL,				/* flush_gc */
67    NULL,				/* free_gc */
68    NULL,				/* create_font */
69    NULL,				/* free_font */
70    xdga_close_display,			/* close_display */
71    xdga_wire_to_event,			/* wire_to_event */
72    xdga_event_to_wire,			/* event_to_wire */
73    NULL,				/* error */
74    NULL,				/* error_string */
75};
76
77static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
78
79
80XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info,
81				   "XFree86-DGA",
82				   &xdga_extension_hooks,
83				   0, NULL)
84
85
86static Status
87xdga_event_to_wire(
88  Display *dpy,
89  XEvent *event,
90  xEvent *wire_ev
91){
92    return True;
93}
94
95static Bool
96xdga_wire_to_event(
97  Display *dpy,
98  XEvent *event,
99  xEvent *wire_ev
100){
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);
106
107  XDGACheckExtension (dpy, info, False);
108
109  switch((wire->u.u.type & 0x7f) - info->codes->first_event) {
110  case MotionNotify:
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;
120	return True;
121  case ButtonPress:
122  case ButtonRelease:
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;
131	return True;
132  case KeyPress:
133  case KeyRelease:
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;
142	return True;
143  }
144
145  return False;
146}
147
148
149Bool SDL_NAME(XDGAQueryExtension) (
150    Display *dpy,
151    int *event_basep,
152    int *error_basep
153){
154    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
155
156    if (XextHasExtension(info)) {
157	*event_basep = info->codes->first_event;
158	*error_basep = info->codes->first_error;
159	return True;
160    } else {
161	return False;
162    }
163}
164
165
166Bool SDL_NAME(XDGAQueryVersion)(
167    Display *dpy,
168    int *majorVersion,
169    int *minorVersion
170){
171    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
172    xXDGAQueryVersionReply rep;
173    xXDGAQueryVersionReq *req;
174
175    XDGACheckExtension (dpy, info, False);
176
177    LockDisplay(dpy);
178    GetReq(XDGAQueryVersion, req);
179    req->reqType = info->codes->major_opcode;
180    req->dgaReqType = X_XDGAQueryVersion;
181    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
182	UnlockDisplay(dpy);
183	SyncHandle();
184	return False;
185    }
186    *majorVersion = rep.majorVersion;
187    *minorVersion = rep.minorVersion;
188    UnlockDisplay(dpy);
189    SyncHandle();
190    if (*majorVersion >= 2)
191    {
192	int i, j;
193
194	for (i = 0, j = info->codes->first_event;
195	     i < XF86DGANumberEvents;
196	     i++, j++)
197	{
198	    XESetWireToEvent(dpy, j, xdga_wire_to_event);
199	    XESetEventToWire(dpy, j, xdga_event_to_wire);
200	}
201	SDL_NAME(XDGASetClientVersion)(dpy);
202    }
203    return True;
204}
205
206Bool SDL_NAME(XDGASetClientVersion)(
207    Display	*dpy
208){
209    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
210    xXDGASetClientVersionReq *req;
211
212    XDGACheckExtension (dpy, info, False);
213
214    LockDisplay(dpy);
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;
220    UnlockDisplay(dpy);
221    SyncHandle();
222    return True;
223}
224
225Bool SDL_NAME(XDGAOpenFramebuffer)(
226    Display	*dpy,
227    int 	screen
228){
229    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
230    xXDGAOpenFramebufferReply rep;
231    xXDGAOpenFramebufferReq *req;
232    char *deviceName = NULL;
233    Bool ret;
234
235    XDGACheckExtension (dpy, info, False);
236
237    LockDisplay(dpy);
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)) {
243	UnlockDisplay(dpy);
244	SyncHandle();
245	return False;
246    }
247
248    if(rep.length) {
249	deviceName = Xmalloc(rep.length << 2);
250	_XRead(dpy, deviceName, rep.length << 2);
251    }
252
253    ret = SDL_NAME(XDGAMapFramebuffer)(screen, deviceName,
254				(unsigned char*)(long)rep.mem1,
255				rep.size, rep.offset, rep.extra);
256
257    if(deviceName)
258	Xfree(deviceName);
259
260    UnlockDisplay(dpy);
261    SyncHandle();
262    return ret;
263}
264
265void SDL_NAME(XDGACloseFramebuffer)(
266    Display	*dpy,
267    int		screen
268){
269    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
270    xXDGACloseFramebufferReq *req;
271
272    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
273
274    SDL_NAME(XDGAUnmapFramebuffer)(screen);
275
276    LockDisplay(dpy);
277    GetReq(XDGACloseFramebuffer, req);
278    req->reqType = info->codes->major_opcode;
279    req->dgaReqType = X_XDGACloseFramebuffer;
280    req->screen = screen;
281    UnlockDisplay(dpy);
282    SyncHandle();
283}
284
285
286
287SDL_NAME(XDGAMode)* SDL_NAME(XDGAQueryModes)(
288    Display *dpy,
289    int screen,
290    int *num
291){
292    XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
293    xXDGAQueryModesReply rep;
294    xXDGAQueryModesReq *req;
295    SDL_NAME(XDGAMode) *modes = NULL;
296
297    *num = 0;
298
299    XDGACheckExtension (dpy, dinfo, NULL);
300
301    LockDisplay(dpy);
302    GetReq(XDGAQueryModes, req);
303    req->reqType = dinfo->codes->major_opcode;
304    req->dgaReqType = X_XDGAQueryModes;
305    req->screen = screen;
306
307    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
308	if(rep.length) {
309	   xXDGAModeInfo info;
310	   int i, size;
311	   char *offset;
312
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 */
317
318
319	   if(modes) {
320	      for(i = 0; i < rep.number; i++) {
321		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
322
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;
348
349		_XRead(dpy, offset, info.name_size);
350		modes[i].name = offset;
351		offset += info.name_size;
352	      }
353	      *num = rep.number;
354	   } else
355		_XEatData(dpy, rep.length << 2);
356	}
357    }
358
359    UnlockDisplay(dpy);
360    SyncHandle();
361
362    return modes;
363}
364
365
366SDL_NAME(XDGADevice) *
367SDL_NAME(XDGASetMode)(
368    Display	*dpy,
369    int		screen,
370    int		mode
371){
372    XExtDisplayInfo *dinfo = SDL_NAME(xdga_find_display) (dpy);
373    xXDGASetModeReply rep;
374    xXDGASetModeReq *req;
375    SDL_NAME(XDGADevice) *dev = NULL;
376    Pixmap pid;
377
378    XDGACheckExtension (dpy, dinfo, NULL);
379
380    LockDisplay(dpy);
381    GetReq(XDGASetMode, req);
382    req->reqType = dinfo->codes->major_opcode;
383    req->dgaReqType = X_XDGASetMode;
384    req->screen = screen;
385    req->mode = mode;
386    req->pid = pid = XAllocID(dpy);
387
388    if (_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
389	if(rep.length) {
390	   xXDGAModeInfo info;
391	   int size;
392
393	   size = rep.length << 2;
394	   size -= sz_xXDGAModeInfo; /* get text size */
395
396	   dev = (SDL_NAME(XDGADevice)*)Xmalloc(sizeof(SDL_NAME(XDGADevice)) + size);
397
398	   if(dev) {
399		_XRead(dpy, (char*)(&info), sz_xXDGAModeInfo);
400
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;
426
427		dev->mode.name = (char*)(&dev[1]);
428		_XRead(dpy, dev->mode.name, info.name_size);
429
430		dev->pixmap = (rep.flags & XDGAPixmap) ? pid : 0;
431		dev->data = SDL_NAME(XDGAGetMappedMemory)(screen);
432
433		if(dev->data)
434		    dev->data += rep.offset;
435	   }
436	   /* not sure what to do if the allocation fails */
437	}
438    }
439
440    UnlockDisplay(dpy);
441    SyncHandle();
442
443    return dev;
444}
445
446
447void SDL_NAME(XDGASetViewport)(
448    Display	*dpy,
449    int		screen,
450    int		x,
451    int		y,
452    int		flags
453){
454    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
455    xXDGASetViewportReq *req;
456
457    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
458
459    LockDisplay(dpy);
460    GetReq(XDGASetViewport, req);
461    req->reqType = info->codes->major_opcode;
462    req->dgaReqType = X_XDGASetViewport;
463    req->screen = screen;
464    req->x = x;
465    req->y = y;
466    req->flags = flags;
467    UnlockDisplay(dpy);
468    SyncHandle();
469}
470
471
472void SDL_NAME(XDGAInstallColormap)(
473    Display	*dpy,
474    int		screen,
475    Colormap	cmap
476){
477    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
478    xXDGAInstallColormapReq *req;
479
480    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
481
482    LockDisplay(dpy);
483    GetReq(XDGAInstallColormap, req);
484    req->reqType = info->codes->major_opcode;
485    req->dgaReqType = X_XDGAInstallColormap;
486    req->screen = screen;
487    req->cmap = cmap;
488    UnlockDisplay(dpy);
489    SyncHandle();
490}
491
492void SDL_NAME(XDGASelectInput)(
493    Display	*dpy,
494    int		screen,
495    long	mask
496){
497    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
498    xXDGASelectInputReq *req;
499
500    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
501
502    LockDisplay(dpy);
503    GetReq(XDGASelectInput, req);
504    req->reqType = info->codes->major_opcode;
505    req->dgaReqType = X_XDGASelectInput;
506    req->screen = screen;
507    req->mask = mask;
508    UnlockDisplay(dpy);
509    SyncHandle();
510}
511
512void SDL_NAME(XDGAFillRectangle)(
513    Display	*dpy,
514    int		screen,
515    int		x,
516    int		y,
517    unsigned int	width,
518    unsigned int	height,
519    unsigned long	color
520){
521    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
522    xXDGAFillRectangleReq *req;
523
524    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
525
526    LockDisplay(dpy);
527    GetReq(XDGAFillRectangle, req);
528    req->reqType = info->codes->major_opcode;
529    req->dgaReqType = X_XDGAFillRectangle;
530    req->screen = screen;
531    req->x = x;
532    req->y = y;
533    req->width = width;
534    req->height = height;
535    req->color = color;
536    UnlockDisplay(dpy);
537    SyncHandle();
538}
539
540void SDL_NAME(XDGACopyArea)(
541    Display	*dpy,
542    int		screen,
543    int		srcx,
544    int		srcy,
545    unsigned int	width,
546    unsigned int	height,
547    int		dstx,
548    int		dsty
549){
550    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
551    xXDGACopyAreaReq *req;
552
553    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
554
555    LockDisplay(dpy);
556    GetReq(XDGACopyArea, req);
557    req->reqType = info->codes->major_opcode;
558    req->dgaReqType = X_XDGACopyArea;
559    req->screen = screen;
560    req->srcx = srcx;
561    req->srcy = srcy;
562    req->width = width;
563    req->height = height;
564    req->dstx = dstx;
565    req->dsty = dsty;
566    UnlockDisplay(dpy);
567    SyncHandle();
568}
569
570void SDL_NAME(XDGACopyTransparentArea)(
571    Display	*dpy,
572    int		screen,
573    int		srcx,
574    int		srcy,
575    unsigned int	width,
576    unsigned int	height,
577    int		dstx,
578    int		dsty,
579    unsigned long key
580){
581    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
582    xXDGACopyTransparentAreaReq *req;
583
584    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
585
586    LockDisplay(dpy);
587    GetReq(XDGACopyTransparentArea, req);
588    req->reqType = info->codes->major_opcode;
589    req->dgaReqType = X_XDGACopyTransparentArea;
590    req->screen = screen;
591    req->srcx = srcx;
592    req->srcy = srcy;
593    req->width = width;
594    req->height = height;
595    req->dstx = dstx;
596    req->dsty = dsty;
597    req->key = key;
598    UnlockDisplay(dpy);
599    SyncHandle();
600}
601
602
603int SDL_NAME(XDGAGetViewportStatus)(
604    Display *dpy,
605    int screen
606){
607    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
608    xXDGAGetViewportStatusReply rep;
609    xXDGAGetViewportStatusReq *req;
610    int status = 0;
611
612    XDGACheckExtension (dpy, info, 0);
613
614    LockDisplay(dpy);
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))
620	status = rep.status;
621    UnlockDisplay(dpy);
622    SyncHandle();
623    return status;
624}
625
626void SDL_NAME(XDGASync)(
627    Display *dpy,
628    int screen
629){
630    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
631    xXDGASyncReply rep;
632    xXDGASyncReq *req;
633
634    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
635
636    LockDisplay(dpy);
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);
642    UnlockDisplay(dpy);
643    SyncHandle();
644}
645
646
647void SDL_NAME(XDGAChangePixmapMode)(
648    Display *dpy,
649    int screen,
650    int *x,
651    int *y,
652    int mode
653){
654    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
655    xXDGAChangePixmapModeReq *req;
656    xXDGAChangePixmapModeReply rep;
657
658    XextSimpleCheckExtension (dpy, info, SDL_NAME(xdga_extension_name));
659
660    LockDisplay(dpy);
661    GetReq(XDGAChangePixmapMode, req);
662    req->reqType = info->codes->major_opcode;
663    req->dgaReqType = X_XDGAChangePixmapMode;
664    req->screen = screen;
665    req->x = *x;
666    req->y = *y;
667    req->flags = mode;
668    _XReply(dpy, (xReply *)&rep, 0, xFalse);
669    *x = rep.x;
670    *y = rep.y;
671    UnlockDisplay(dpy);
672    SyncHandle();
673}
674
675Colormap SDL_NAME(XDGACreateColormap)(
676    Display *dpy,
677    int screen,
678    SDL_NAME(XDGADevice) *dev,
679    int	alloc
680){
681    XExtDisplayInfo *info = SDL_NAME(xdga_find_display) (dpy);
682    xXDGACreateColormapReq *req;
683    Colormap cid;
684
685    XDGACheckExtension (dpy, info, -1);
686
687    LockDisplay(dpy);
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;
693    req->alloc = alloc;
694    cid = req->id = XAllocID(dpy);
695    UnlockDisplay(dpy);
696    SyncHandle();
697
698    return cid;
699}
700
701
702void SDL_NAME(XDGAKeyEventToXKeyEvent)(
703    SDL_NAME(XDGAKeyEvent)* dk,
704    XKeyEvent* xk
705){
706    xk->type = dk->type;
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;
713    xk->time = dk->time;
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;
718}
719
720#include <X11/Xmd.h>
721#include <stdlib.h>
722#include <stdio.h>
723#include <fcntl.h>
724#if defined(ISC)
725# define HAS_SVR3_MMAP
726# include <sys/types.h>
727# include <errno.h>
728
729# include <sys/at_ansi.h>
730# include <sys/kd.h>
731
732# include <sys/sysmacros.h>
733# include <sys/immu.h>
734# include <sys/region.h>
735
736# include <sys/mmap.h>
737#else
738# if !defined(Lynx)
739#  if !defined(__EMX__)
740#   include <sys/mman.h>
741#  endif
742# else
743#  include <sys/types.h>
744#  include <errno.h>
745#  include <smem.h>
746# endif
747#endif
748#include <sys/wait.h>
749#include <signal.h>
750#include <unistd.h>
751
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"
756#else
757#define DEV_MEM "/dev/mem"
758#endif
759
760
761
762typedef struct _DGAMapRec{
763  unsigned char *physical;
764  unsigned char *virtual;
765  CARD32 size;
766  int fd;
767  int screen;
768  struct _DGAMapRec *next;
769} DGAMapRec, *DGAMapPtr;
770
771static Bool
772DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr);
773static void DGAUnmapPhysical(DGAMapPtr);
774
775static DGAMapPtr _Maps = NULL;
776
777
778unsigned char*
779SDL_NAME(XDGAGetMappedMemory)(int screen)
780{
781    DGAMapPtr pMap = _Maps;
782    unsigned char *pntr = NULL;
783
784    while(pMap != NULL) {
785	if(pMap->screen == screen) {
786	    pntr = pMap->virtual;
787	    break;
788	}
789	pMap = pMap->next;
790    }
791
792    return pntr;
793}
794
795Bool
796SDL_NAME(XDGAMapFramebuffer)(
797   int screen,
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 */
803){
804   DGAMapPtr pMap = _Maps;
805   Bool result;
806
807   /* is it already mapped ? */
808   while(pMap != NULL) {
809     if(pMap->screen == screen)
810	return True;
811     pMap = pMap->next;
812   }
813
814   if(extra & XDGANeedRoot) {
815    /* we should probably check if we have root permissions and
816       return False here */
817
818   }
819
820   pMap = (DGAMapPtr)Xmalloc(sizeof(DGAMapRec));
821
822   result = DGAMapPhysical(screen, name, base, size, offset, extra, pMap);
823
824   if(result) {
825      pMap->next = _Maps;
826      _Maps = pMap;
827   } else
828      Xfree(pMap);
829
830   return result;
831}
832
833void
834SDL_NAME(XDGAUnmapFramebuffer)(int screen)
835{
836   DGAMapPtr pMap = _Maps;
837   DGAMapPtr pPrev = NULL;
838
839   /* is it already mapped */
840    while(pMap != NULL) {
841	if(pMap->screen == screen)
842	    break;
843	pPrev = pMap;
844	pMap = pMap->next;
845    }
846
847    if(!pMap)
848	return;
849
850    DGAUnmapPhysical(pMap);
851
852    if(!pPrev)
853	_Maps = pMap->next;
854    else
855	pPrev->next = pMap->next;
856
857    Xfree(pMap);
858}
859
860
861static Bool
862DGAMapPhysical(
863   int screen,
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 */
869   DGAMapPtr pMap
870) {
871#if defined(ISC) && defined(HAS_SVR3_MMAP)
872    struct kd_memloc mloc;
873#elif defined(__EMX__)
874    APIRET rc;
875    ULONG action;
876    HFILE hfd;
877#endif
878
879    base += offset;
880
881    pMap->screen = screen;
882    pMap->physical = base;
883    pMap->size = size;
884
885#if defined(ISC) && defined(HAS_SVR3_MMAP)
886    if ((pMap->fd = open("/dev/mmap", O_RDWR)) < 0)
887	return False;
888    mloc.vaddr = (char *)0;
889    mloc.physaddr = (char *)base;
890    mloc.length = size;
891    mloc.ioflg=1;
892
893    if ((pMap->virtual = (void *)ioctl(pMap->fd, MAP, &mloc)) == (void *)-1)
894	return False;
895#elif defined (__EMX__)
896    /*
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
900     */
901
902    rc = DosOpen("/dev/pmap$", &hfd, &action, 0, FILE_NORMAL, FILE_OPEN,
903		 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, (PEAOP2)NULL);
904    if (rc != 0)
905	return False;
906    {
907	struct map_ioctl {
908		union {
909			ULONG phys;
910			void* user;
911		} a;
912		ULONG size;
913	} pmap,dmap;
914	ULONG plen,dlen;
915#define XFREE86_PMAP	0x76
916#define PMAP_MAP	0x44
917
918	pmap.a.phys = base;
919	pmap.size = size;
920	rc = DosDevIOCtl(hfd, XFREE86_PMAP, PMAP_MAP,
921			 (PULONG)&pmap, sizeof(pmap), &plen,
922			 (PULONG)&dmap, sizeof(dmap), &dlen);
923	if (rc == 0) {
924		pMap->virtual = dmap.a.user;
925	}
926   }
927   if (rc != 0)
928	return False;
929#elif defined (Lynx)
930    pMap->virtual = smem_create("XF86DGA", (char*)base, size, SM_READ|SM_WRITE);
931#else
932#ifndef MAP_FILE
933#define MAP_FILE 0
934#endif
935    if (!name)
936	    name = DEV_MEM;
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;
942
943        if ((pMap->fd = open("/dev/fb0", O_RDWR)) < 0) {
944            return False;
945        }
946        /* The useable framebuffer console memory may not be the whole
947           framebuffer that X has access to. :-(
948         */
949        if ( ioctl(pMap->fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
950            close(pMap->fd);
951            return False;
952        }
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)))
956         */
957        base = 0;
958        size = pMap->size = finfo.smem_len;
959    }
960#else
961	return False;
962#endif
963    pMap->virtual = mmap(NULL, size, PROT_READ | PROT_WRITE,
964			MAP_FILE | MAP_SHARED, pMap->fd, (off_t)((size_t)base));
965    if (pMap->virtual == (void *)-1)
966	return False;
967#endif
968
969#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
970	&& !defined(__EMX__)
971    mprotect(pMap->virtual, size, PROT_READ | PROT_WRITE);
972#endif
973
974    return True;
975}
976
977
978
979static void
980DGAUnmapPhysical(DGAMapPtr pMap)
981{
982#if !defined(ISC) && !defined(HAS_SVR3_MMAP) && !defined(Lynx) \
983	&& !defined(__EMX__)
984    mprotect(pMap->virtual,pMap->size, PROT_READ);
985#elif defined(Lynx)
986	/* XXX this doesn't allow enable after disable */
987    smem_create(NULL, pMap->virtual, pMap->size, SM_DETACH);
988    smem_remove("XF86DGA");
989#endif
990
991
992   /* We need to unmap and close too !!!!!!!!!!*/
993}
994