e14743d1 |
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 | } |