1 /*
2 * Copyright (c) 1995 Jon Tombs
3 * Copyright (c) 1995, 1996, 1999 XFree86 Inc
4 * Copyright (c) 1999 - The XFree86 Project Inc.
5 *
6 * Written by Mark Vojkovich
7 */
10 #ifdef HAVE_XORG_CONFIG_H
11 #include <xorg-config.h>
12 #endif
14 #include <X11/X.h>
15 #include <X11/Xproto.h>
16 #include "misc.h"
17 #include "dixstruct.h"
18 #include "dixevents.h"
19 #include "pixmapstr.h"
20 #include "extnsionst.h"
21 #include "colormapst.h"
22 #include "cursorstr.h"
23 #include "scrnintstr.h"
24 #include "servermd.h"
25 #include <X11/extensions/xf86dgaproto.h>
26 #include "swaprep.h"
27 #include "dgaproc.h"
28 #include "protocol-versions.h"
30 #include <string.h>
32 #include "modinit.h"
34 #define DGA_PROTOCOL_OLD_SUPPORT 1
37 static void XDGAResetProc(ExtensionEntry *extEntry);
39 static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
41 unsigned char DGAReqCode = 0;
42 int DGAErrorBase;
43 int DGAEventBase;
45 static DevPrivateKeyRec DGAScreenPrivateKeyRec;
46 #define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
47 #define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
48 static DevPrivateKeyRec DGAClientPrivateKeyRec;
49 #define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
50 static int DGACallbackRefCount = 0;
52 /* This holds the client's version information */
53 typedef struct {
54 int major;
55 int minor;
56 } DGAPrivRec, *DGAPrivPtr;
58 #define DGA_GETCLIENT(idx) ((ClientPtr) \
59 dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
60 #define DGA_SETCLIENT(idx,p) \
61 dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
63 #define DGA_GETPRIV(c) ((DGAPrivPtr) \
64 dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
65 #define DGA_SETPRIV(c,p) \
66 dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
69 static void
70 XDGAResetProc (ExtensionEntry *extEntry)
71 {
72 DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL);
73 DGACallbackRefCount = 0;
74 }
77 static int
78 ProcXDGAQueryVersion(ClientPtr client)
79 {
80 xXDGAQueryVersionReply rep;
82 REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
83 rep.type = X_Reply;
84 rep.length = 0;
85 rep.sequenceNumber = client->sequence;
86 rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
87 rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
89 WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep);
90 return Success;
91 }
94 static int
95 ProcXDGAOpenFramebuffer(ClientPtr client)
96 {
97 REQUEST(xXDGAOpenFramebufferReq);
98 xXDGAOpenFramebufferReply rep;
99 char *deviceName;
100 int nameSize;
102 if (stuff->screen >= screenInfo.numScreens)
103 return BadValue;
105 if (!DGAAvailable(stuff->screen))
106 return DGAErrorBase + XF86DGANoDirectVideoMode;
108 REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
109 rep.type = X_Reply;
110 rep.length = 0;
111 rep.sequenceNumber = client->sequence;
113 if(!DGAOpenFramebuffer(stuff->screen, &deviceName,
114 (unsigned char**)(&rep.mem1),
115 (int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra))
116 {
117 return BadAlloc;
118 }
120 nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
121 rep.length = bytes_to_int32(nameSize);
123 WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep);
124 if(rep.length)
125 WriteToClient(client, nameSize, deviceName);
127 return Success;
128 }
131 static int
132 ProcXDGACloseFramebuffer(ClientPtr client)
133 {
134 REQUEST(xXDGACloseFramebufferReq);
136 if (stuff->screen >= screenInfo.numScreens)
137 return BadValue;
139 if (!DGAAvailable(stuff->screen))
140 return DGAErrorBase + XF86DGANoDirectVideoMode;
142 REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
144 DGACloseFramebuffer(stuff->screen);
146 return Success;
147 }
149 static int
150 ProcXDGAQueryModes(ClientPtr client)
151 {
152 int i, num, size;
153 REQUEST(xXDGAQueryModesReq);
154 xXDGAQueryModesReply rep;
155 xXDGAModeInfo info;
156 XDGAModePtr mode;
158 if (stuff->screen >= screenInfo.numScreens)
159 return BadValue;
161 REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
162 rep.type = X_Reply;
163 rep.length = 0;
164 rep.number = 0;
165 rep.sequenceNumber = client->sequence;
167 if (!DGAAvailable(stuff->screen)) {
168 rep.number = 0;
169 rep.length = 0;
170 WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
171 return Success;
172 }
174 if(!(num = DGAGetModes(stuff->screen))) {
175 WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
176 return Success;
177 }
179 if(!(mode = (XDGAModePtr)malloc(num * sizeof(XDGAModeRec))))
180 return BadAlloc;
182 for(i = 0; i < num; i++)
183 DGAGetModeInfo(stuff->screen, mode + i, i + 1);
185 size = num * sz_xXDGAModeInfo;
186 for(i = 0; i < num; i++)
187 size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
189 rep.number = num;
190 rep.length = bytes_to_int32(size);
192 WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
194 for(i = 0; i < num; i++) {
195 size = strlen(mode[i].name) + 1;
197 info.byte_order = mode[i].byteOrder;
198 info.depth = mode[i].depth;
199 info.num = mode[i].num;
200 info.bpp = mode[i].bitsPerPixel;
201 info.name_size = (size + 3) & ~3L;
202 info.vsync_num = mode[i].VSync_num;
203 info.vsync_den = mode[i].VSync_den;
204 info.flags = mode[i].flags;
205 info.image_width = mode[i].imageWidth;
206 info.image_height = mode[i].imageHeight;
207 info.pixmap_width = mode[i].pixmapWidth;
208 info.pixmap_height = mode[i].pixmapHeight;
209 info.bytes_per_scanline = mode[i].bytesPerScanline;
210 info.red_mask = mode[i].red_mask;
211 info.green_mask = mode[i].green_mask;
212 info.blue_mask = mode[i].blue_mask;
213 info.visual_class = mode[i].visualClass;
214 info.viewport_width = mode[i].viewportWidth;
215 info.viewport_height = mode[i].viewportHeight;
216 info.viewport_xstep = mode[i].xViewportStep;
217 info.viewport_ystep = mode[i].yViewportStep;
218 info.viewport_xmax = mode[i].maxViewportX;
219 info.viewport_ymax = mode[i].maxViewportY;
220 info.viewport_flags = mode[i].viewportFlags;
221 info.reserved1 = mode[i].reserved1;
222 info.reserved2 = mode[i].reserved2;
224 WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
225 WriteToClient(client, size, mode[i].name);
226 }
228 free(mode);
230 return Success;
231 }
234 static void
235 DGAClientStateChange (
236 CallbackListPtr* pcbl,
237 pointer nulldata,
238 pointer calldata
239 ){
240 NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
241 ClientPtr client = NULL;
242 int i;
244 for(i = 0; i < screenInfo.numScreens; i++) {
245 if(DGA_GETCLIENT(i) == pci->client) {
246 client = pci->client;
247 break;
248 }
249 }
251 if(client &&
252 ((client->clientState == ClientStateGone) ||
253 (client->clientState == ClientStateRetained))) {
254 XDGAModeRec mode;
255 PixmapPtr pPix;
257 DGA_SETCLIENT(i, NULL);
258 DGASelectInput(i, NULL, 0);
259 DGASetMode(i, 0, &mode, &pPix);
261 if(--DGACallbackRefCount == 0)
262 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
263 }
264 }
266 static int
267 ProcXDGASetMode(ClientPtr client)
268 {
269 REQUEST(xXDGASetModeReq);
270 xXDGASetModeReply rep;
271 XDGAModeRec mode;
272 xXDGAModeInfo info;
273 PixmapPtr pPix;
274 ClientPtr owner;
275 int size;
277 if (stuff->screen >= screenInfo.numScreens)
278 return BadValue;
279 owner = DGA_GETCLIENT(stuff->screen);
281 REQUEST_SIZE_MATCH(xXDGASetModeReq);
282 rep.type = X_Reply;
283 rep.length = 0;
284 rep.offset = 0;
285 rep.flags = 0;
286 rep.sequenceNumber = client->sequence;
288 if (!DGAAvailable(stuff->screen))
289 return DGAErrorBase + XF86DGANoDirectVideoMode;
291 if(owner && owner != client)
292 return DGAErrorBase + XF86DGANoDirectVideoMode;
294 if(!stuff->mode) {
295 if(owner) {
296 if(--DGACallbackRefCount == 0)
297 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
298 }
299 DGA_SETCLIENT(stuff->screen, NULL);
300 DGASelectInput(stuff->screen, NULL, 0);
301 DGASetMode(stuff->screen, 0, &mode, &pPix);
302 WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
303 return Success;
304 }
306 if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
307 return BadValue;
309 if(!owner) {
310 if(DGACallbackRefCount++ == 0)
311 AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
312 }
314 DGA_SETCLIENT(stuff->screen, client);
316 if(pPix) {
317 if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
318 pPix->drawable.id = (int)stuff->pid;
319 rep.flags = DGA_PIXMAP_AVAILABLE;
320 }
321 }
323 size = strlen(mode.name) + 1;
325 info.byte_order = mode.byteOrder;
326 info.depth = mode.depth;
327 info.num = mode.num;
328 info.bpp = mode.bitsPerPixel;
329 info.name_size = (size + 3) & ~3L;
330 info.vsync_num = mode.VSync_num;
331 info.vsync_den = mode.VSync_den;
332 info.flags = mode.flags;
333 info.image_width = mode.imageWidth;
334 info.image_height = mode.imageHeight;
335 info.pixmap_width = mode.pixmapWidth;
336 info.pixmap_height = mode.pixmapHeight;
337 info.bytes_per_scanline = mode.bytesPerScanline;
338 info.red_mask = mode.red_mask;
339 info.green_mask = mode.green_mask;
340 info.blue_mask = mode.blue_mask;
341 info.visual_class = mode.visualClass;
342 info.viewport_width = mode.viewportWidth;
343 info.viewport_height = mode.viewportHeight;
344 info.viewport_xstep = mode.xViewportStep;
345 info.viewport_ystep = mode.yViewportStep;
346 info.viewport_xmax = mode.maxViewportX;
347 info.viewport_ymax = mode.maxViewportY;
348 info.viewport_flags = mode.viewportFlags;
349 info.reserved1 = mode.reserved1;
350 info.reserved2 = mode.reserved2;
352 rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
354 WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
355 WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
356 WriteToClient(client, size, mode.name);
358 return Success;
359 }
361 static int
362 ProcXDGASetViewport(ClientPtr client)
363 {
364 REQUEST(xXDGASetViewportReq);
366 if (stuff->screen >= screenInfo.numScreens)
367 return BadValue;
369 if(DGA_GETCLIENT(stuff->screen) != client)
370 return DGAErrorBase + XF86DGADirectNotActivated;
372 REQUEST_SIZE_MATCH(xXDGASetViewportReq);
374 DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
376 return Success;
377 }
379 static int
380 ProcXDGAInstallColormap(ClientPtr client)
381 {
382 ColormapPtr cmap;
383 int rc;
384 REQUEST(xXDGAInstallColormapReq);
386 if (stuff->screen >= screenInfo.numScreens)
387 return BadValue;
389 if(DGA_GETCLIENT(stuff->screen) != client)
390 return DGAErrorBase + XF86DGADirectNotActivated;
392 REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
394 rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
395 client, DixInstallAccess);
396 if (rc != Success)
397 return rc;
398 DGAInstallCmap(cmap);
399 return Success;
400 }
403 static int
404 ProcXDGASelectInput(ClientPtr client)
405 {
406 REQUEST(xXDGASelectInputReq);
408 if (stuff->screen >= screenInfo.numScreens)
409 return BadValue;
411 if(DGA_GETCLIENT(stuff->screen) != client)
412 return DGAErrorBase + XF86DGADirectNotActivated;
414 REQUEST_SIZE_MATCH(xXDGASelectInputReq);
416 if(DGA_GETCLIENT(stuff->screen) == client)
417 DGASelectInput(stuff->screen, client, stuff->mask);
419 return Success;
420 }
423 static int
424 ProcXDGAFillRectangle(ClientPtr client)
425 {
426 REQUEST(xXDGAFillRectangleReq);
428 if (stuff->screen >= screenInfo.numScreens)
429 return BadValue;
431 if(DGA_GETCLIENT(stuff->screen) != client)
432 return DGAErrorBase + XF86DGADirectNotActivated;
434 REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
436 if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
437 stuff->width, stuff->height, stuff->color))
438 return BadMatch;
440 return Success;
441 }
443 static int
444 ProcXDGACopyArea(ClientPtr client)
445 {
446 REQUEST(xXDGACopyAreaReq);
448 if (stuff->screen >= screenInfo.numScreens)
449 return BadValue;
451 if(DGA_GETCLIENT(stuff->screen) != client)
452 return DGAErrorBase + XF86DGADirectNotActivated;
454 REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
456 if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
457 stuff->width, stuff->height, stuff->dstx, stuff->dsty))
458 return BadMatch;
460 return Success;
461 }
464 static int
465 ProcXDGACopyTransparentArea(ClientPtr client)
466 {
467 REQUEST(xXDGACopyTransparentAreaReq);
469 if (stuff->screen >= screenInfo.numScreens)
470 return BadValue;
472 if(DGA_GETCLIENT(stuff->screen) != client)
473 return DGAErrorBase + XF86DGADirectNotActivated;
475 REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
477 if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
478 stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key))
479 return BadMatch;
481 return Success;
482 }
485 static int
486 ProcXDGAGetViewportStatus(ClientPtr client)
487 {
488 REQUEST(xXDGAGetViewportStatusReq);
489 xXDGAGetViewportStatusReply rep;
491 if (stuff->screen >= screenInfo.numScreens)
492 return BadValue;
494 if(DGA_GETCLIENT(stuff->screen) != client)
495 return DGAErrorBase + XF86DGADirectNotActivated;
497 REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
498 rep.type = X_Reply;
499 rep.length = 0;
500 rep.sequenceNumber = client->sequence;
502 rep.status = DGAGetViewportStatus(stuff->screen);
504 WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep);
505 return Success;
506 }
508 static int
509 ProcXDGASync(ClientPtr client)
510 {
511 REQUEST(xXDGASyncReq);
512 xXDGASyncReply rep;
514 if (stuff->screen >= screenInfo.numScreens)
515 return BadValue;
517 if(DGA_GETCLIENT(stuff->screen) != client)
518 return DGAErrorBase + XF86DGADirectNotActivated;
520 REQUEST_SIZE_MATCH(xXDGASyncReq);
521 rep.type = X_Reply;
522 rep.length = 0;
523 rep.sequenceNumber = client->sequence;
525 DGASync(stuff->screen);
527 WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep);
528 return Success;
529 }
531 static int
532 ProcXDGASetClientVersion(ClientPtr client)
533 {
534 REQUEST(xXDGASetClientVersionReq);
536 DGAPrivPtr pPriv;
538 REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
539 if ((pPriv = DGA_GETPRIV(client)) == NULL) {
540 pPriv = malloc(sizeof(DGAPrivRec));
541 /* XXX Need to look into freeing this */
542 if (!pPriv)
543 return BadAlloc;
544 DGA_SETPRIV(client, pPriv);
545 }
546 pPriv->major = stuff->major;
547 pPriv->minor = stuff->minor;
549 return Success;
550 }
552 static int
553 ProcXDGAChangePixmapMode(ClientPtr client)
554 {
555 REQUEST(xXDGAChangePixmapModeReq);
556 xXDGAChangePixmapModeReply rep;
557 int x, y;
559 if (stuff->screen >= screenInfo.numScreens)
560 return BadValue;
562 if(DGA_GETCLIENT(stuff->screen) != client)
563 return DGAErrorBase + XF86DGADirectNotActivated;
565 REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
566 rep.type = X_Reply;
567 rep.length = 0;
568 rep.sequenceNumber = client->sequence;
570 x = stuff->x;
571 y = stuff->y;
573 if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
574 return BadMatch;
576 rep.x = x;
577 rep.y = y;
578 WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep);
580 return Success;
581 }
584 static int
585 ProcXDGACreateColormap(ClientPtr client)
586 {
587 REQUEST(xXDGACreateColormapReq);
588 int result;
590 if (stuff->screen >= screenInfo.numScreens)
591 return BadValue;
593 if(DGA_GETCLIENT(stuff->screen) != client)
594 return DGAErrorBase + XF86DGADirectNotActivated;
596 REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
598 if(!stuff->mode)
599 return BadValue;
601 result = DGACreateColormap(stuff->screen, client, stuff->id,
602 stuff->mode, stuff->alloc);
603 if(result != Success)
604 return result;
606 return Success;
607 }
609 /*
610 *
611 * Support for the old DGA protocol, used to live in xf86dga.c
612 *
613 */
615 #ifdef DGA_PROTOCOL_OLD_SUPPORT
619 static int
620 ProcXF86DGAGetVideoLL(ClientPtr client)
621 {
622 REQUEST(xXF86DGAGetVideoLLReq);
623 xXF86DGAGetVideoLLReply rep;
624 XDGAModeRec mode;
625 int num, offset, flags;
626 char *name;
628 if (stuff->screen >= screenInfo.numScreens)
629 return BadValue;
631 REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
632 rep.type = X_Reply;
633 rep.length = 0;
634 rep.sequenceNumber = client->sequence;
636 if(!DGAAvailable(stuff->screen))
637 return DGAErrorBase + XF86DGANoDirectVideoMode;
639 if(!(num = DGAGetOldDGAMode(stuff->screen)))
640 return DGAErrorBase + XF86DGANoDirectVideoMode;
642 /* get the parameters for the mode that best matches */
643 DGAGetModeInfo(stuff->screen, &mode, num);
645 if(!DGAOpenFramebuffer(stuff->screen, &name,
646 (unsigned char**)(&rep.offset),
647 (int*)(&rep.bank_size), &offset, &flags))
648 return BadAlloc;
650 rep.offset += mode.offset;
651 rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
652 rep.ram_size = rep.bank_size >> 10;
654 WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep);
655 return Success;
656 }
658 static int
659 ProcXF86DGADirectVideo(ClientPtr client)
660 {
661 int num;
662 PixmapPtr pix;
663 XDGAModeRec mode;
664 ClientPtr owner;
665 REQUEST(xXF86DGADirectVideoReq);
667 if (stuff->screen >= screenInfo.numScreens)
668 return BadValue;
669 REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
671 if (!DGAAvailable(stuff->screen))
672 return DGAErrorBase + XF86DGANoDirectVideoMode;
674 owner = DGA_GETCLIENT(stuff->screen);
676 if (owner && owner != client)
677 return DGAErrorBase + XF86DGANoDirectVideoMode;
679 if (stuff->enable & XF86DGADirectGraphics) {
680 if(!(num = DGAGetOldDGAMode(stuff->screen)))
681 return DGAErrorBase + XF86DGANoDirectVideoMode;
682 } else
683 num = 0;
685 if(Success != DGASetMode(stuff->screen, num, &mode, &pix))
686 return DGAErrorBase + XF86DGAScreenNotActive;
688 DGASetInputMode (stuff->screen,
689 (stuff->enable & XF86DGADirectKeyb) != 0,
690 (stuff->enable & XF86DGADirectMouse) != 0);
692 /* We need to track the client and attach the teardown callback */
693 if (stuff->enable &
694 (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
695 if (!owner) {
696 if (DGACallbackRefCount++ == 0)
697 AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
698 }
700 DGA_SETCLIENT(stuff->screen, client);
701 } else {
702 if (owner) {
703 if (--DGACallbackRefCount == 0)
704 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
705 }
707 DGA_SETCLIENT(stuff->screen, NULL);
708 }
710 return Success;
711 }
713 static int
714 ProcXF86DGAGetViewPortSize(ClientPtr client)
715 {
716 int num;
717 XDGAModeRec mode;
718 REQUEST(xXF86DGAGetViewPortSizeReq);
719 xXF86DGAGetViewPortSizeReply rep;
721 if (stuff->screen >= screenInfo.numScreens)
722 return BadValue;
724 REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
725 rep.type = X_Reply;
726 rep.length = 0;
727 rep.sequenceNumber = client->sequence;
729 if (!DGAAvailable(stuff->screen))
730 return DGAErrorBase + XF86DGANoDirectVideoMode;
732 if(!(num = DGAGetOldDGAMode(stuff->screen)))
733 return DGAErrorBase + XF86DGANoDirectVideoMode;
735 DGAGetModeInfo(stuff->screen, &mode, num);
737 rep.width = mode.viewportWidth;
738 rep.height = mode.viewportHeight;
740 WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep);
741 return Success;
742 }
744 static int
745 ProcXF86DGASetViewPort(ClientPtr client)
746 {
747 REQUEST(xXF86DGASetViewPortReq);
749 if (stuff->screen >= screenInfo.numScreens)
750 return BadValue;
752 if (DGA_GETCLIENT(stuff->screen) != client)
753 return DGAErrorBase + XF86DGADirectNotActivated;
755 REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
757 if (!DGAAvailable(stuff->screen))
758 return DGAErrorBase + XF86DGANoDirectVideoMode;
760 if (!DGAActive(stuff->screen))
761 return DGAErrorBase + XF86DGADirectNotActivated;
763 if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
764 != Success)
765 return DGAErrorBase + XF86DGADirectNotActivated;
767 return Success;
768 }
770 static int
771 ProcXF86DGAGetVidPage(ClientPtr client)
772 {
773 REQUEST(xXF86DGAGetVidPageReq);
774 xXF86DGAGetVidPageReply rep;
776 if (stuff->screen >= screenInfo.numScreens)
777 return BadValue;
779 REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
780 rep.type = X_Reply;
781 rep.length = 0;
782 rep.sequenceNumber = client->sequence;
783 rep.vpage = 0; /* silently fail */
785 WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep);
786 return Success;
787 }
790 static int
791 ProcXF86DGASetVidPage(ClientPtr client)
792 {
793 REQUEST(xXF86DGASetVidPageReq);
795 if (stuff->screen >= screenInfo.numScreens)
796 return BadValue;
798 REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
800 /* silently fail */
802 return Success;
803 }
806 static int
807 ProcXF86DGAInstallColormap(ClientPtr client)
808 {
809 ColormapPtr pcmp;
810 int rc;
811 REQUEST(xXF86DGAInstallColormapReq);
813 if (stuff->screen >= screenInfo.numScreens)
814 return BadValue;
816 if (DGA_GETCLIENT(stuff->screen) != client)
817 return DGAErrorBase + XF86DGADirectNotActivated;
819 REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
821 if (!DGAActive(stuff->screen))
822 return DGAErrorBase + XF86DGADirectNotActivated;
824 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP,
825 client, DixInstallAccess);
826 if (rc == Success) {
827 DGAInstallCmap(pcmp);
828 return Success;
829 } else {
830 return rc;
831 }
832 }
834 static int
835 ProcXF86DGAQueryDirectVideo(ClientPtr client)
836 {
837 REQUEST(xXF86DGAQueryDirectVideoReq);
838 xXF86DGAQueryDirectVideoReply rep;
840 if (stuff->screen >= screenInfo.numScreens)
841 return BadValue;
843 REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
844 rep.type = X_Reply;
845 rep.length = 0;
846 rep.sequenceNumber = client->sequence;
847 rep.flags = 0;
849 if (DGAAvailable(stuff->screen))
850 rep.flags = XF86DGADirectPresent;
852 WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep);
853 return Success;
854 }
856 static int
857 ProcXF86DGAViewPortChanged(ClientPtr client)
858 {
859 REQUEST(xXF86DGAViewPortChangedReq);
860 xXF86DGAViewPortChangedReply rep;
862 if (stuff->screen >= screenInfo.numScreens)
863 return BadValue;
865 if (DGA_GETCLIENT(stuff->screen) != client)
866 return DGAErrorBase + XF86DGADirectNotActivated;
868 REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
870 if (!DGAActive(stuff->screen))
871 return DGAErrorBase + XF86DGADirectNotActivated;
873 rep.type = X_Reply;
874 rep.length = 0;
875 rep.sequenceNumber = client->sequence;
876 rep.result = 1;
878 WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep);
879 return Success;
880 }
882 #endif /* DGA_PROTOCOL_OLD_SUPPORT */
884 static int
885 SProcXDGADispatch (ClientPtr client)
886 {
887 return DGAErrorBase + XF86DGAClientNotLocal;
888 }
890 #if 0
891 #define DGA_REQ_DEBUG
892 #endif
894 #ifdef DGA_REQ_DEBUG
895 static char *dgaMinor[] = {
896 "QueryVersion",
897 "GetVideoLL",
898 "DirectVideo",
899 "GetViewPortSize",
900 "SetViewPort",
901 "GetVidPage",
902 "SetVidPage",
903 "InstallColormap",
904 "QueryDirectVideo",
905 "ViewPortChanged",
906 "10",
907 "11",
908 "QueryModes",
909 "SetMode",
910 "SetViewport",
911 "InstallColormap",
912 "SelectInput",
913 "FillRectangle",
914 "CopyArea",
915 "CopyTransparentArea",
916 "GetViewportStatus",
917 "Sync",
918 "OpenFramebuffer",
919 "CloseFramebuffer",
920 "SetClientVersion",
921 "ChangePixmapMode",
922 "CreateColormap",
923 };
924 #endif
926 static int
927 ProcXDGADispatch (ClientPtr client)
928 {
929 REQUEST(xReq);
931 if (!LocalClient(client))
932 return DGAErrorBase + XF86DGAClientNotLocal;
934 #ifdef DGA_REQ_DEBUG
935 if (stuff->data <= X_XDGACreateColormap)
936 fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]);
937 #endif
939 switch (stuff->data){
940 /*
941 * DGA2 Protocol
942 */
943 case X_XDGAQueryVersion:
944 return ProcXDGAQueryVersion(client);
945 case X_XDGAQueryModes:
946 return ProcXDGAQueryModes(client);
947 case X_XDGASetMode:
948 return ProcXDGASetMode(client);
949 case X_XDGAOpenFramebuffer:
950 return ProcXDGAOpenFramebuffer(client);
951 case X_XDGACloseFramebuffer:
952 return ProcXDGACloseFramebuffer(client);
953 case X_XDGASetViewport:
954 return ProcXDGASetViewport(client);
955 case X_XDGAInstallColormap:
956 return ProcXDGAInstallColormap(client);
957 case X_XDGASelectInput:
958 return ProcXDGASelectInput(client);
959 case X_XDGAFillRectangle:
960 return ProcXDGAFillRectangle(client);
961 case X_XDGACopyArea:
962 return ProcXDGACopyArea(client);
963 case X_XDGACopyTransparentArea:
964 return ProcXDGACopyTransparentArea(client);
965 case X_XDGAGetViewportStatus:
966 return ProcXDGAGetViewportStatus(client);
967 case X_XDGASync:
968 return ProcXDGASync(client);
969 case X_XDGASetClientVersion:
970 return ProcXDGASetClientVersion(client);
971 case X_XDGAChangePixmapMode:
972 return ProcXDGAChangePixmapMode(client);
973 case X_XDGACreateColormap:
974 return ProcXDGACreateColormap(client);
975 /*
976 * Old DGA Protocol
977 */
978 #ifdef DGA_PROTOCOL_OLD_SUPPORT
979 case X_XF86DGAGetVideoLL:
980 return ProcXF86DGAGetVideoLL(client);
981 case X_XF86DGADirectVideo:
982 return ProcXF86DGADirectVideo(client);
983 case X_XF86DGAGetViewPortSize:
984 return ProcXF86DGAGetViewPortSize(client);
985 case X_XF86DGASetViewPort:
986 return ProcXF86DGASetViewPort(client);
987 case X_XF86DGAGetVidPage:
988 return ProcXF86DGAGetVidPage(client);
989 case X_XF86DGASetVidPage:
990 return ProcXF86DGASetVidPage(client);
991 case X_XF86DGAInstallColormap:
992 return ProcXF86DGAInstallColormap(client);
993 case X_XF86DGAQueryDirectVideo:
994 return ProcXF86DGAQueryDirectVideo(client);
995 case X_XF86DGAViewPortChanged:
996 return ProcXF86DGAViewPortChanged(client);
997 #endif /* DGA_PROTOCOL_OLD_SUPPORT */
998 default:
999 return BadRequest;
1000 }
1001 }
1003 void
1004 XFree86DGARegister(INITARGS)
1005 {
1006 XDGAEventBase = &DGAEventBase;
1007 }
1009 void
1010 XFree86DGAExtensionInit(INITARGS)
1011 {
1012 ExtensionEntry* extEntry;
1014 if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0))
1015 return;
1017 if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
1018 return;
1020 if ((extEntry = AddExtension(XF86DGANAME,
1021 XF86DGANumberEvents,
1022 XF86DGANumberErrors,
1023 ProcXDGADispatch,
1024 SProcXDGADispatch,
1025 XDGAResetProc,
1026 StandardMinorOpcode))) {
1027 int i;
1029 DGAReqCode = (unsigned char)extEntry->base;
1030 DGAErrorBase = extEntry->errorBase;
1031 DGAEventBase = extEntry->eventBase;
1032 for (i = KeyPress; i <= MotionNotify; i++)
1033 SetCriticalEvent (DGAEventBase + i);
1034 }
1035 }