2 * Copyright (c) 1995 Jon Tombs
3 * Copyright (c) 1995, 1996, 1999 XFree86 Inc
4 * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
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).
29 * Written by Mark Vojkovich
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.
40 #ifdef HAVE_XORG_CONFIG_H
41 #include <xorg-config.h>
45 #include <X11/Xproto.h>
50 #include <X11/extensions/xf86dgaproto.h>
51 #include "colormapst.h"
52 #include "pixmapstr.h"
58 #include "xf86Xinput.h"
59 #include "exglobals.h"
62 #include "eventconvert.h"
63 #include "xf86Extensions.h"
68 #include "dixstruct.h"
69 #include "dixevents.h"
70 #include "extnsionst.h"
71 #include "cursorstr.h"
72 #include "scrnintstr.h"
75 #include "protocol-versions.h"
79 #define DGA_PROTOCOL_OLD_SUPPORT 1
81 static DevPrivateKeyRec DGAScreenKeyRec
;
83 #define DGAScreenKeyRegistered dixPrivateKeyRegistered(&DGAScreenKeyRec)
84 static Bool mieq_installed
;
86 static Bool
DGACloseScreen(ScreenPtr pScreen
);
87 static void DGADestroyColormap(ColormapPtr pmap
);
88 static void DGAInstallColormap(ColormapPtr pmap
);
89 static void DGAUninstallColormap(ColormapPtr pmap
);
90 static void DGAHandleEvent(int screen_num
, InternalEvent
*event
,
94 DGACopyModeInfo(DGAModePtr mode
, XDGAModePtr xmode
);
96 static unsigned char DGAReqCode
= 0;
97 static int DGAErrorBase
;
98 static int DGAEventBase
;
100 #define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
101 dixLookupPrivate(&(pScreen)->devPrivates, &DGAScreenKeyRec))
103 typedef struct _FakedVisualList
{
106 struct _FakedVisualList
*next
;
113 CloseScreenProcPtr CloseScreen
;
114 DestroyColormapProcPtr DestroyColormap
;
115 InstallColormapProcPtr InstallColormap
;
116 UninstallColormapProcPtr UninstallColormap
;
117 DGADevicePtr current
;
118 DGAFunctionPtr funcs
;
122 FakedVisualList
*fakedVisuals
;
123 ColormapPtr dgaColormap
;
124 ColormapPtr savedColormap
;
127 } DGAScreenRec
, *DGAScreenPtr
;
130 DGAInit(ScreenPtr pScreen
, DGAFunctionPtr funcs
, DGAModePtr modes
, int num
)
132 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
133 DGAScreenPtr pScreenPriv
;
136 if (!funcs
|| !funcs
->SetMode
|| !funcs
->OpenFramebuffer
)
139 if (!modes
|| num
<= 0)
142 if (!dixRegisterPrivateKey(&DGAScreenKeyRec
, PRIVATE_SCREEN
, 0))
145 pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
148 if (!(pScreenPriv
= (DGAScreenPtr
) malloc(sizeof(DGAScreenRec
))))
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
;
161 pScreenPriv
->pScrn
= pScrn
;
162 pScreenPriv
->numModes
= num
;
163 pScreenPriv
->modes
= modes
;
164 pScreenPriv
->current
= NULL
;
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
;
175 for (i
= 0; i
< num
; i
++)
176 modes
[i
].num
= i
+ 1;
179 if (!noPanoramiXExtension
)
180 for (i
= 0; i
< num
; i
++)
181 modes
[i
].flags
&= ~DGA_PIXMAP_AVAILABLE
;
187 /* DGAReInitModes allows the driver to re-initialize
192 DGAReInitModes(ScreenPtr pScreen
, DGAModePtr modes
, int num
)
194 DGAScreenPtr pScreenPriv
;
197 /* No DGA? Ignore call (but don't make it look like it failed) */
198 if (!DGAScreenKeyRegistered
)
201 pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
207 /* Can't do this while DGA is active */
208 if (pScreenPriv
->current
)
211 /* Quick sanity check */
217 pScreenPriv
->numModes
= num
;
218 pScreenPriv
->modes
= modes
;
220 /* This practically disables DGA. So be it. */
224 for (i
= 0; i
< num
; i
++)
225 modes
[i
].num
= i
+ 1;
228 if (!noPanoramiXExtension
)
229 for (i
= 0; i
< num
; i
++)
230 modes
[i
].flags
&= ~DGA_PIXMAP_AVAILABLE
;
237 FreeMarkedVisuals(ScreenPtr pScreen
)
239 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
240 FakedVisualList
*prev
, *curr
, *tmp
;
242 if (!pScreenPriv
->fakedVisuals
)
246 curr
= pScreenPriv
->fakedVisuals
;
255 pScreenPriv
->fakedVisuals
= curr
;
267 DGACloseScreen(ScreenPtr pScreen
)
269 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
271 if (mieq_installed
) {
272 mieqSetHandler(ET_DGAEvent
, NULL
);
273 mieq_installed
= FALSE
;
276 FreeMarkedVisuals(pScreen
);
278 pScreen
->CloseScreen
= pScreenPriv
->CloseScreen
;
279 pScreen
->DestroyColormap
= pScreenPriv
->DestroyColormap
;
280 pScreen
->InstallColormap
= pScreenPriv
->InstallColormap
;
281 pScreen
->UninstallColormap
= pScreenPriv
->UninstallColormap
;
283 /* DGAShutdown() should have ensured that no DGA
284 screen were active by here */
288 return ((*pScreen
->CloseScreen
) (pScreen
));
292 DGADestroyColormap(ColormapPtr pmap
)
294 ScreenPtr pScreen
= pmap
->pScreen
;
295 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
296 VisualPtr pVisual
= pmap
->pVisual
;
298 if (pScreenPriv
->fakedVisuals
) {
299 FakedVisualList
*curr
= pScreenPriv
->fakedVisuals
;
302 if (curr
->pVisual
== pVisual
) {
303 /* We can't get rid of them yet since FreeColormap
304 still needs the pVisual during the cleanup */
312 if (pScreenPriv
->DestroyColormap
) {
313 pScreen
->DestroyColormap
= pScreenPriv
->DestroyColormap
;
314 (*pScreen
->DestroyColormap
) (pmap
);
315 pScreen
->DestroyColormap
= DGADestroyColormap
;
320 DGAInstallColormap(ColormapPtr pmap
)
322 ScreenPtr pScreen
= pmap
->pScreen
;
323 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
325 if (pScreenPriv
->current
&& pScreenPriv
->dgaColormap
) {
326 if (pmap
!= pScreenPriv
->dgaColormap
) {
327 pScreenPriv
->savedColormap
= pmap
;
328 pmap
= pScreenPriv
->dgaColormap
;
332 pScreen
->InstallColormap
= pScreenPriv
->InstallColormap
;
333 (*pScreen
->InstallColormap
) (pmap
);
334 pScreen
->InstallColormap
= DGAInstallColormap
;
338 DGAUninstallColormap(ColormapPtr pmap
)
340 ScreenPtr pScreen
= pmap
->pScreen
;
341 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
343 if (pScreenPriv
->current
&& pScreenPriv
->dgaColormap
) {
344 if (pmap
== pScreenPriv
->dgaColormap
) {
345 pScreenPriv
->dgaColormap
= NULL
;
349 pScreen
->UninstallColormap
= pScreenPriv
->UninstallColormap
;
350 (*pScreen
->UninstallColormap
) (pmap
);
351 pScreen
->UninstallColormap
= DGAUninstallColormap
;
355 xf86SetDGAMode(ScrnInfoPtr pScrn
, int num
, DGADevicePtr devRet
)
357 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
358 DGAScreenPtr pScreenPriv
;
360 PixmapPtr pPix
= NULL
;
361 DGAModePtr pMode
= NULL
;
363 /* First check if DGAInit was successful on this screen */
364 if (!DGAScreenKeyRegistered
)
366 pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
371 if (pScreenPriv
->current
) {
372 PixmapPtr oldPix
= pScreenPriv
->current
->pPix
;
375 if (oldPix
->drawable
.id
)
376 FreeResource(oldPix
->drawable
.id
, RT_NONE
);
378 (*pScreen
->DestroyPixmap
) (oldPix
);
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
;
388 pScreenPriv
->dgaColormap
= NULL
;
389 (*pScrn
->EnableDisableFBAccess
) (pScrn
, TRUE
);
391 FreeMarkedVisuals(pScreen
);
394 pScreenPriv
->grabMouse
= FALSE
;
395 pScreenPriv
->grabKeyboard
= FALSE
;
400 if (!pScrn
->vtSema
&& !pScreenPriv
->current
) /* Really switched away */
403 if ((num
> 0) && (num
<= pScreenPriv
->numModes
))
404 pMode
= &(pScreenPriv
->modes
[num
- 1]);
408 if (!(device
= (DGADevicePtr
) malloc(sizeof(DGADeviceRec
))))
411 if (!pScreenPriv
->current
) {
412 Bool oldVTSema
= pScrn
->vtSema
;
414 pScrn
->vtSema
= FALSE
; /* kludge until we rewrite VT switching */
415 (*pScrn
->EnableDisableFBAccess
) (pScrn
, FALSE
);
416 pScrn
->vtSema
= oldVTSema
;
419 if (!(*pScreenPriv
->funcs
->SetMode
) (pScrn
, pMode
)) {
424 pScrn
->currentMode
= pMode
->mode
;
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 */
431 pScrn
->vtSema
= FALSE
;
433 if (pScreenPriv
->current
) {
434 PixmapPtr oldPix
= pScreenPriv
->current
->pPix
;
437 if (oldPix
->drawable
.id
)
438 FreeResource(oldPix
->drawable
.id
, RT_NONE
);
440 (*pScreen
->DestroyPixmap
) (oldPix
);
442 free(pScreenPriv
->current
);
443 pScreenPriv
->current
= NULL
;
446 if (pMode
->flags
& DGA_PIXMAP_AVAILABLE
) {
447 if ((pPix
= (*pScreen
->CreatePixmap
) (pScreen
, 0, 0, pMode
->depth
, 0))) {
448 (*pScreen
->ModifyPixmapHeader
) (pPix
,
450 pMode
->pixmapHeight
, pMode
->depth
,
452 pMode
->bytesPerScanline
,
453 (pointer
) (pMode
->address
));
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
;
464 if (!mieq_installed
) {
465 mieqSetHandler(ET_DGAEvent
, DGAHandleEvent
);
466 mieq_installed
= TRUE
;
472 /*********** exported ones ***************/
475 DGASetInputMode(int index
, Bool keyboard
, Bool mouse
)
477 ScreenPtr pScreen
= screenInfo
.screens
[index
];
478 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
481 pScreenPriv
->grabMouse
= mouse
;
482 pScreenPriv
->grabKeyboard
= keyboard
;
484 if (!mieq_installed
) {
485 mieqSetHandler(ET_DGAEvent
, DGAHandleEvent
);
486 mieq_installed
= TRUE
;
492 DGAChangePixmapMode(int index
, int *x
, int *y
, int mode
)
494 DGAScreenPtr pScreenPriv
;
499 if (!DGAScreenKeyRegistered
)
502 pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
504 if (!pScreenPriv
|| !pScreenPriv
->current
|| !pScreenPriv
->current
->pPix
)
507 pDev
= pScreenPriv
->current
;
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
;
519 switch (xf86Screens
[index
]->bitsPerPixel
) {
530 if (BITMAP_SCANLINE_PAD
== 64)
533 *x
= (*x
>> shift
) << shift
;
535 pPix
->drawable
.x
= *x
;
536 pPix
->drawable
.y
= *y
;
537 pPix
->drawable
.width
= pMode
->viewportWidth
;
538 pPix
->drawable
.height
= pMode
->viewportHeight
;
541 pPix
->drawable
.x
= 0;
542 pPix
->drawable
.y
= 0;
543 pPix
->drawable
.width
= pMode
->pixmapWidth
;
544 pPix
->drawable
.height
= pMode
->pixmapHeight
;
546 pPix
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
547 pScreenPriv
->pixmapMode
= mode
;
553 DGAScreenAvailable(ScreenPtr pScreen
)
555 if (!DGAScreenKeyRegistered
)
558 if (DGA_GET_SCREEN_PRIV(pScreen
))
564 DGAAvailable(int index
)
568 assert(index
< MAXSCREENS
);
569 pScreen
= screenInfo
.screens
[index
];
570 return DGAScreenAvailable(pScreen
);
576 DGAScreenPtr pScreenPriv
;
578 if (!DGAScreenKeyRegistered
)
581 pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
583 if (pScreenPriv
&& pScreenPriv
->current
)
589 /* Called by the event code in case the server is abruptly terminated */
597 if (!DGAScreenKeyRegistered
)
600 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
601 pScrn
= xf86Screens
[i
];
603 (void) (*pScrn
->SetDGAMode
) (pScrn
, 0, NULL
);
607 /* Called by the extension to initialize a mode */
610 DGASetMode(int index
, int num
, XDGAModePtr mode
, PixmapPtr
*pPix
)
612 ScrnInfoPtr pScrn
= xf86Screens
[index
];
616 /* We rely on the extension to check that DGA is available */
618 ret
= (*pScrn
->SetDGAMode
) (pScrn
, num
, &device
);
619 if ((ret
== Success
) && num
) {
620 DGACopyModeInfo(device
.mode
, mode
);
627 /* Called from the extension to let the DDX know which events are requested */
630 DGASelectInput(int index
, ClientPtr client
, long mask
)
632 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
634 /* We rely on the extension to check that DGA is available */
635 pScreenPriv
->client
= client
;
636 pScreenPriv
->input
= mask
;
640 DGAGetViewportStatus(int index
)
642 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
644 /* We rely on the extension to check that DGA is active */
646 if (!pScreenPriv
->funcs
->GetViewport
)
649 return (*pScreenPriv
->funcs
->GetViewport
) (pScreenPriv
->pScrn
);
653 DGASetViewport(int index
, int x
, int y
, int mode
)
655 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
657 if (pScreenPriv
->funcs
->SetViewport
)
658 (*pScreenPriv
->funcs
->SetViewport
) (pScreenPriv
->pScrn
, x
, y
, mode
);
663 BitsClear(CARD32 data
)
668 for (mask
= 1; mask
; mask
<<= 1) {
679 DGACreateColormap(int index
, ClientPtr client
, int id
, int mode
, int alloc
)
681 ScreenPtr pScreen
= screenInfo
.screens
[index
];
682 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
683 FakedVisualList
*fvlp
;
688 if (!mode
|| (mode
> pScreenPriv
->numModes
))
691 if ((alloc
!= AllocNone
) && (alloc
!= AllocAll
))
694 pMode
= &(pScreenPriv
->modes
[mode
- 1]);
696 if (!(pVisual
= malloc(sizeof(VisualRec
))))
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;
705 switch (pVisual
->class) {
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;
719 pVisual
->ColormapEntries
= 1 << pVisual
->bitsPerRGBValue
;
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
);
730 if (!(fvlp
= malloc(sizeof(FakedVisualList
)))) {
736 fvlp
->pVisual
= pVisual
;
737 fvlp
->next
= pScreenPriv
->fakedVisuals
;
738 pScreenPriv
->fakedVisuals
= fvlp
;
740 LEGAL_NEW_RESOURCE(id
, client
);
742 return CreateColormap(id
, pScreen
, pVisual
, &pmap
, alloc
, client
->index
);
745 /* Called by the extension to install a colormap on DGA active screens */
748 DGAInstallCmap(ColormapPtr cmap
)
750 ScreenPtr pScreen
= cmap
->pScreen
;
751 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
753 /* We rely on the extension to check that DGA is active */
755 if (!pScreenPriv
->dgaColormap
)
756 pScreenPriv
->savedColormap
= GetInstalledmiColormap(pScreen
);
758 pScreenPriv
->dgaColormap
= cmap
;
760 (*pScreen
->InstallColormap
) (cmap
);
766 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
768 /* We rely on the extension to check that DGA is active */
770 if (pScreenPriv
->funcs
->Sync
)
771 (*pScreenPriv
->funcs
->Sync
) (pScreenPriv
->pScrn
);
777 DGAFillRect(int index
, int x
, int y
, int w
, int h
, unsigned long color
)
779 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
781 /* We rely on the extension to check that DGA is active */
783 if (pScreenPriv
->funcs
->FillRect
&&
784 (pScreenPriv
->current
->mode
->flags
& DGA_FILL_RECT
)) {
786 (*pScreenPriv
->funcs
->FillRect
) (pScreenPriv
->pScrn
, x
, y
, w
, h
, color
);
793 DGABlitRect(int index
, int srcx
, int srcy
, int w
, int h
, int dstx
, int dsty
)
795 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
797 /* We rely on the extension to check that DGA is active */
799 if (pScreenPriv
->funcs
->BlitRect
&&
800 (pScreenPriv
->current
->mode
->flags
& DGA_BLIT_RECT
)) {
802 (*pScreenPriv
->funcs
->BlitRect
) (pScreenPriv
->pScrn
,
803 srcx
, srcy
, w
, h
, dstx
, dsty
);
810 DGABlitTransRect(int index
,
812 int w
, int h
, int dstx
, int dsty
, unsigned long color
)
814 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
816 /* We rely on the extension to check that DGA is active */
818 if (pScreenPriv
->funcs
->BlitTransRect
&&
819 (pScreenPriv
->current
->mode
->flags
& DGA_BLIT_RECT_TRANS
)) {
821 (*pScreenPriv
->funcs
->BlitTransRect
) (pScreenPriv
->pScrn
,
822 srcx
, srcy
, w
, h
, dstx
, dsty
,
830 DGAGetModes(int index
)
832 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
834 /* We rely on the extension to check that DGA is available */
836 return pScreenPriv
->numModes
;
840 DGAGetModeInfo(int index
, XDGAModePtr mode
, int num
)
842 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
844 /* We rely on the extension to check that DGA is available */
846 if ((num
<= 0) || (num
> pScreenPriv
->numModes
))
849 DGACopyModeInfo(&(pScreenPriv
->modes
[num
- 1]), mode
);
855 DGACopyModeInfo(DGAModePtr mode
, XDGAModePtr xmode
)
857 DisplayModePtr dmode
= mode
->mode
;
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
;
887 if (dmode
->Flags
& V_INTERLACE
)
888 xmode
->flags
|= DGA_INTERLACED
;
889 if (dmode
->Flags
& V_DBLSCAN
)
890 xmode
->flags
|= DGA_DOUBLESCAN
;
899 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
900 pScreen
= screenInfo
.screens
[i
];
902 /* Alternatively, this could send events to DGA clients */
904 if (DGAScreenKeyRegistered
) {
905 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
907 if (pScreenPriv
&& pScreenPriv
->current
)
916 DGAStealKeyEvent(DeviceIntPtr dev
, int index
, int key_code
, int is_down
)
918 DGAScreenPtr pScreenPriv
;
921 if (!DGAScreenKeyRegistered
) /* no DGA */
924 if (key_code
< 8 || key_code
> 255)
927 pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
929 if (!pScreenPriv
|| !pScreenPriv
->grabKeyboard
) /* no direct mode */
933 .header
= ET_Internal
,
935 .length
= sizeof(event
),
936 .time
= GetTimeInMillis(),
937 .subtype
= (is_down
? ET_KeyPress
: ET_KeyRelease
),
942 mieqEnqueue(dev
, (InternalEvent
*) &event
);
948 DGAStealMotionEvent(DeviceIntPtr dev
, int index
, int dx
, int dy
)
950 DGAScreenPtr pScreenPriv
;
953 if (!DGAScreenKeyRegistered
) /* no DGA */
956 pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
958 if (!pScreenPriv
|| !pScreenPriv
->grabMouse
) /* no direct mode */
962 .header
= ET_Internal
,
964 .length
= sizeof(event
),
965 .time
= GetTimeInMillis(),
966 .subtype
= ET_Motion
,
971 mieqEnqueue(dev
, (InternalEvent
*) &event
);
976 DGAStealButtonEvent(DeviceIntPtr dev
, int index
, int button
, int is_down
)
978 DGAScreenPtr pScreenPriv
;
981 if (!DGAScreenKeyRegistered
) /* no DGA */
984 pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
986 if (!pScreenPriv
|| !pScreenPriv
->grabMouse
)
990 .header
= ET_Internal
,
992 .length
= sizeof(event
),
993 .time
= GetTimeInMillis(),
994 .subtype
= (is_down
? ET_ButtonPress
: ET_ButtonRelease
),
999 mieqEnqueue(dev
, (InternalEvent
*) &event
);
1004 /* We have the power to steal or modify events that are about to get queued */
1006 #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
1007 static 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) */
1018 DGAProcessKeyboardEvent(ScreenPtr pScreen
, DGAEvent
* event
, DeviceIntPtr keybd
)
1020 KeyClassPtr keyc
= keybd
->key
;
1021 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
1022 DeviceIntPtr pointer
= GetMaster(keybd
, POINTER_OR_FLOAT
);
1024 .header
= ET_Internal
,
1025 .length
= sizeof(ev
),
1026 .detail
.key
= event
->detail
,
1027 .type
= event
->subtype
,
1030 .corestate
= XkbStateFieldFromRec(&keyc
->xkbInfo
->state
)
1032 ev
.corestate
|= pointer
->button
->state
;
1034 UpdateDeviceState(keybd
, &ev
);
1036 if (!IsMaster(keybd
))
1040 * Deliver the DGA event
1042 if (pScreenPriv
->client
) {
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
1050 de
.u
.u
.type
= DGAEventBase
+ GetCoreType(ev
.type
);
1051 de
.u
.u
.detail
= event
->detail
;
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);
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
);
1072 DGAProcessPointerEvent(ScreenPtr pScreen
, DGAEvent
* event
, DeviceIntPtr mouse
)
1074 ButtonClassPtr butc
= mouse
->button
;
1075 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
1076 DeviceIntPtr master
= GetMaster(mouse
, MASTER_KEYBOARD
);
1078 .header
= ET_Internal
,
1079 .length
= sizeof(ev
),
1080 .detail
.key
= event
->detail
,
1081 .type
= event
->subtype
,
1082 .corestate
= butc
? butc
->state
: 0
1085 if (master
&& master
->key
)
1086 ev
.corestate
|= XkbStateFieldFromRec(&master
->key
->xkbInfo
->state
);
1088 UpdateDeviceState(mouse
, &ev
);
1090 if (!IsMaster(mouse
))
1094 * Deliver the DGA event
1096 if (pScreenPriv
->client
) {
1097 int coreEquiv
= GetCoreType(ev
.type
);
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
1105 de
.u
.u
.type
= DGAEventBase
+ coreEquiv
;
1106 de
.u
.u
.detail
= event
->detail
;
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);
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
);
1130 DGAOpenFramebuffer(int index
,
1132 unsigned char **mem
, int *size
, int *offset
, int *flags
)
1134 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
1136 /* We rely on the extension to check that DGA is available */
1138 return (*pScreenPriv
->funcs
->OpenFramebuffer
) (pScreenPriv
->pScrn
,
1139 name
, mem
, size
, offset
,
1144 DGACloseFramebuffer(int index
)
1146 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
1148 /* We rely on the extension to check that DGA is available */
1149 if (pScreenPriv
->funcs
->CloseFramebuffer
)
1150 (*pScreenPriv
->funcs
->CloseFramebuffer
) (pScreenPriv
->pScrn
);
1153 /* For DGA 1.0 backwards compatibility only */
1156 DGAGetOldDGAMode(int index
)
1158 DGAScreenPtr pScreenPriv
= DGA_GET_SCREEN_PRIV(screenInfo
.screens
[index
]);
1159 ScrnInfoPtr pScrn
= pScreenPriv
->pScrn
;
1163 /* We rely on the extension to check that DGA is available */
1165 w
= pScrn
->currentMode
->HDisplay
;
1166 h
= pScrn
->currentMode
->VDisplay
;
1167 p
= pad_to_int32(pScrn
->displayWidth
* bits_to_bytes(pScrn
->bitsPerPixel
));
1169 for (i
= 0; i
< pScreenPriv
->numModes
; i
++) {
1170 mode
= &(pScreenPriv
->modes
[i
]);
1172 if ((mode
->viewportWidth
== w
) && (mode
->viewportHeight
== h
) &&
1173 (mode
->bytesPerScanline
== p
) &&
1174 (mode
->bitsPerPixel
== pScrn
->bitsPerPixel
) &&
1175 (mode
->depth
== pScrn
->depth
)) {
1185 DGAHandleEvent(int screen_num
, InternalEvent
*ev
, DeviceIntPtr device
)
1187 DGAEvent
*event
= &ev
->dga_event
;
1188 ScreenPtr pScreen
= screenInfo
.screens
[screen_num
];
1189 DGAScreenPtr pScreenPriv
;
1192 if (!DGAScreenKeyRegistered
|| noXFree86DGAExtension
)
1194 pScreenPriv
= DGA_GET_SCREEN_PRIV(pScreen
);
1196 /* DGA not initialized on this screen */
1200 switch (event
->subtype
) {
1203 DGAProcessKeyboardEvent(pScreen
, event
, device
);
1208 DGAProcessPointerEvent(pScreen
, event
, device
);
1215 static void XDGAResetProc(ExtensionEntry
* extEntry
);
1217 static void DGAClientStateChange(CallbackListPtr
*, pointer
, pointer
);
1219 static DevPrivateKeyRec DGAScreenPrivateKeyRec
;
1221 #define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
1222 #define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
1223 static DevPrivateKeyRec DGAClientPrivateKeyRec
;
1225 #define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
1226 static int DGACallbackRefCount
= 0;
1228 /* This holds the client's version information */
1232 } DGAPrivRec
, *DGAPrivPtr
;
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)
1239 #define DGA_GETPRIV(c) ((DGAPrivPtr) \
1240 dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
1241 #define DGA_SETPRIV(c,p) \
1242 dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
1245 XDGAResetProc(ExtensionEntry
* extEntry
)
1247 DeleteCallback(&ClientStateCallback
, DGAClientStateChange
, NULL
);
1248 DGACallbackRefCount
= 0;
1252 ProcXDGAQueryVersion(ClientPtr client
)
1254 xXDGAQueryVersionReply rep
;
1256 REQUEST_SIZE_MATCH(xXDGAQueryVersionReq
);
1259 rep
.sequenceNumber
= client
->sequence
;
1260 rep
.majorVersion
= SERVER_XDGA_MAJOR_VERSION
;
1261 rep
.minorVersion
= SERVER_XDGA_MINOR_VERSION
;
1263 WriteToClient(client
, sizeof(xXDGAQueryVersionReply
), (char *) &rep
);
1268 ProcXDGAOpenFramebuffer(ClientPtr client
)
1270 REQUEST(xXDGAOpenFramebufferReq
);
1271 xXDGAOpenFramebufferReply rep
;
1275 if (stuff
->screen
>= screenInfo
.numScreens
)
1278 if (!DGAAvailable(stuff
->screen
))
1279 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1281 REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq
);
1284 rep
.sequenceNumber
= client
->sequence
;
1286 if (!DGAOpenFramebuffer(stuff
->screen
, &deviceName
,
1287 (unsigned char **) (&rep
.mem1
),
1288 (int *) &rep
.size
, (int *) &rep
.offset
,
1289 (int *) &rep
.extra
)) {
1293 nameSize
= deviceName
? (strlen(deviceName
) + 1) : 0;
1294 rep
.length
= bytes_to_int32(nameSize
);
1296 WriteToClient(client
, sizeof(xXDGAOpenFramebufferReply
), (char *) &rep
);
1298 WriteToClient(client
, nameSize
, deviceName
);
1304 ProcXDGACloseFramebuffer(ClientPtr client
)
1306 REQUEST(xXDGACloseFramebufferReq
);
1308 if (stuff
->screen
>= screenInfo
.numScreens
)
1311 if (!DGAAvailable(stuff
->screen
))
1312 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1314 REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq
);
1316 DGACloseFramebuffer(stuff
->screen
);
1322 ProcXDGAQueryModes(ClientPtr client
)
1326 REQUEST(xXDGAQueryModesReq
);
1327 xXDGAQueryModesReply rep
;
1331 if (stuff
->screen
>= screenInfo
.numScreens
)
1334 REQUEST_SIZE_MATCH(xXDGAQueryModesReq
);
1338 rep
.sequenceNumber
= client
->sequence
;
1340 if (!DGAAvailable(stuff
->screen
)) {
1343 WriteToClient(client
, sz_xXDGAQueryModesReply
, (char *) &rep
);
1347 if (!(num
= DGAGetModes(stuff
->screen
))) {
1348 WriteToClient(client
, sz_xXDGAQueryModesReply
, (char *) &rep
);
1352 if (!(mode
= (XDGAModePtr
) malloc(num
* sizeof(XDGAModeRec
))))
1355 for (i
= 0; i
< num
; i
++)
1356 DGAGetModeInfo(stuff
->screen
, mode
+ i
, i
+ 1);
1358 size
= num
* sz_xXDGAModeInfo
;
1359 for (i
= 0; i
< num
; i
++)
1360 size
+= pad_to_int32(strlen(mode
[i
].name
) + 1); /* plus NULL */
1363 rep
.length
= bytes_to_int32(size
);
1365 WriteToClient(client
, sz_xXDGAQueryModesReply
, (char *) &rep
);
1367 for (i
= 0; i
< num
; i
++) {
1368 size
= strlen(mode
[i
].name
) + 1;
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
;
1397 WriteToClient(client
, sz_xXDGAModeInfo
, (char *) (&info
));
1398 WriteToClient(client
, size
, mode
[i
].name
);
1407 DGAClientStateChange(CallbackListPtr
*pcbl
, pointer nulldata
, pointer calldata
)
1409 NewClientInfoRec
*pci
= (NewClientInfoRec
*) calldata
;
1410 ClientPtr client
= NULL
;
1413 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
1414 if (DGA_GETCLIENT(i
) == pci
->client
) {
1415 client
= pci
->client
;
1421 ((client
->clientState
== ClientStateGone
) ||
1422 (client
->clientState
== ClientStateRetained
))) {
1426 DGA_SETCLIENT(i
, NULL
);
1427 DGASelectInput(i
, NULL
, 0);
1428 DGASetMode(i
, 0, &mode
, &pPix
);
1430 if (--DGACallbackRefCount
== 0)
1431 DeleteCallback(&ClientStateCallback
, DGAClientStateChange
, NULL
);
1436 ProcXDGASetMode(ClientPtr client
)
1438 REQUEST(xXDGASetModeReq
);
1439 xXDGASetModeReply rep
;
1446 if (stuff
->screen
>= screenInfo
.numScreens
)
1448 owner
= DGA_GETCLIENT(stuff
->screen
);
1450 REQUEST_SIZE_MATCH(xXDGASetModeReq
);
1455 rep
.sequenceNumber
= client
->sequence
;
1457 if (!DGAAvailable(stuff
->screen
))
1458 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1460 if (owner
&& owner
!= client
)
1461 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1465 if (--DGACallbackRefCount
== 0)
1466 DeleteCallback(&ClientStateCallback
, DGAClientStateChange
,
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
);
1476 if (Success
!= DGASetMode(stuff
->screen
, stuff
->mode
, &mode
, &pPix
))
1480 if (DGACallbackRefCount
++ == 0)
1481 AddCallback(&ClientStateCallback
, DGAClientStateChange
, NULL
);
1484 DGA_SETCLIENT(stuff
->screen
, client
);
1487 if (AddResource(stuff
->pid
, RT_PIXMAP
, (pointer
) (pPix
))) {
1488 pPix
->drawable
.id
= (int) stuff
->pid
;
1489 rep
.flags
= DGA_PIXMAP_AVAILABLE
;
1493 size
= strlen(mode
.name
) + 1;
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
;
1522 rep
.length
= bytes_to_int32(sz_xXDGAModeInfo
+ info
.name_size
);
1524 WriteToClient(client
, sz_xXDGASetModeReply
, (char *) &rep
);
1525 WriteToClient(client
, sz_xXDGAModeInfo
, (char *) (&info
));
1526 WriteToClient(client
, size
, mode
.name
);
1532 ProcXDGASetViewport(ClientPtr client
)
1534 REQUEST(xXDGASetViewportReq
);
1536 if (stuff
->screen
>= screenInfo
.numScreens
)
1539 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1540 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1542 REQUEST_SIZE_MATCH(xXDGASetViewportReq
);
1544 DGASetViewport(stuff
->screen
, stuff
->x
, stuff
->y
, stuff
->flags
);
1550 ProcXDGAInstallColormap(ClientPtr client
)
1555 REQUEST(xXDGAInstallColormapReq
);
1557 if (stuff
->screen
>= screenInfo
.numScreens
)
1560 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1561 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1563 REQUEST_SIZE_MATCH(xXDGAInstallColormapReq
);
1565 rc
= dixLookupResourceByType((pointer
*) &cmap
, stuff
->cmap
, RT_COLORMAP
,
1566 client
, DixInstallAccess
);
1569 DGAInstallCmap(cmap
);
1574 ProcXDGASelectInput(ClientPtr client
)
1576 REQUEST(xXDGASelectInputReq
);
1578 if (stuff
->screen
>= screenInfo
.numScreens
)
1581 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1582 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1584 REQUEST_SIZE_MATCH(xXDGASelectInputReq
);
1586 if (DGA_GETCLIENT(stuff
->screen
) == client
)
1587 DGASelectInput(stuff
->screen
, client
, stuff
->mask
);
1593 ProcXDGAFillRectangle(ClientPtr client
)
1595 REQUEST(xXDGAFillRectangleReq
);
1597 if (stuff
->screen
>= screenInfo
.numScreens
)
1600 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1601 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1603 REQUEST_SIZE_MATCH(xXDGAFillRectangleReq
);
1605 if (Success
!= DGAFillRect(stuff
->screen
, stuff
->x
, stuff
->y
,
1606 stuff
->width
, stuff
->height
, stuff
->color
))
1613 ProcXDGACopyArea(ClientPtr client
)
1615 REQUEST(xXDGACopyAreaReq
);
1617 if (stuff
->screen
>= screenInfo
.numScreens
)
1620 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1621 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1623 REQUEST_SIZE_MATCH(xXDGACopyAreaReq
);
1625 if (Success
!= DGABlitRect(stuff
->screen
, stuff
->srcx
, stuff
->srcy
,
1626 stuff
->width
, stuff
->height
, stuff
->dstx
,
1634 ProcXDGACopyTransparentArea(ClientPtr client
)
1636 REQUEST(xXDGACopyTransparentAreaReq
);
1638 if (stuff
->screen
>= screenInfo
.numScreens
)
1641 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1642 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1644 REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq
);
1646 if (Success
!= DGABlitTransRect(stuff
->screen
, stuff
->srcx
, stuff
->srcy
,
1647 stuff
->width
, stuff
->height
, stuff
->dstx
,
1648 stuff
->dsty
, stuff
->key
))
1655 ProcXDGAGetViewportStatus(ClientPtr client
)
1657 REQUEST(xXDGAGetViewportStatusReq
);
1658 xXDGAGetViewportStatusReply rep
;
1660 if (stuff
->screen
>= screenInfo
.numScreens
)
1663 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1664 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1666 REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq
);
1669 rep
.sequenceNumber
= client
->sequence
;
1671 rep
.status
= DGAGetViewportStatus(stuff
->screen
);
1673 WriteToClient(client
, sizeof(xXDGAGetViewportStatusReply
), (char *) &rep
);
1678 ProcXDGASync(ClientPtr client
)
1680 REQUEST(xXDGASyncReq
);
1683 if (stuff
->screen
>= screenInfo
.numScreens
)
1686 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1687 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1689 REQUEST_SIZE_MATCH(xXDGASyncReq
);
1692 rep
.sequenceNumber
= client
->sequence
;
1694 DGASync(stuff
->screen
);
1696 WriteToClient(client
, sizeof(xXDGASyncReply
), (char *) &rep
);
1701 ProcXDGASetClientVersion(ClientPtr client
)
1703 REQUEST(xXDGASetClientVersionReq
);
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 */
1713 DGA_SETPRIV(client
, pPriv
);
1715 pPriv
->major
= stuff
->major
;
1716 pPriv
->minor
= stuff
->minor
;
1722 ProcXDGAChangePixmapMode(ClientPtr client
)
1724 REQUEST(xXDGAChangePixmapModeReq
);
1725 xXDGAChangePixmapModeReply rep
;
1728 if (stuff
->screen
>= screenInfo
.numScreens
)
1731 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1732 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1734 REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq
);
1737 rep
.sequenceNumber
= client
->sequence
;
1742 if (!DGAChangePixmapMode(stuff
->screen
, &x
, &y
, stuff
->flags
))
1747 WriteToClient(client
, sizeof(xXDGAChangePixmapModeReply
), (char *) &rep
);
1753 ProcXDGACreateColormap(ClientPtr client
)
1755 REQUEST(xXDGACreateColormapReq
);
1758 if (stuff
->screen
>= screenInfo
.numScreens
)
1761 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1762 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1764 REQUEST_SIZE_MATCH(xXDGACreateColormapReq
);
1769 result
= DGACreateColormap(stuff
->screen
, client
, stuff
->id
,
1770 stuff
->mode
, stuff
->alloc
);
1771 if (result
!= Success
)
1779 * Support for the old DGA protocol, used to live in xf86dga.c
1783 #ifdef DGA_PROTOCOL_OLD_SUPPORT
1786 ProcXF86DGAGetVideoLL(ClientPtr client
)
1788 REQUEST(xXF86DGAGetVideoLLReq
);
1789 xXF86DGAGetVideoLLReply rep
;
1791 int num
, offset
, flags
;
1794 if (stuff
->screen
>= screenInfo
.numScreens
)
1797 REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq
);
1800 rep
.sequenceNumber
= client
->sequence
;
1802 if (!DGAAvailable(stuff
->screen
))
1803 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1805 if (!(num
= DGAGetOldDGAMode(stuff
->screen
)))
1806 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1808 /* get the parameters for the mode that best matches */
1809 DGAGetModeInfo(stuff
->screen
, &mode
, num
);
1811 if (!DGAOpenFramebuffer(stuff
->screen
, &name
,
1812 (unsigned char **) (&rep
.offset
),
1813 (int *) (&rep
.bank_size
), &offset
, &flags
))
1816 rep
.offset
+= mode
.offset
;
1817 rep
.width
= mode
.bytesPerScanline
/ (mode
.bitsPerPixel
>> 3);
1818 rep
.ram_size
= rep
.bank_size
>> 10;
1820 WriteToClient(client
, SIZEOF(xXF86DGAGetVideoLLReply
), (char *) &rep
);
1825 ProcXF86DGADirectVideo(ClientPtr client
)
1832 REQUEST(xXF86DGADirectVideoReq
);
1834 if (stuff
->screen
>= screenInfo
.numScreens
)
1836 REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq
);
1838 if (!DGAAvailable(stuff
->screen
))
1839 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1841 owner
= DGA_GETCLIENT(stuff
->screen
);
1843 if (owner
&& owner
!= client
)
1844 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1846 if (stuff
->enable
& XF86DGADirectGraphics
) {
1847 if (!(num
= DGAGetOldDGAMode(stuff
->screen
)))
1848 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1853 if (Success
!= DGASetMode(stuff
->screen
, num
, &mode
, &pix
))
1854 return DGAErrorBase
+ XF86DGAScreenNotActive
;
1856 DGASetInputMode(stuff
->screen
,
1857 (stuff
->enable
& XF86DGADirectKeyb
) != 0,
1858 (stuff
->enable
& XF86DGADirectMouse
) != 0);
1860 /* We need to track the client and attach the teardown callback */
1862 (XF86DGADirectGraphics
| XF86DGADirectKeyb
| XF86DGADirectMouse
)) {
1864 if (DGACallbackRefCount
++ == 0)
1865 AddCallback(&ClientStateCallback
, DGAClientStateChange
, NULL
);
1868 DGA_SETCLIENT(stuff
->screen
, client
);
1872 if (--DGACallbackRefCount
== 0)
1873 DeleteCallback(&ClientStateCallback
, DGAClientStateChange
,
1877 DGA_SETCLIENT(stuff
->screen
, NULL
);
1884 ProcXF86DGAGetViewPortSize(ClientPtr client
)
1889 REQUEST(xXF86DGAGetViewPortSizeReq
);
1890 xXF86DGAGetViewPortSizeReply rep
;
1892 if (stuff
->screen
>= screenInfo
.numScreens
)
1895 REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq
);
1898 rep
.sequenceNumber
= client
->sequence
;
1900 if (!DGAAvailable(stuff
->screen
))
1901 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1903 if (!(num
= DGAGetOldDGAMode(stuff
->screen
)))
1904 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1906 DGAGetModeInfo(stuff
->screen
, &mode
, num
);
1908 rep
.width
= mode
.viewportWidth
;
1909 rep
.height
= mode
.viewportHeight
;
1911 WriteToClient(client
, SIZEOF(xXF86DGAGetViewPortSizeReply
), (char *) &rep
);
1916 ProcXF86DGASetViewPort(ClientPtr client
)
1918 REQUEST(xXF86DGASetViewPortReq
);
1920 if (stuff
->screen
>= screenInfo
.numScreens
)
1923 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1924 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1926 REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq
);
1928 if (!DGAAvailable(stuff
->screen
))
1929 return DGAErrorBase
+ XF86DGANoDirectVideoMode
;
1931 if (!DGAActive(stuff
->screen
))
1932 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1934 if (DGASetViewport(stuff
->screen
, stuff
->x
, stuff
->y
, DGA_FLIP_RETRACE
)
1936 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1942 ProcXF86DGAGetVidPage(ClientPtr client
)
1944 REQUEST(xXF86DGAGetVidPageReq
);
1945 xXF86DGAGetVidPageReply rep
;
1947 if (stuff
->screen
>= screenInfo
.numScreens
)
1950 REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq
);
1953 rep
.sequenceNumber
= client
->sequence
;
1954 rep
.vpage
= 0; /* silently fail */
1956 WriteToClient(client
, SIZEOF(xXF86DGAGetVidPageReply
), (char *) &rep
);
1961 ProcXF86DGASetVidPage(ClientPtr client
)
1963 REQUEST(xXF86DGASetVidPageReq
);
1965 if (stuff
->screen
>= screenInfo
.numScreens
)
1968 REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq
);
1976 ProcXF86DGAInstallColormap(ClientPtr client
)
1981 REQUEST(xXF86DGAInstallColormapReq
);
1983 if (stuff
->screen
>= screenInfo
.numScreens
)
1986 if (DGA_GETCLIENT(stuff
->screen
) != client
)
1987 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1989 REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq
);
1991 if (!DGAActive(stuff
->screen
))
1992 return DGAErrorBase
+ XF86DGADirectNotActivated
;
1994 rc
= dixLookupResourceByType((pointer
*) &pcmp
, stuff
->id
, RT_COLORMAP
,
1995 client
, DixInstallAccess
);
1996 if (rc
== Success
) {
1997 DGAInstallCmap(pcmp
);
2006 ProcXF86DGAQueryDirectVideo(ClientPtr client
)
2008 REQUEST(xXF86DGAQueryDirectVideoReq
);
2009 xXF86DGAQueryDirectVideoReply rep
;
2011 if (stuff
->screen
>= screenInfo
.numScreens
)
2014 REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq
);
2017 rep
.sequenceNumber
= client
->sequence
;
2020 if (DGAAvailable(stuff
->screen
))
2021 rep
.flags
= XF86DGADirectPresent
;
2023 WriteToClient(client
, SIZEOF(xXF86DGAQueryDirectVideoReply
), (char *) &rep
);
2028 ProcXF86DGAViewPortChanged(ClientPtr client
)
2030 REQUEST(xXF86DGAViewPortChangedReq
);
2031 xXF86DGAViewPortChangedReply rep
;
2033 if (stuff
->screen
>= screenInfo
.numScreens
)
2036 if (DGA_GETCLIENT(stuff
->screen
) != client
)
2037 return DGAErrorBase
+ XF86DGADirectNotActivated
;
2039 REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq
);
2041 if (!DGAActive(stuff
->screen
))
2042 return DGAErrorBase
+ XF86DGADirectNotActivated
;
2046 rep
.sequenceNumber
= client
->sequence
;
2049 WriteToClient(client
, SIZEOF(xXF86DGAViewPortChangedReply
), (char *) &rep
);
2053 #endif /* DGA_PROTOCOL_OLD_SUPPORT */
2056 SProcXDGADispatch(ClientPtr client
)
2058 return DGAErrorBase
+ XF86DGAClientNotLocal
;
2062 #define DGA_REQ_DEBUG
2065 #ifdef DGA_REQ_DEBUG
2066 static char *dgaMinor
[] = {
2086 "CopyTransparentArea",
2087 "GetViewportStatus",
2098 ProcXDGADispatch(ClientPtr client
)
2103 return DGAErrorBase
+ XF86DGAClientNotLocal
;
2105 #ifdef DGA_REQ_DEBUG
2106 if (stuff
->data
<= X_XDGACreateColormap
)
2107 fprintf(stderr
, " DGA %s\n", dgaMinor
[stuff
->data
]);
2110 switch (stuff
->data
) {
2114 case X_XDGAQueryVersion
:
2115 return ProcXDGAQueryVersion(client
);
2116 case X_XDGAQueryModes
:
2117 return ProcXDGAQueryModes(client
);
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
);
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
);
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 */
2175 XFree86DGAExtensionInit(void)
2177 ExtensionEntry
*extEntry
;
2179 if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec
, PRIVATE_CLIENT
, 0))
2182 if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
2185 if ((extEntry
= AddExtension(XF86DGANAME
,
2186 XF86DGANumberEvents
,
2187 XF86DGANumberErrors
,
2190 XDGAResetProc
, StandardMinorOpcode
))) {
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
);