SDL-1.2.14
[sdl_omap.git] / src / video / Xext / Xxf86dga / XF86DGA2.c
1 /* $XFree86: xc/lib/Xxf86dga/XF86DGA2.c,v 1.18 2001/08/17 13:27:51 dawes Exp $ */
2 /*
3
4 Copyright (c) 1995  Jon Tombs
5 Copyright (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
40 char *SDL_NAME(xdga_extension_name) = XF86DGANAME;
41
42 static XExtensionInfo _xdga_info_data;
43 static XExtensionInfo *xdga_info = &_xdga_info_data;
44
45  
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);
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
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);
62
63 static 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
77 static XEXT_GENERATE_CLOSE_DISPLAY (xdga_close_display, xdga_info)
78
79
80 XEXT_GENERATE_FIND_DISPLAY (SDL_NAME(xdga_find_display), xdga_info, 
81                                    "XFree86-DGA", 
82                                    &xdga_extension_hooks, 
83                                    0, NULL)
84
85
86 static Status
87 xdga_event_to_wire(
88   Display *dpy,
89   XEvent *event,
90   xEvent *wire_ev
91 ){
92     return True;
93 }
94
95 static Bool
96 xdga_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
149 Bool 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
166 Bool 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
206 Bool 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
225 Bool 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
265 void 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
287 SDL_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
366 SDL_NAME(XDGADevice) * 
367 SDL_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
447 void 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
472 void 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
492 void 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
512 void 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
540 void 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
570 void 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
603 int 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
626 void 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
647 void 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
675 Colormap 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
702 void 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
762 typedef 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
771 static Bool
772 DGAMapPhysical(int, char*, unsigned char*, CARD32, CARD32, CARD32, DGAMapPtr); 
773 static void DGAUnmapPhysical(DGAMapPtr);
774
775 static DGAMapPtr _Maps = NULL;
776
777
778 unsigned char*
779 SDL_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
795 Bool
796 SDL_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
833 void
834 SDL_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
861 static Bool
862 DGAMapPhysical(
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)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
979 static void
980 DGAUnmapPhysical(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 }