Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / common / xf86DGA.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright (c) 1995 Jon Tombs
3 * Copyright (c) 1995, 1996, 1999 XFree86 Inc
4 * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Except as contained in this notice, the name of the copyright holder(s)
25 * and author(s) shall not be used in advertising or otherwise to promote
26 * the sale, use or other dealings in this Software without prior written
27 * authorization from the copyright holder(s) and author(s).
28 *
29 * Written by Mark Vojkovich
30 */
31
32/*
33 * This is quite literally just two files glued together:
34 * hw/xfree86/common/xf86DGA.c is the first part, and
35 * hw/xfree86/dixmods/extmod/xf86dga2.c is the second part. One day, if
36 * someone actually cares about DGA, it'd be nice to clean this up. But trust
37 * me, I am not that person.
38 */
39
40#ifdef HAVE_XORG_CONFIG_H
41#include <xorg-config.h>
42#endif
43
44#include <X11/X.h>
45#include <X11/Xproto.h>
46#include "xf86.h"
47#include "xf86str.h"
48#include "xf86Priv.h"
49#include "dgaproc.h"
50#include <X11/extensions/xf86dgaproto.h>
51#include "colormapst.h"
52#include "pixmapstr.h"
53#include "inputstr.h"
54#include "globals.h"
55#include "servermd.h"
56#include "micmap.h"
57#include "xkbsrv.h"
58#include "xf86Xinput.h"
59#include "exglobals.h"
60#include "exevents.h"
61#include "eventstr.h"
62#include "eventconvert.h"
63#include "xf86Extensions.h"
64
65#include "mi.h"
66
67#include "misc.h"
68#include "dixstruct.h"
69#include "dixevents.h"
70#include "extnsionst.h"
71#include "cursorstr.h"
72#include "scrnintstr.h"
73#include "swaprep.h"
74#include "dgaproc.h"
75#include "protocol-versions.h"
76
77#include <string.h>
78
79#define DGA_PROTOCOL_OLD_SUPPORT 1
80
81static DevPrivateKeyRec DGAScreenKeyRec;
82
83#define DGAScreenKeyRegistered dixPrivateKeyRegistered(&DGAScreenKeyRec)
84static Bool mieq_installed;
85
86static Bool DGACloseScreen(ScreenPtr pScreen);
87static void DGADestroyColormap(ColormapPtr pmap);
88static void DGAInstallColormap(ColormapPtr pmap);
89static void DGAUninstallColormap(ColormapPtr pmap);
90static void DGAHandleEvent(int screen_num, InternalEvent *event,
91 DeviceIntPtr device);
92
93static void
94 DGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode);
95
96static unsigned char DGAReqCode = 0;
97static int DGAErrorBase;
98static int DGAEventBase;
99
100#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
101 dixLookupPrivate(&(pScreen)->devPrivates, &DGAScreenKeyRec))
102
103typedef struct _FakedVisualList {
104 Bool free;
105 VisualPtr pVisual;
106 struct _FakedVisualList *next;
107} FakedVisualList;
108
109typedef struct {
110 ScrnInfoPtr pScrn;
111 int numModes;
112 DGAModePtr modes;
113 CloseScreenProcPtr CloseScreen;
114 DestroyColormapProcPtr DestroyColormap;
115 InstallColormapProcPtr InstallColormap;
116 UninstallColormapProcPtr UninstallColormap;
117 DGADevicePtr current;
118 DGAFunctionPtr funcs;
119 int input;
120 ClientPtr client;
121 int pixmapMode;
122 FakedVisualList *fakedVisuals;
123 ColormapPtr dgaColormap;
124 ColormapPtr savedColormap;
125 Bool grabMouse;
126 Bool grabKeyboard;
127} DGAScreenRec, *DGAScreenPtr;
128
129Bool
130DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes, int num)
131{
132 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
133 DGAScreenPtr pScreenPriv;
134 int i;
135
136 if (!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
137 return FALSE;
138
139 if (!modes || num <= 0)
140 return FALSE;
141
142 if (!dixRegisterPrivateKey(&DGAScreenKeyRec, PRIVATE_SCREEN, 0))
143 return FALSE;
144
145 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
146
147 if (!pScreenPriv) {
148 if (!(pScreenPriv = (DGAScreenPtr) malloc(sizeof(DGAScreenRec))))
149 return FALSE;
150 dixSetPrivate(&pScreen->devPrivates, &DGAScreenKeyRec, pScreenPriv);
151 pScreenPriv->CloseScreen = pScreen->CloseScreen;
152 pScreen->CloseScreen = DGACloseScreen;
153 pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
154 pScreen->DestroyColormap = DGADestroyColormap;
155 pScreenPriv->InstallColormap = pScreen->InstallColormap;
156 pScreen->InstallColormap = DGAInstallColormap;
157 pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
158 pScreen->UninstallColormap = DGAUninstallColormap;
159 }
160
161 pScreenPriv->pScrn = pScrn;
162 pScreenPriv->numModes = num;
163 pScreenPriv->modes = modes;
164 pScreenPriv->current = NULL;
165
166 pScreenPriv->funcs = funcs;
167 pScreenPriv->input = 0;
168 pScreenPriv->client = NULL;
169 pScreenPriv->fakedVisuals = NULL;
170 pScreenPriv->dgaColormap = NULL;
171 pScreenPriv->savedColormap = NULL;
172 pScreenPriv->grabMouse = FALSE;
173 pScreenPriv->grabKeyboard = FALSE;
174
175 for (i = 0; i < num; i++)
176 modes[i].num = i + 1;
177
178#ifdef PANORAMIX
179 if (!noPanoramiXExtension)
180 for (i = 0; i < num; i++)
181 modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
182#endif
183
184 return TRUE;
185}
186
187/* DGAReInitModes allows the driver to re-initialize
188 * the DGA mode list.
189 */
190
191Bool
192DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num)
193{
194 DGAScreenPtr pScreenPriv;
195 int i;
196
197 /* No DGA? Ignore call (but don't make it look like it failed) */
198 if (!DGAScreenKeyRegistered)
199 return TRUE;
200
201 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
202
203 /* Same as above */
204 if (!pScreenPriv)
205 return TRUE;
206
207 /* Can't do this while DGA is active */
208 if (pScreenPriv->current)
209 return FALSE;
210
211 /* Quick sanity check */
212 if (!num)
213 modes = NULL;
214 else if (!modes)
215 num = 0;
216
217 pScreenPriv->numModes = num;
218 pScreenPriv->modes = modes;
219
220 /* This practically disables DGA. So be it. */
221 if (!num)
222 return TRUE;
223
224 for (i = 0; i < num; i++)
225 modes[i].num = i + 1;
226
227#ifdef PANORAMIX
228 if (!noPanoramiXExtension)
229 for (i = 0; i < num; i++)
230 modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
231#endif
232
233 return TRUE;
234}
235
236static void
237FreeMarkedVisuals(ScreenPtr pScreen)
238{
239 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
240 FakedVisualList *prev, *curr, *tmp;
241
242 if (!pScreenPriv->fakedVisuals)
243 return;
244
245 prev = NULL;
246 curr = pScreenPriv->fakedVisuals;
247
248 while (curr) {
249 if (curr->free) {
250 tmp = curr;
251 curr = curr->next;
252 if (prev)
253 prev->next = curr;
254 else
255 pScreenPriv->fakedVisuals = curr;
256 free(tmp->pVisual);
257 free(tmp);
258 }
259 else {
260 prev = curr;
261 curr = curr->next;
262 }
263 }
264}
265
266static Bool
267DGACloseScreen(ScreenPtr pScreen)
268{
269 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
270
271 if (mieq_installed) {
272 mieqSetHandler(ET_DGAEvent, NULL);
273 mieq_installed = FALSE;
274 }
275
276 FreeMarkedVisuals(pScreen);
277
278 pScreen->CloseScreen = pScreenPriv->CloseScreen;
279 pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
280 pScreen->InstallColormap = pScreenPriv->InstallColormap;
281 pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
282
283 /* DGAShutdown() should have ensured that no DGA
284 screen were active by here */
285
286 free(pScreenPriv);
287
288 return ((*pScreen->CloseScreen) (pScreen));
289}
290
291static void
292DGADestroyColormap(ColormapPtr pmap)
293{
294 ScreenPtr pScreen = pmap->pScreen;
295 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
296 VisualPtr pVisual = pmap->pVisual;
297
298 if (pScreenPriv->fakedVisuals) {
299 FakedVisualList *curr = pScreenPriv->fakedVisuals;
300
301 while (curr) {
302 if (curr->pVisual == pVisual) {
303 /* We can't get rid of them yet since FreeColormap
304 still needs the pVisual during the cleanup */
305 curr->free = TRUE;
306 break;
307 }
308 curr = curr->next;
309 }
310 }
311
312 if (pScreenPriv->DestroyColormap) {
313 pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
314 (*pScreen->DestroyColormap) (pmap);
315 pScreen->DestroyColormap = DGADestroyColormap;
316 }
317}
318
319static void
320DGAInstallColormap(ColormapPtr pmap)
321{
322 ScreenPtr pScreen = pmap->pScreen;
323 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
324
325 if (pScreenPriv->current && pScreenPriv->dgaColormap) {
326 if (pmap != pScreenPriv->dgaColormap) {
327 pScreenPriv->savedColormap = pmap;
328 pmap = pScreenPriv->dgaColormap;
329 }
330 }
331
332 pScreen->InstallColormap = pScreenPriv->InstallColormap;
333 (*pScreen->InstallColormap) (pmap);
334 pScreen->InstallColormap = DGAInstallColormap;
335}
336
337static void
338DGAUninstallColormap(ColormapPtr pmap)
339{
340 ScreenPtr pScreen = pmap->pScreen;
341 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
342
343 if (pScreenPriv->current && pScreenPriv->dgaColormap) {
344 if (pmap == pScreenPriv->dgaColormap) {
345 pScreenPriv->dgaColormap = NULL;
346 }
347 }
348
349 pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
350 (*pScreen->UninstallColormap) (pmap);
351 pScreen->UninstallColormap = DGAUninstallColormap;
352}
353
354int
355xf86SetDGAMode(ScrnInfoPtr pScrn, int num, DGADevicePtr devRet)
356{
357 ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
358 DGAScreenPtr pScreenPriv;
359 DGADevicePtr device;
360 PixmapPtr pPix = NULL;
361 DGAModePtr pMode = NULL;
362
363 /* First check if DGAInit was successful on this screen */
364 if (!DGAScreenKeyRegistered)
365 return BadValue;
366 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
367 if (!pScreenPriv)
368 return BadValue;
369
370 if (!num) {
371 if (pScreenPriv->current) {
372 PixmapPtr oldPix = pScreenPriv->current->pPix;
373
374 if (oldPix) {
375 if (oldPix->drawable.id)
376 FreeResource(oldPix->drawable.id, RT_NONE);
377 else
378 (*pScreen->DestroyPixmap) (oldPix);
379 }
380 free(pScreenPriv->current);
381 pScreenPriv->current = NULL;
382 pScrn->vtSema = TRUE;
383 (*pScreenPriv->funcs->SetMode) (pScrn, NULL);
384 if (pScreenPriv->savedColormap) {
385 (*pScreen->InstallColormap) (pScreenPriv->savedColormap);
386 pScreenPriv->savedColormap = NULL;
387 }
388 pScreenPriv->dgaColormap = NULL;
389 (*pScrn->EnableDisableFBAccess) (pScrn, TRUE);
390
391 FreeMarkedVisuals(pScreen);
392 }
393
394 pScreenPriv->grabMouse = FALSE;
395 pScreenPriv->grabKeyboard = FALSE;
396
397 return Success;
398 }
399
400 if (!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */
401 return BadAlloc;
402
403 if ((num > 0) && (num <= pScreenPriv->numModes))
404 pMode = &(pScreenPriv->modes[num - 1]);
405 else
406 return BadValue;
407
408 if (!(device = (DGADevicePtr) malloc(sizeof(DGADeviceRec))))
409 return BadAlloc;
410
411 if (!pScreenPriv->current) {
412 Bool oldVTSema = pScrn->vtSema;
413
414 pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */
415 (*pScrn->EnableDisableFBAccess) (pScrn, FALSE);
416 pScrn->vtSema = oldVTSema;
417 }
418
419 if (!(*pScreenPriv->funcs->SetMode) (pScrn, pMode)) {
420 free(device);
421 return BadAlloc;
422 }
423
424 pScrn->currentMode = pMode->mode;
425
426 if (!pScreenPriv->current && !pScreenPriv->input) {
427 /* if it's multihead we need to warp the cursor off of
428 our screen so it doesn't get trapped */
429 }
430
431 pScrn->vtSema = FALSE;
432
433 if (pScreenPriv->current) {
434 PixmapPtr oldPix = pScreenPriv->current->pPix;
435
436 if (oldPix) {
437 if (oldPix->drawable.id)
438 FreeResource(oldPix->drawable.id, RT_NONE);
439 else
440 (*pScreen->DestroyPixmap) (oldPix);
441 }
442 free(pScreenPriv->current);
443 pScreenPriv->current = NULL;
444 }
445
446 if (pMode->flags & DGA_PIXMAP_AVAILABLE) {
447 if ((pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pMode->depth, 0))) {
448 (*pScreen->ModifyPixmapHeader) (pPix,
449 pMode->pixmapWidth,
450 pMode->pixmapHeight, pMode->depth,
451 pMode->bitsPerPixel,
452 pMode->bytesPerScanline,
453 (pointer) (pMode->address));
454 }
455 }
456
457 devRet->mode = device->mode = pMode;
458 devRet->pPix = device->pPix = pPix;
459 pScreenPriv->current = device;
460 pScreenPriv->pixmapMode = FALSE;
461 pScreenPriv->grabMouse = TRUE;
462 pScreenPriv->grabKeyboard = TRUE;
463
464 if (!mieq_installed) {
465 mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
466 mieq_installed = TRUE;
467 }
468
469 return Success;
470}
471
472/*********** exported ones ***************/
473
474void
475DGASetInputMode(int index, Bool keyboard, Bool mouse)
476{
477 ScreenPtr pScreen = screenInfo.screens[index];
478 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
479
480 if (pScreenPriv) {
481 pScreenPriv->grabMouse = mouse;
482 pScreenPriv->grabKeyboard = keyboard;
483
484 if (!mieq_installed) {
485 mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
486 mieq_installed = TRUE;
487 }
488 }
489}
490
491Bool
492DGAChangePixmapMode(int index, int *x, int *y, int mode)
493{
494 DGAScreenPtr pScreenPriv;
495 DGADevicePtr pDev;
496 DGAModePtr pMode;
497 PixmapPtr pPix;
498
499 if (!DGAScreenKeyRegistered)
500 return FALSE;
501
502 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
503
504 if (!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
505 return FALSE;
506
507 pDev = pScreenPriv->current;
508 pPix = pDev->pPix;
509 pMode = pDev->mode;
510
511 if (mode) {
512 int shift = 2;
513
514 if (*x > (pMode->pixmapWidth - pMode->viewportWidth))
515 *x = pMode->pixmapWidth - pMode->viewportWidth;
516 if (*y > (pMode->pixmapHeight - pMode->viewportHeight))
517 *y = pMode->pixmapHeight - pMode->viewportHeight;
518
519 switch (xf86Screens[index]->bitsPerPixel) {
520 case 16:
521 shift = 1;
522 break;
523 case 32:
524 shift = 0;
525 break;
526 default:
527 break;
528 }
529
530 if (BITMAP_SCANLINE_PAD == 64)
531 shift++;
532
533 *x = (*x >> shift) << shift;
534
535 pPix->drawable.x = *x;
536 pPix->drawable.y = *y;
537 pPix->drawable.width = pMode->viewportWidth;
538 pPix->drawable.height = pMode->viewportHeight;
539 }
540 else {
541 pPix->drawable.x = 0;
542 pPix->drawable.y = 0;
543 pPix->drawable.width = pMode->pixmapWidth;
544 pPix->drawable.height = pMode->pixmapHeight;
545 }
546 pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
547 pScreenPriv->pixmapMode = mode;
548
549 return TRUE;
550}
551
552Bool
553DGAScreenAvailable(ScreenPtr pScreen)
554{
555 if (!DGAScreenKeyRegistered)
556 return FALSE;
557
558 if (DGA_GET_SCREEN_PRIV(pScreen))
559 return TRUE;
560 return FALSE;
561}
562
563Bool
564DGAAvailable(int index)
565{
566 ScreenPtr pScreen;
567
568 assert(index < MAXSCREENS);
569 pScreen = screenInfo.screens[index];
570 return DGAScreenAvailable(pScreen);
571}
572
573Bool
574DGAActive(int index)
575{
576 DGAScreenPtr pScreenPriv;
577
578 if (!DGAScreenKeyRegistered)
579 return FALSE;
580
581 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
582
583 if (pScreenPriv && pScreenPriv->current)
584 return TRUE;
585
586 return FALSE;
587}
588
589/* Called by the event code in case the server is abruptly terminated */
590
591void
592DGAShutdown(void)
593{
594 ScrnInfoPtr pScrn;
595 int i;
596
597 if (!DGAScreenKeyRegistered)
598 return;
599
600 for (i = 0; i < screenInfo.numScreens; i++) {
601 pScrn = xf86Screens[i];
602
603 (void) (*pScrn->SetDGAMode) (pScrn, 0, NULL);
604 }
605}
606
607/* Called by the extension to initialize a mode */
608
609int
610DGASetMode(int index, int num, XDGAModePtr mode, PixmapPtr *pPix)
611{
612 ScrnInfoPtr pScrn = xf86Screens[index];
613 DGADeviceRec device;
614 int ret;
615
616 /* We rely on the extension to check that DGA is available */
617
618 ret = (*pScrn->SetDGAMode) (pScrn, num, &device);
619 if ((ret == Success) && num) {
620 DGACopyModeInfo(device.mode, mode);
621 *pPix = device.pPix;
622 }
623
624 return ret;
625}
626
627/* Called from the extension to let the DDX know which events are requested */
628
629void
630DGASelectInput(int index, ClientPtr client, long mask)
631{
632 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
633
634 /* We rely on the extension to check that DGA is available */
635 pScreenPriv->client = client;
636 pScreenPriv->input = mask;
637}
638
639int
640DGAGetViewportStatus(int index)
641{
642 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
643
644 /* We rely on the extension to check that DGA is active */
645
646 if (!pScreenPriv->funcs->GetViewport)
647 return 0;
648
649 return (*pScreenPriv->funcs->GetViewport) (pScreenPriv->pScrn);
650}
651
652int
653DGASetViewport(int index, int x, int y, int mode)
654{
655 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
656
657 if (pScreenPriv->funcs->SetViewport)
658 (*pScreenPriv->funcs->SetViewport) (pScreenPriv->pScrn, x, y, mode);
659 return Success;
660}
661
662static int
663BitsClear(CARD32 data)
664{
665 int bits = 0;
666 CARD32 mask;
667
668 for (mask = 1; mask; mask <<= 1) {
669 if (!(data & mask))
670 bits++;
671 else
672 break;
673 }
674
675 return bits;
676}
677
678int
679DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
680{
681 ScreenPtr pScreen = screenInfo.screens[index];
682 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
683 FakedVisualList *fvlp;
684 VisualPtr pVisual;
685 DGAModePtr pMode;
686 ColormapPtr pmap;
687
688 if (!mode || (mode > pScreenPriv->numModes))
689 return BadValue;
690
691 if ((alloc != AllocNone) && (alloc != AllocAll))
692 return BadValue;
693
694 pMode = &(pScreenPriv->modes[mode - 1]);
695
696 if (!(pVisual = malloc(sizeof(VisualRec))))
697 return BadAlloc;
698
699 pVisual->vid = FakeClientID(0);
700 pVisual->class = pMode->visualClass;
701 pVisual->nplanes = pMode->depth;
702 pVisual->ColormapEntries = 1 << pMode->depth;
703 pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
704
705 switch (pVisual->class) {
706 case PseudoColor:
707 case GrayScale:
708 case StaticGray:
709 pVisual->bitsPerRGBValue = 8; /* not quite */
710 pVisual->redMask = 0;
711 pVisual->greenMask = 0;
712 pVisual->blueMask = 0;
713 pVisual->offsetRed = 0;
714 pVisual->offsetGreen = 0;
715 pVisual->offsetBlue = 0;
716 break;
717 case DirectColor:
718 case TrueColor:
719 pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
720 /* fall through */
721 case StaticColor:
722 pVisual->redMask = pMode->red_mask;
723 pVisual->greenMask = pMode->green_mask;
724 pVisual->blueMask = pMode->blue_mask;
725 pVisual->offsetRed = BitsClear(pVisual->redMask);
726 pVisual->offsetGreen = BitsClear(pVisual->greenMask);
727 pVisual->offsetBlue = BitsClear(pVisual->blueMask);
728 }
729
730 if (!(fvlp = malloc(sizeof(FakedVisualList)))) {
731 free(pVisual);
732 return BadAlloc;
733 }
734
735 fvlp->free = FALSE;
736 fvlp->pVisual = pVisual;
737 fvlp->next = pScreenPriv->fakedVisuals;
738 pScreenPriv->fakedVisuals = fvlp;
739
740 LEGAL_NEW_RESOURCE(id, client);
741
742 return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
743}
744
745/* Called by the extension to install a colormap on DGA active screens */
746
747void
748DGAInstallCmap(ColormapPtr cmap)
749{
750 ScreenPtr pScreen = cmap->pScreen;
751 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
752
753 /* We rely on the extension to check that DGA is active */
754
755 if (!pScreenPriv->dgaColormap)
756 pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
757
758 pScreenPriv->dgaColormap = cmap;
759
760 (*pScreen->InstallColormap) (cmap);
761}
762
763int
764DGASync(int index)
765{
766 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
767
768 /* We rely on the extension to check that DGA is active */
769
770 if (pScreenPriv->funcs->Sync)
771 (*pScreenPriv->funcs->Sync) (pScreenPriv->pScrn);
772
773 return Success;
774}
775
776int
777DGAFillRect(int index, int x, int y, int w, int h, unsigned long color)
778{
779 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
780
781 /* We rely on the extension to check that DGA is active */
782
783 if (pScreenPriv->funcs->FillRect &&
784 (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
785
786 (*pScreenPriv->funcs->FillRect) (pScreenPriv->pScrn, x, y, w, h, color);
787 return Success;
788 }
789 return BadMatch;
790}
791
792int
793DGABlitRect(int index, int srcx, int srcy, int w, int h, int dstx, int dsty)
794{
795 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
796
797 /* We rely on the extension to check that DGA is active */
798
799 if (pScreenPriv->funcs->BlitRect &&
800 (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
801
802 (*pScreenPriv->funcs->BlitRect) (pScreenPriv->pScrn,
803 srcx, srcy, w, h, dstx, dsty);
804 return Success;
805 }
806 return BadMatch;
807}
808
809int
810DGABlitTransRect(int index,
811 int srcx, int srcy,
812 int w, int h, int dstx, int dsty, unsigned long color)
813{
814 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
815
816 /* We rely on the extension to check that DGA is active */
817
818 if (pScreenPriv->funcs->BlitTransRect &&
819 (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
820
821 (*pScreenPriv->funcs->BlitTransRect) (pScreenPriv->pScrn,
822 srcx, srcy, w, h, dstx, dsty,
823 color);
824 return Success;
825 }
826 return BadMatch;
827}
828
829int
830DGAGetModes(int index)
831{
832 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
833
834 /* We rely on the extension to check that DGA is available */
835
836 return pScreenPriv->numModes;
837}
838
839int
840DGAGetModeInfo(int index, XDGAModePtr mode, int num)
841{
842 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
843
844 /* We rely on the extension to check that DGA is available */
845
846 if ((num <= 0) || (num > pScreenPriv->numModes))
847 return BadValue;
848
849 DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
850
851 return Success;
852}
853
854static void
855DGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode)
856{
857 DisplayModePtr dmode = mode->mode;
858
859 xmode->num = mode->num;
860 xmode->name = dmode->name;
861 xmode->VSync_num = (int) (dmode->VRefresh * 1000.0);
862 xmode->VSync_den = 1000;
863 xmode->flags = mode->flags;
864 xmode->imageWidth = mode->imageWidth;
865 xmode->imageHeight = mode->imageHeight;
866 xmode->pixmapWidth = mode->pixmapWidth;
867 xmode->pixmapHeight = mode->pixmapHeight;
868 xmode->bytesPerScanline = mode->bytesPerScanline;
869 xmode->byteOrder = mode->byteOrder;
870 xmode->depth = mode->depth;
871 xmode->bitsPerPixel = mode->bitsPerPixel;
872 xmode->red_mask = mode->red_mask;
873 xmode->green_mask = mode->green_mask;
874 xmode->blue_mask = mode->blue_mask;
875 xmode->visualClass = mode->visualClass;
876 xmode->viewportWidth = mode->viewportWidth;
877 xmode->viewportHeight = mode->viewportHeight;
878 xmode->xViewportStep = mode->xViewportStep;
879 xmode->yViewportStep = mode->yViewportStep;
880 xmode->maxViewportX = mode->maxViewportX;
881 xmode->maxViewportY = mode->maxViewportY;
882 xmode->viewportFlags = mode->viewportFlags;
883 xmode->reserved1 = mode->reserved1;
884 xmode->reserved2 = mode->reserved2;
885 xmode->offset = mode->offset;
886
887 if (dmode->Flags & V_INTERLACE)
888 xmode->flags |= DGA_INTERLACED;
889 if (dmode->Flags & V_DBLSCAN)
890 xmode->flags |= DGA_DOUBLESCAN;
891}
892
893Bool
894DGAVTSwitch(void)
895{
896 ScreenPtr pScreen;
897 int i;
898
899 for (i = 0; i < screenInfo.numScreens; i++) {
900 pScreen = screenInfo.screens[i];
901
902 /* Alternatively, this could send events to DGA clients */
903
904 if (DGAScreenKeyRegistered) {
905 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
906
907 if (pScreenPriv && pScreenPriv->current)
908 return FALSE;
909 }
910 }
911
912 return TRUE;
913}
914
915Bool
916DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
917{
918 DGAScreenPtr pScreenPriv;
919 DGAEvent event;
920
921 if (!DGAScreenKeyRegistered) /* no DGA */
922 return FALSE;
923
924 if (key_code < 8 || key_code > 255)
925 return FALSE;
926
927 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
928
929 if (!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
930 return FALSE;
931
932 event = (DGAEvent) {
933 .header = ET_Internal,
934 .type = ET_DGAEvent,
935 .length = sizeof(event),
936 .time = GetTimeInMillis(),
937 .subtype = (is_down ? ET_KeyPress : ET_KeyRelease),
938 .detail = key_code,
939 .dx = 0,
940 .dy = 0
941 };
942 mieqEnqueue(dev, (InternalEvent *) &event);
943
944 return TRUE;
945}
946
947Bool
948DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
949{
950 DGAScreenPtr pScreenPriv;
951 DGAEvent event;
952
953 if (!DGAScreenKeyRegistered) /* no DGA */
954 return FALSE;
955
956 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
957
958 if (!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */
959 return FALSE;
960
961 event = (DGAEvent) {
962 .header = ET_Internal,
963 .type = ET_DGAEvent,
964 .length = sizeof(event),
965 .time = GetTimeInMillis(),
966 .subtype = ET_Motion,
967 .detail = 0,
968 .dx = dx,
969 .dy = dy
970 };
971 mieqEnqueue(dev, (InternalEvent *) &event);
972 return TRUE;
973}
974
975Bool
976DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
977{
978 DGAScreenPtr pScreenPriv;
979 DGAEvent event;
980
981 if (!DGAScreenKeyRegistered) /* no DGA */
982 return FALSE;
983
984 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
985
986 if (!pScreenPriv || !pScreenPriv->grabMouse)
987 return FALSE;
988
989 event = (DGAEvent) {
990 .header = ET_Internal,
991 .type = ET_DGAEvent,
992 .length = sizeof(event),
993 .time = GetTimeInMillis(),
994 .subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease),
995 .detail = button,
996 .dx = 0,
997 .dy = 0
998 };
999 mieqEnqueue(dev, (InternalEvent *) &event);
1000
1001 return TRUE;
1002}
1003
1004/* We have the power to steal or modify events that are about to get queued */
1005
1006#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
1007static Mask filters[] = {
1008 NoSuchEvent, /* 0 */
1009 NoSuchEvent, /* 1 */
1010 KeyPressMask, /* KeyPress */
1011 KeyReleaseMask, /* KeyRelease */
1012 ButtonPressMask, /* ButtonPress */
1013 ButtonReleaseMask, /* ButtonRelease */
1014 PointerMotionMask, /* MotionNotify (initial state) */
1015};
1016
1017static void
1018DGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd)
1019{
1020 KeyClassPtr keyc = keybd->key;
1021 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
1022 DeviceIntPtr pointer = GetMaster(keybd, POINTER_OR_FLOAT);
1023 DeviceEvent ev = {
1024 .header = ET_Internal,
1025 .length = sizeof(ev),
1026 .detail.key = event->detail,
1027 .type = event->subtype,
1028 .root_x = 0,
1029 .root_y = 0,
1030 .corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state)
1031 };
1032 ev.corestate |= pointer->button->state;
1033
1034 UpdateDeviceState(keybd, &ev);
1035
1036 if (!IsMaster(keybd))
1037 return;
1038
1039 /*
1040 * Deliver the DGA event
1041 */
1042 if (pScreenPriv->client) {
1043 dgaEvent de = {
1044 .u.event.time = event->time,
1045 .u.event.dx = event->dx,
1046 .u.event.dy = event->dy,
1047 .u.event.screen = pScreen->myNum,
1048 .u.event.state = ev.corestate
1049 };
1050 de.u.u.type = DGAEventBase + GetCoreType(ev.type);
1051 de.u.u.detail = event->detail;
1052
1053 /* If the DGA client has selected input, then deliver based on the usual filter */
1054 TryClientEvents(pScreenPriv->client, keybd, (xEvent *) &de, 1,
1055 filters[ev.type], pScreenPriv->input, 0);
1056 }
1057 else {
1058 /* If the keyboard is actively grabbed, deliver a grabbed core event */
1059 if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab) {
1060 ev.detail.key = event->detail;
1061 ev.time = event->time;
1062 ev.root_x = event->dx;
1063 ev.root_y = event->dy;
1064 ev.corestate = event->state;
1065 ev.deviceid = keybd->id;
1066 DeliverGrabbedEvent((InternalEvent *) &ev, keybd, FALSE);
1067 }
1068 }
1069}
1070
1071static void
1072DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
1073{
1074 ButtonClassPtr butc = mouse->button;
1075 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
1076 DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
1077 DeviceEvent ev = {
1078 .header = ET_Internal,
1079 .length = sizeof(ev),
1080 .detail.key = event->detail,
1081 .type = event->subtype,
1082 .corestate = butc ? butc->state : 0
1083 };
1084
1085 if (master && master->key)
1086 ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
1087
1088 UpdateDeviceState(mouse, &ev);
1089
1090 if (!IsMaster(mouse))
1091 return;
1092
1093 /*
1094 * Deliver the DGA event
1095 */
1096 if (pScreenPriv->client) {
1097 int coreEquiv = GetCoreType(ev.type);
1098 dgaEvent de = {
1099 .u.event.time = event->time,
1100 .u.event.dx = event->dx,
1101 .u.event.dy = event->dy,
1102 .u.event.screen = pScreen->myNum,
1103 .u.event.state = ev.corestate
1104 };
1105 de.u.u.type = DGAEventBase + coreEquiv;
1106 de.u.u.detail = event->detail;
1107
1108 /* If the DGA client has selected input, then deliver based on the usual filter */
1109 TryClientEvents(pScreenPriv->client, mouse, (xEvent *) &de, 1,
1110 filters[coreEquiv], pScreenPriv->input, 0);
1111 }
1112 else {
1113 /* If the pointer is actively grabbed, deliver a grabbed core event */
1114 if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab) {
1115 ev.detail.button = event->detail;
1116 ev.time = event->time;
1117 ev.root_x = event->dx;
1118 ev.root_y = event->dy;
1119 ev.corestate = event->state;
1120 /* DGA is core only, so valuators.data doesn't actually matter.
1121 * Mask must be set for EventToCore to create motion events. */
1122 SetBit(ev.valuators.mask, 0);
1123 SetBit(ev.valuators.mask, 1);
1124 DeliverGrabbedEvent((InternalEvent *) &ev, mouse, FALSE);
1125 }
1126 }
1127}
1128
1129Bool
1130DGAOpenFramebuffer(int index,
1131 char **name,
1132 unsigned char **mem, int *size, int *offset, int *flags)
1133{
1134 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
1135
1136 /* We rely on the extension to check that DGA is available */
1137
1138 return (*pScreenPriv->funcs->OpenFramebuffer) (pScreenPriv->pScrn,
1139 name, mem, size, offset,
1140 flags);
1141}
1142
1143void
1144DGACloseFramebuffer(int index)
1145{
1146 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
1147
1148 /* We rely on the extension to check that DGA is available */
1149 if (pScreenPriv->funcs->CloseFramebuffer)
1150 (*pScreenPriv->funcs->CloseFramebuffer) (pScreenPriv->pScrn);
1151}
1152
1153/* For DGA 1.0 backwards compatibility only */
1154
1155int
1156DGAGetOldDGAMode(int index)
1157{
1158 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
1159 ScrnInfoPtr pScrn = pScreenPriv->pScrn;
1160 DGAModePtr mode;
1161 int i, w, h, p;
1162
1163 /* We rely on the extension to check that DGA is available */
1164
1165 w = pScrn->currentMode->HDisplay;
1166 h = pScrn->currentMode->VDisplay;
1167 p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
1168
1169 for (i = 0; i < pScreenPriv->numModes; i++) {
1170 mode = &(pScreenPriv->modes[i]);
1171
1172 if ((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
1173 (mode->bytesPerScanline == p) &&
1174 (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
1175 (mode->depth == pScrn->depth)) {
1176
1177 return mode->num;
1178 }
1179 }
1180
1181 return 0;
1182}
1183
1184static void
1185DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
1186{
1187 DGAEvent *event = &ev->dga_event;
1188 ScreenPtr pScreen = screenInfo.screens[screen_num];
1189 DGAScreenPtr pScreenPriv;
1190
1191 /* no DGA */
1192 if (!DGAScreenKeyRegistered || noXFree86DGAExtension)
1193 return;
1194 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
1195
1196 /* DGA not initialized on this screen */
1197 if (!pScreenPriv)
1198 return;
1199
1200 switch (event->subtype) {
1201 case KeyPress:
1202 case KeyRelease:
1203 DGAProcessKeyboardEvent(pScreen, event, device);
1204 break;
1205 case MotionNotify:
1206 case ButtonPress:
1207 case ButtonRelease:
1208 DGAProcessPointerEvent(pScreen, event, device);
1209 break;
1210 default:
1211 break;
1212 }
1213}
1214
1215static void XDGAResetProc(ExtensionEntry * extEntry);
1216
1217static void DGAClientStateChange(CallbackListPtr *, pointer, pointer);
1218
1219static DevPrivateKeyRec DGAScreenPrivateKeyRec;
1220
1221#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
1222#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
1223static DevPrivateKeyRec DGAClientPrivateKeyRec;
1224
1225#define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
1226static int DGACallbackRefCount = 0;
1227
1228/* This holds the client's version information */
1229typedef struct {
1230 int major;
1231 int minor;
1232} DGAPrivRec, *DGAPrivPtr;
1233
1234#define DGA_GETCLIENT(idx) ((ClientPtr) \
1235 dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
1236#define DGA_SETCLIENT(idx,p) \
1237 dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
1238
1239#define DGA_GETPRIV(c) ((DGAPrivPtr) \
1240 dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
1241#define DGA_SETPRIV(c,p) \
1242 dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
1243
1244static void
1245XDGAResetProc(ExtensionEntry * extEntry)
1246{
1247 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
1248 DGACallbackRefCount = 0;
1249}
1250
1251static int
1252ProcXDGAQueryVersion(ClientPtr client)
1253{
1254 xXDGAQueryVersionReply rep;
1255
1256 REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
1257 rep.type = X_Reply;
1258 rep.length = 0;
1259 rep.sequenceNumber = client->sequence;
1260 rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
1261 rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
1262
1263 WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *) &rep);
1264 return Success;
1265}
1266
1267static int
1268ProcXDGAOpenFramebuffer(ClientPtr client)
1269{
1270 REQUEST(xXDGAOpenFramebufferReq);
1271 xXDGAOpenFramebufferReply rep;
1272 char *deviceName;
1273 int nameSize;
1274
1275 if (stuff->screen >= screenInfo.numScreens)
1276 return BadValue;
1277
1278 if (!DGAAvailable(stuff->screen))
1279 return DGAErrorBase + XF86DGANoDirectVideoMode;
1280
1281 REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
1282 rep.type = X_Reply;
1283 rep.length = 0;
1284 rep.sequenceNumber = client->sequence;
1285
1286 if (!DGAOpenFramebuffer(stuff->screen, &deviceName,
1287 (unsigned char **) (&rep.mem1),
1288 (int *) &rep.size, (int *) &rep.offset,
1289 (int *) &rep.extra)) {
1290 return BadAlloc;
1291 }
1292
1293 nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
1294 rep.length = bytes_to_int32(nameSize);
1295
1296 WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *) &rep);
1297 if (rep.length)
1298 WriteToClient(client, nameSize, deviceName);
1299
1300 return Success;
1301}
1302
1303static int
1304ProcXDGACloseFramebuffer(ClientPtr client)
1305{
1306 REQUEST(xXDGACloseFramebufferReq);
1307
1308 if (stuff->screen >= screenInfo.numScreens)
1309 return BadValue;
1310
1311 if (!DGAAvailable(stuff->screen))
1312 return DGAErrorBase + XF86DGANoDirectVideoMode;
1313
1314 REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
1315
1316 DGACloseFramebuffer(stuff->screen);
1317
1318 return Success;
1319}
1320
1321static int
1322ProcXDGAQueryModes(ClientPtr client)
1323{
1324 int i, num, size;
1325
1326 REQUEST(xXDGAQueryModesReq);
1327 xXDGAQueryModesReply rep;
1328 xXDGAModeInfo info;
1329 XDGAModePtr mode;
1330
1331 if (stuff->screen >= screenInfo.numScreens)
1332 return BadValue;
1333
1334 REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
1335 rep.type = X_Reply;
1336 rep.length = 0;
1337 rep.number = 0;
1338 rep.sequenceNumber = client->sequence;
1339
1340 if (!DGAAvailable(stuff->screen)) {
1341 rep.number = 0;
1342 rep.length = 0;
1343 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
1344 return Success;
1345 }
1346
1347 if (!(num = DGAGetModes(stuff->screen))) {
1348 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
1349 return Success;
1350 }
1351
1352 if (!(mode = (XDGAModePtr) malloc(num * sizeof(XDGAModeRec))))
1353 return BadAlloc;
1354
1355 for (i = 0; i < num; i++)
1356 DGAGetModeInfo(stuff->screen, mode + i, i + 1);
1357
1358 size = num * sz_xXDGAModeInfo;
1359 for (i = 0; i < num; i++)
1360 size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
1361
1362 rep.number = num;
1363 rep.length = bytes_to_int32(size);
1364
1365 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
1366
1367 for (i = 0; i < num; i++) {
1368 size = strlen(mode[i].name) + 1;
1369
1370 info.byte_order = mode[i].byteOrder;
1371 info.depth = mode[i].depth;
1372 info.num = mode[i].num;
1373 info.bpp = mode[i].bitsPerPixel;
1374 info.name_size = (size + 3) & ~3L;
1375 info.vsync_num = mode[i].VSync_num;
1376 info.vsync_den = mode[i].VSync_den;
1377 info.flags = mode[i].flags;
1378 info.image_width = mode[i].imageWidth;
1379 info.image_height = mode[i].imageHeight;
1380 info.pixmap_width = mode[i].pixmapWidth;
1381 info.pixmap_height = mode[i].pixmapHeight;
1382 info.bytes_per_scanline = mode[i].bytesPerScanline;
1383 info.red_mask = mode[i].red_mask;
1384 info.green_mask = mode[i].green_mask;
1385 info.blue_mask = mode[i].blue_mask;
1386 info.visual_class = mode[i].visualClass;
1387 info.viewport_width = mode[i].viewportWidth;
1388 info.viewport_height = mode[i].viewportHeight;
1389 info.viewport_xstep = mode[i].xViewportStep;
1390 info.viewport_ystep = mode[i].yViewportStep;
1391 info.viewport_xmax = mode[i].maxViewportX;
1392 info.viewport_ymax = mode[i].maxViewportY;
1393 info.viewport_flags = mode[i].viewportFlags;
1394 info.reserved1 = mode[i].reserved1;
1395 info.reserved2 = mode[i].reserved2;
1396
1397 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info));
1398 WriteToClient(client, size, mode[i].name);
1399 }
1400
1401 free(mode);
1402
1403 return Success;
1404}
1405
1406static void
1407DGAClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
1408{
1409 NewClientInfoRec *pci = (NewClientInfoRec *) calldata;
1410 ClientPtr client = NULL;
1411 int i;
1412
1413 for (i = 0; i < screenInfo.numScreens; i++) {
1414 if (DGA_GETCLIENT(i) == pci->client) {
1415 client = pci->client;
1416 break;
1417 }
1418 }
1419
1420 if (client &&
1421 ((client->clientState == ClientStateGone) ||
1422 (client->clientState == ClientStateRetained))) {
1423 XDGAModeRec mode;
1424 PixmapPtr pPix;
1425
1426 DGA_SETCLIENT(i, NULL);
1427 DGASelectInput(i, NULL, 0);
1428 DGASetMode(i, 0, &mode, &pPix);
1429
1430 if (--DGACallbackRefCount == 0)
1431 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
1432 }
1433}
1434
1435static int
1436ProcXDGASetMode(ClientPtr client)
1437{
1438 REQUEST(xXDGASetModeReq);
1439 xXDGASetModeReply rep;
1440 XDGAModeRec mode;
1441 xXDGAModeInfo info;
1442 PixmapPtr pPix;
1443 ClientPtr owner;
1444 int size;
1445
1446 if (stuff->screen >= screenInfo.numScreens)
1447 return BadValue;
1448 owner = DGA_GETCLIENT(stuff->screen);
1449
1450 REQUEST_SIZE_MATCH(xXDGASetModeReq);
1451 rep.type = X_Reply;
1452 rep.length = 0;
1453 rep.offset = 0;
1454 rep.flags = 0;
1455 rep.sequenceNumber = client->sequence;
1456
1457 if (!DGAAvailable(stuff->screen))
1458 return DGAErrorBase + XF86DGANoDirectVideoMode;
1459
1460 if (owner && owner != client)
1461 return DGAErrorBase + XF86DGANoDirectVideoMode;
1462
1463 if (!stuff->mode) {
1464 if (owner) {
1465 if (--DGACallbackRefCount == 0)
1466 DeleteCallback(&ClientStateCallback, DGAClientStateChange,
1467 NULL);
1468 }
1469 DGA_SETCLIENT(stuff->screen, NULL);
1470 DGASelectInput(stuff->screen, NULL, 0);
1471 DGASetMode(stuff->screen, 0, &mode, &pPix);
1472 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep);
1473 return Success;
1474 }
1475
1476 if (Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
1477 return BadValue;
1478
1479 if (!owner) {
1480 if (DGACallbackRefCount++ == 0)
1481 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL);
1482 }
1483
1484 DGA_SETCLIENT(stuff->screen, client);
1485
1486 if (pPix) {
1487 if (AddResource(stuff->pid, RT_PIXMAP, (pointer) (pPix))) {
1488 pPix->drawable.id = (int) stuff->pid;
1489 rep.flags = DGA_PIXMAP_AVAILABLE;
1490 }
1491 }
1492
1493 size = strlen(mode.name) + 1;
1494
1495 info.byte_order = mode.byteOrder;
1496 info.depth = mode.depth;
1497 info.num = mode.num;
1498 info.bpp = mode.bitsPerPixel;
1499 info.name_size = (size + 3) & ~3L;
1500 info.vsync_num = mode.VSync_num;
1501 info.vsync_den = mode.VSync_den;
1502 info.flags = mode.flags;
1503 info.image_width = mode.imageWidth;
1504 info.image_height = mode.imageHeight;
1505 info.pixmap_width = mode.pixmapWidth;
1506 info.pixmap_height = mode.pixmapHeight;
1507 info.bytes_per_scanline = mode.bytesPerScanline;
1508 info.red_mask = mode.red_mask;
1509 info.green_mask = mode.green_mask;
1510 info.blue_mask = mode.blue_mask;
1511 info.visual_class = mode.visualClass;
1512 info.viewport_width = mode.viewportWidth;
1513 info.viewport_height = mode.viewportHeight;
1514 info.viewport_xstep = mode.xViewportStep;
1515 info.viewport_ystep = mode.yViewportStep;
1516 info.viewport_xmax = mode.maxViewportX;
1517 info.viewport_ymax = mode.maxViewportY;
1518 info.viewport_flags = mode.viewportFlags;
1519 info.reserved1 = mode.reserved1;
1520 info.reserved2 = mode.reserved2;
1521
1522 rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
1523
1524 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep);
1525 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info));
1526 WriteToClient(client, size, mode.name);
1527
1528 return Success;
1529}
1530
1531static int
1532ProcXDGASetViewport(ClientPtr client)
1533{
1534 REQUEST(xXDGASetViewportReq);
1535
1536 if (stuff->screen >= screenInfo.numScreens)
1537 return BadValue;
1538
1539 if (DGA_GETCLIENT(stuff->screen) != client)
1540 return DGAErrorBase + XF86DGADirectNotActivated;
1541
1542 REQUEST_SIZE_MATCH(xXDGASetViewportReq);
1543
1544 DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
1545
1546 return Success;
1547}
1548
1549static int
1550ProcXDGAInstallColormap(ClientPtr client)
1551{
1552 ColormapPtr cmap;
1553 int rc;
1554
1555 REQUEST(xXDGAInstallColormapReq);
1556
1557 if (stuff->screen >= screenInfo.numScreens)
1558 return BadValue;
1559
1560 if (DGA_GETCLIENT(stuff->screen) != client)
1561 return DGAErrorBase + XF86DGADirectNotActivated;
1562
1563 REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
1564
1565 rc = dixLookupResourceByType((pointer *) &cmap, stuff->cmap, RT_COLORMAP,
1566 client, DixInstallAccess);
1567 if (rc != Success)
1568 return rc;
1569 DGAInstallCmap(cmap);
1570 return Success;
1571}
1572
1573static int
1574ProcXDGASelectInput(ClientPtr client)
1575{
1576 REQUEST(xXDGASelectInputReq);
1577
1578 if (stuff->screen >= screenInfo.numScreens)
1579 return BadValue;
1580
1581 if (DGA_GETCLIENT(stuff->screen) != client)
1582 return DGAErrorBase + XF86DGADirectNotActivated;
1583
1584 REQUEST_SIZE_MATCH(xXDGASelectInputReq);
1585
1586 if (DGA_GETCLIENT(stuff->screen) == client)
1587 DGASelectInput(stuff->screen, client, stuff->mask);
1588
1589 return Success;
1590}
1591
1592static int
1593ProcXDGAFillRectangle(ClientPtr client)
1594{
1595 REQUEST(xXDGAFillRectangleReq);
1596
1597 if (stuff->screen >= screenInfo.numScreens)
1598 return BadValue;
1599
1600 if (DGA_GETCLIENT(stuff->screen) != client)
1601 return DGAErrorBase + XF86DGADirectNotActivated;
1602
1603 REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
1604
1605 if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
1606 stuff->width, stuff->height, stuff->color))
1607 return BadMatch;
1608
1609 return Success;
1610}
1611
1612static int
1613ProcXDGACopyArea(ClientPtr client)
1614{
1615 REQUEST(xXDGACopyAreaReq);
1616
1617 if (stuff->screen >= screenInfo.numScreens)
1618 return BadValue;
1619
1620 if (DGA_GETCLIENT(stuff->screen) != client)
1621 return DGAErrorBase + XF86DGADirectNotActivated;
1622
1623 REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
1624
1625 if (Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
1626 stuff->width, stuff->height, stuff->dstx,
1627 stuff->dsty))
1628 return BadMatch;
1629
1630 return Success;
1631}
1632
1633static int
1634ProcXDGACopyTransparentArea(ClientPtr client)
1635{
1636 REQUEST(xXDGACopyTransparentAreaReq);
1637
1638 if (stuff->screen >= screenInfo.numScreens)
1639 return BadValue;
1640
1641 if (DGA_GETCLIENT(stuff->screen) != client)
1642 return DGAErrorBase + XF86DGADirectNotActivated;
1643
1644 REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
1645
1646 if (Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
1647 stuff->width, stuff->height, stuff->dstx,
1648 stuff->dsty, stuff->key))
1649 return BadMatch;
1650
1651 return Success;
1652}
1653
1654static int
1655ProcXDGAGetViewportStatus(ClientPtr client)
1656{
1657 REQUEST(xXDGAGetViewportStatusReq);
1658 xXDGAGetViewportStatusReply rep;
1659
1660 if (stuff->screen >= screenInfo.numScreens)
1661 return BadValue;
1662
1663 if (DGA_GETCLIENT(stuff->screen) != client)
1664 return DGAErrorBase + XF86DGADirectNotActivated;
1665
1666 REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
1667 rep.type = X_Reply;
1668 rep.length = 0;
1669 rep.sequenceNumber = client->sequence;
1670
1671 rep.status = DGAGetViewportStatus(stuff->screen);
1672
1673 WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *) &rep);
1674 return Success;
1675}
1676
1677static int
1678ProcXDGASync(ClientPtr client)
1679{
1680 REQUEST(xXDGASyncReq);
1681 xXDGASyncReply rep;
1682
1683 if (stuff->screen >= screenInfo.numScreens)
1684 return BadValue;
1685
1686 if (DGA_GETCLIENT(stuff->screen) != client)
1687 return DGAErrorBase + XF86DGADirectNotActivated;
1688
1689 REQUEST_SIZE_MATCH(xXDGASyncReq);
1690 rep.type = X_Reply;
1691 rep.length = 0;
1692 rep.sequenceNumber = client->sequence;
1693
1694 DGASync(stuff->screen);
1695
1696 WriteToClient(client, sizeof(xXDGASyncReply), (char *) &rep);
1697 return Success;
1698}
1699
1700static int
1701ProcXDGASetClientVersion(ClientPtr client)
1702{
1703 REQUEST(xXDGASetClientVersionReq);
1704
1705 DGAPrivPtr pPriv;
1706
1707 REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
1708 if ((pPriv = DGA_GETPRIV(client)) == NULL) {
1709 pPriv = malloc(sizeof(DGAPrivRec));
1710 /* XXX Need to look into freeing this */
1711 if (!pPriv)
1712 return BadAlloc;
1713 DGA_SETPRIV(client, pPriv);
1714 }
1715 pPriv->major = stuff->major;
1716 pPriv->minor = stuff->minor;
1717
1718 return Success;
1719}
1720
1721static int
1722ProcXDGAChangePixmapMode(ClientPtr client)
1723{
1724 REQUEST(xXDGAChangePixmapModeReq);
1725 xXDGAChangePixmapModeReply rep;
1726 int x, y;
1727
1728 if (stuff->screen >= screenInfo.numScreens)
1729 return BadValue;
1730
1731 if (DGA_GETCLIENT(stuff->screen) != client)
1732 return DGAErrorBase + XF86DGADirectNotActivated;
1733
1734 REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
1735 rep.type = X_Reply;
1736 rep.length = 0;
1737 rep.sequenceNumber = client->sequence;
1738
1739 x = stuff->x;
1740 y = stuff->y;
1741
1742 if (!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
1743 return BadMatch;
1744
1745 rep.x = x;
1746 rep.y = y;
1747 WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *) &rep);
1748
1749 return Success;
1750}
1751
1752static int
1753ProcXDGACreateColormap(ClientPtr client)
1754{
1755 REQUEST(xXDGACreateColormapReq);
1756 int result;
1757
1758 if (stuff->screen >= screenInfo.numScreens)
1759 return BadValue;
1760
1761 if (DGA_GETCLIENT(stuff->screen) != client)
1762 return DGAErrorBase + XF86DGADirectNotActivated;
1763
1764 REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
1765
1766 if (!stuff->mode)
1767 return BadValue;
1768
1769 result = DGACreateColormap(stuff->screen, client, stuff->id,
1770 stuff->mode, stuff->alloc);
1771 if (result != Success)
1772 return result;
1773
1774 return Success;
1775}
1776
1777/*
1778 *
1779 * Support for the old DGA protocol, used to live in xf86dga.c
1780 *
1781 */
1782
1783#ifdef DGA_PROTOCOL_OLD_SUPPORT
1784
1785static int
1786ProcXF86DGAGetVideoLL(ClientPtr client)
1787{
1788 REQUEST(xXF86DGAGetVideoLLReq);
1789 xXF86DGAGetVideoLLReply rep;
1790 XDGAModeRec mode;
1791 int num, offset, flags;
1792 char *name;
1793
1794 if (stuff->screen >= screenInfo.numScreens)
1795 return BadValue;
1796
1797 REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
1798 rep.type = X_Reply;
1799 rep.length = 0;
1800 rep.sequenceNumber = client->sequence;
1801
1802 if (!DGAAvailable(stuff->screen))
1803 return DGAErrorBase + XF86DGANoDirectVideoMode;
1804
1805 if (!(num = DGAGetOldDGAMode(stuff->screen)))
1806 return DGAErrorBase + XF86DGANoDirectVideoMode;
1807
1808 /* get the parameters for the mode that best matches */
1809 DGAGetModeInfo(stuff->screen, &mode, num);
1810
1811 if (!DGAOpenFramebuffer(stuff->screen, &name,
1812 (unsigned char **) (&rep.offset),
1813 (int *) (&rep.bank_size), &offset, &flags))
1814 return BadAlloc;
1815
1816 rep.offset += mode.offset;
1817 rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
1818 rep.ram_size = rep.bank_size >> 10;
1819
1820 WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *) &rep);
1821 return Success;
1822}
1823
1824static int
1825ProcXF86DGADirectVideo(ClientPtr client)
1826{
1827 int num;
1828 PixmapPtr pix;
1829 XDGAModeRec mode;
1830 ClientPtr owner;
1831
1832 REQUEST(xXF86DGADirectVideoReq);
1833
1834 if (stuff->screen >= screenInfo.numScreens)
1835 return BadValue;
1836 REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
1837
1838 if (!DGAAvailable(stuff->screen))
1839 return DGAErrorBase + XF86DGANoDirectVideoMode;
1840
1841 owner = DGA_GETCLIENT(stuff->screen);
1842
1843 if (owner && owner != client)
1844 return DGAErrorBase + XF86DGANoDirectVideoMode;
1845
1846 if (stuff->enable & XF86DGADirectGraphics) {
1847 if (!(num = DGAGetOldDGAMode(stuff->screen)))
1848 return DGAErrorBase + XF86DGANoDirectVideoMode;
1849 }
1850 else
1851 num = 0;
1852
1853 if (Success != DGASetMode(stuff->screen, num, &mode, &pix))
1854 return DGAErrorBase + XF86DGAScreenNotActive;
1855
1856 DGASetInputMode(stuff->screen,
1857 (stuff->enable & XF86DGADirectKeyb) != 0,
1858 (stuff->enable & XF86DGADirectMouse) != 0);
1859
1860 /* We need to track the client and attach the teardown callback */
1861 if (stuff->enable &
1862 (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
1863 if (!owner) {
1864 if (DGACallbackRefCount++ == 0)
1865 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL);
1866 }
1867
1868 DGA_SETCLIENT(stuff->screen, client);
1869 }
1870 else {
1871 if (owner) {
1872 if (--DGACallbackRefCount == 0)
1873 DeleteCallback(&ClientStateCallback, DGAClientStateChange,
1874 NULL);
1875 }
1876
1877 DGA_SETCLIENT(stuff->screen, NULL);
1878 }
1879
1880 return Success;
1881}
1882
1883static int
1884ProcXF86DGAGetViewPortSize(ClientPtr client)
1885{
1886 int num;
1887 XDGAModeRec mode;
1888
1889 REQUEST(xXF86DGAGetViewPortSizeReq);
1890 xXF86DGAGetViewPortSizeReply rep;
1891
1892 if (stuff->screen >= screenInfo.numScreens)
1893 return BadValue;
1894
1895 REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
1896 rep.type = X_Reply;
1897 rep.length = 0;
1898 rep.sequenceNumber = client->sequence;
1899
1900 if (!DGAAvailable(stuff->screen))
1901 return DGAErrorBase + XF86DGANoDirectVideoMode;
1902
1903 if (!(num = DGAGetOldDGAMode(stuff->screen)))
1904 return DGAErrorBase + XF86DGANoDirectVideoMode;
1905
1906 DGAGetModeInfo(stuff->screen, &mode, num);
1907
1908 rep.width = mode.viewportWidth;
1909 rep.height = mode.viewportHeight;
1910
1911 WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *) &rep);
1912 return Success;
1913}
1914
1915static int
1916ProcXF86DGASetViewPort(ClientPtr client)
1917{
1918 REQUEST(xXF86DGASetViewPortReq);
1919
1920 if (stuff->screen >= screenInfo.numScreens)
1921 return BadValue;
1922
1923 if (DGA_GETCLIENT(stuff->screen) != client)
1924 return DGAErrorBase + XF86DGADirectNotActivated;
1925
1926 REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
1927
1928 if (!DGAAvailable(stuff->screen))
1929 return DGAErrorBase + XF86DGANoDirectVideoMode;
1930
1931 if (!DGAActive(stuff->screen))
1932 return DGAErrorBase + XF86DGADirectNotActivated;
1933
1934 if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
1935 != Success)
1936 return DGAErrorBase + XF86DGADirectNotActivated;
1937
1938 return Success;
1939}
1940
1941static int
1942ProcXF86DGAGetVidPage(ClientPtr client)
1943{
1944 REQUEST(xXF86DGAGetVidPageReq);
1945 xXF86DGAGetVidPageReply rep;
1946
1947 if (stuff->screen >= screenInfo.numScreens)
1948 return BadValue;
1949
1950 REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
1951 rep.type = X_Reply;
1952 rep.length = 0;
1953 rep.sequenceNumber = client->sequence;
1954 rep.vpage = 0; /* silently fail */
1955
1956 WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *) &rep);
1957 return Success;
1958}
1959
1960static int
1961ProcXF86DGASetVidPage(ClientPtr client)
1962{
1963 REQUEST(xXF86DGASetVidPageReq);
1964
1965 if (stuff->screen >= screenInfo.numScreens)
1966 return BadValue;
1967
1968 REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
1969
1970 /* silently fail */
1971
1972 return Success;
1973}
1974
1975static int
1976ProcXF86DGAInstallColormap(ClientPtr client)
1977{
1978 ColormapPtr pcmp;
1979 int rc;
1980
1981 REQUEST(xXF86DGAInstallColormapReq);
1982
1983 if (stuff->screen >= screenInfo.numScreens)
1984 return BadValue;
1985
1986 if (DGA_GETCLIENT(stuff->screen) != client)
1987 return DGAErrorBase + XF86DGADirectNotActivated;
1988
1989 REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
1990
1991 if (!DGAActive(stuff->screen))
1992 return DGAErrorBase + XF86DGADirectNotActivated;
1993
1994 rc = dixLookupResourceByType((pointer *) &pcmp, stuff->id, RT_COLORMAP,
1995 client, DixInstallAccess);
1996 if (rc == Success) {
1997 DGAInstallCmap(pcmp);
1998 return Success;
1999 }
2000 else {
2001 return rc;
2002 }
2003}
2004
2005static int
2006ProcXF86DGAQueryDirectVideo(ClientPtr client)
2007{
2008 REQUEST(xXF86DGAQueryDirectVideoReq);
2009 xXF86DGAQueryDirectVideoReply rep;
2010
2011 if (stuff->screen >= screenInfo.numScreens)
2012 return BadValue;
2013
2014 REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
2015 rep.type = X_Reply;
2016 rep.length = 0;
2017 rep.sequenceNumber = client->sequence;
2018 rep.flags = 0;
2019
2020 if (DGAAvailable(stuff->screen))
2021 rep.flags = XF86DGADirectPresent;
2022
2023 WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *) &rep);
2024 return Success;
2025}
2026
2027static int
2028ProcXF86DGAViewPortChanged(ClientPtr client)
2029{
2030 REQUEST(xXF86DGAViewPortChangedReq);
2031 xXF86DGAViewPortChangedReply rep;
2032
2033 if (stuff->screen >= screenInfo.numScreens)
2034 return BadValue;
2035
2036 if (DGA_GETCLIENT(stuff->screen) != client)
2037 return DGAErrorBase + XF86DGADirectNotActivated;
2038
2039 REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
2040
2041 if (!DGAActive(stuff->screen))
2042 return DGAErrorBase + XF86DGADirectNotActivated;
2043
2044 rep.type = X_Reply;
2045 rep.length = 0;
2046 rep.sequenceNumber = client->sequence;
2047 rep.result = 1;
2048
2049 WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *) &rep);
2050 return Success;
2051}
2052
2053#endif /* DGA_PROTOCOL_OLD_SUPPORT */
2054
2055static int
2056SProcXDGADispatch(ClientPtr client)
2057{
2058 return DGAErrorBase + XF86DGAClientNotLocal;
2059}
2060
2061#if 0
2062#define DGA_REQ_DEBUG
2063#endif
2064
2065#ifdef DGA_REQ_DEBUG
2066static char *dgaMinor[] = {
2067 "QueryVersion",
2068 "GetVideoLL",
2069 "DirectVideo",
2070 "GetViewPortSize",
2071 "SetViewPort",
2072 "GetVidPage",
2073 "SetVidPage",
2074 "InstallColormap",
2075 "QueryDirectVideo",
2076 "ViewPortChanged",
2077 "10",
2078 "11",
2079 "QueryModes",
2080 "SetMode",
2081 "SetViewport",
2082 "InstallColormap",
2083 "SelectInput",
2084 "FillRectangle",
2085 "CopyArea",
2086 "CopyTransparentArea",
2087 "GetViewportStatus",
2088 "Sync",
2089 "OpenFramebuffer",
2090 "CloseFramebuffer",
2091 "SetClientVersion",
2092 "ChangePixmapMode",
2093 "CreateColormap",
2094};
2095#endif
2096
2097static int
2098ProcXDGADispatch(ClientPtr client)
2099{
2100 REQUEST(xReq);
2101
2102 if (!client->local)
2103 return DGAErrorBase + XF86DGAClientNotLocal;
2104
2105#ifdef DGA_REQ_DEBUG
2106 if (stuff->data <= X_XDGACreateColormap)
2107 fprintf(stderr, " DGA %s\n", dgaMinor[stuff->data]);
2108#endif
2109
2110 switch (stuff->data) {
2111 /*
2112 * DGA2 Protocol
2113 */
2114 case X_XDGAQueryVersion:
2115 return ProcXDGAQueryVersion(client);
2116 case X_XDGAQueryModes:
2117 return ProcXDGAQueryModes(client);
2118 case X_XDGASetMode:
2119 return ProcXDGASetMode(client);
2120 case X_XDGAOpenFramebuffer:
2121 return ProcXDGAOpenFramebuffer(client);
2122 case X_XDGACloseFramebuffer:
2123 return ProcXDGACloseFramebuffer(client);
2124 case X_XDGASetViewport:
2125 return ProcXDGASetViewport(client);
2126 case X_XDGAInstallColormap:
2127 return ProcXDGAInstallColormap(client);
2128 case X_XDGASelectInput:
2129 return ProcXDGASelectInput(client);
2130 case X_XDGAFillRectangle:
2131 return ProcXDGAFillRectangle(client);
2132 case X_XDGACopyArea:
2133 return ProcXDGACopyArea(client);
2134 case X_XDGACopyTransparentArea:
2135 return ProcXDGACopyTransparentArea(client);
2136 case X_XDGAGetViewportStatus:
2137 return ProcXDGAGetViewportStatus(client);
2138 case X_XDGASync:
2139 return ProcXDGASync(client);
2140 case X_XDGASetClientVersion:
2141 return ProcXDGASetClientVersion(client);
2142 case X_XDGAChangePixmapMode:
2143 return ProcXDGAChangePixmapMode(client);
2144 case X_XDGACreateColormap:
2145 return ProcXDGACreateColormap(client);
2146 /*
2147 * Old DGA Protocol
2148 */
2149#ifdef DGA_PROTOCOL_OLD_SUPPORT
2150 case X_XF86DGAGetVideoLL:
2151 return ProcXF86DGAGetVideoLL(client);
2152 case X_XF86DGADirectVideo:
2153 return ProcXF86DGADirectVideo(client);
2154 case X_XF86DGAGetViewPortSize:
2155 return ProcXF86DGAGetViewPortSize(client);
2156 case X_XF86DGASetViewPort:
2157 return ProcXF86DGASetViewPort(client);
2158 case X_XF86DGAGetVidPage:
2159 return ProcXF86DGAGetVidPage(client);
2160 case X_XF86DGASetVidPage:
2161 return ProcXF86DGASetVidPage(client);
2162 case X_XF86DGAInstallColormap:
2163 return ProcXF86DGAInstallColormap(client);
2164 case X_XF86DGAQueryDirectVideo:
2165 return ProcXF86DGAQueryDirectVideo(client);
2166 case X_XF86DGAViewPortChanged:
2167 return ProcXF86DGAViewPortChanged(client);
2168#endif /* DGA_PROTOCOL_OLD_SUPPORT */
2169 default:
2170 return BadRequest;
2171 }
2172}
2173
2174void
2175XFree86DGAExtensionInit(void)
2176{
2177 ExtensionEntry *extEntry;
2178
2179 if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0))
2180 return;
2181
2182 if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
2183 return;
2184
2185 if ((extEntry = AddExtension(XF86DGANAME,
2186 XF86DGANumberEvents,
2187 XF86DGANumberErrors,
2188 ProcXDGADispatch,
2189 SProcXDGADispatch,
2190 XDGAResetProc, StandardMinorOpcode))) {
2191 int i;
2192
2193 DGAReqCode = (unsigned char) extEntry->base;
2194 DGAErrorBase = extEntry->errorBase;
2195 DGAEventBase = extEntry->eventBase;
2196 for (i = KeyPress; i <= MotionNotify; i++)
2197 SetCriticalEvent(DGAEventBase + i);
2198 }
2199}