105b261ecSmrg/*
235c4bbdfSmrg * Copyright (c) 1995  Jon Tombs
335c4bbdfSmrg * Copyright (c) 1995, 1996, 1999  XFree86 Inc
405b261ecSmrg * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
505b261ecSmrg *
605b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
705b261ecSmrg * copy of this software and associated documentation files (the "Software"),
805b261ecSmrg * to deal in the Software without restriction, including without limitation
905b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1005b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
1105b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1205b261ecSmrg *
1305b261ecSmrg * The above copyright notice and this permission notice shall be included in
1405b261ecSmrg * all copies or substantial portions of the Software.
1505b261ecSmrg *
1605b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1705b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1805b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1905b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2005b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2105b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2205b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
2305b261ecSmrg *
2405b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
2505b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
2605b261ecSmrg * the sale, use or other dealings in this Software without prior written
2705b261ecSmrg * authorization from the copyright holder(s) and author(s).
2805b261ecSmrg *
2905b261ecSmrg * Written by Mark Vojkovich
3005b261ecSmrg */
3105b261ecSmrg
3235c4bbdfSmrg/*
3335c4bbdfSmrg * This is quite literally just two files glued together:
3435c4bbdfSmrg * hw/xfree86/common/xf86DGA.c is the first part, and
3535c4bbdfSmrg * hw/xfree86/dixmods/extmod/xf86dga2.c is the second part.  One day, if
3635c4bbdfSmrg * someone actually cares about DGA, it'd be nice to clean this up.  But trust
3735c4bbdfSmrg * me, I am not that person.
3835c4bbdfSmrg */
3935c4bbdfSmrg
4005b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
4105b261ecSmrg#include <xorg-config.h>
4205b261ecSmrg#endif
4305b261ecSmrg
4435c4bbdfSmrg#include <X11/X.h>
4535c4bbdfSmrg#include <X11/Xproto.h>
4605b261ecSmrg#include "xf86.h"
4705b261ecSmrg#include "xf86str.h"
4805b261ecSmrg#include "xf86Priv.h"
4905b261ecSmrg#include "dgaproc.h"
506747b715Smrg#include <X11/extensions/xf86dgaproto.h>
5105b261ecSmrg#include "colormapst.h"
5205b261ecSmrg#include "pixmapstr.h"
5305b261ecSmrg#include "inputstr.h"
5405b261ecSmrg#include "globals.h"
5505b261ecSmrg#include "servermd.h"
5605b261ecSmrg#include "micmap.h"
576747b715Smrg#include "xkbsrv.h"
5805b261ecSmrg#include "xf86Xinput.h"
594642e01fSmrg#include "exglobals.h"
604642e01fSmrg#include "exevents.h"
616747b715Smrg#include "eventstr.h"
626747b715Smrg#include "eventconvert.h"
6335c4bbdfSmrg#include "xf86Extensions.h"
6405b261ecSmrg
6505b261ecSmrg#include "mi.h"
6605b261ecSmrg
6735c4bbdfSmrg#include "misc.h"
6835c4bbdfSmrg#include "dixstruct.h"
6935c4bbdfSmrg#include "dixevents.h"
7035c4bbdfSmrg#include "extnsionst.h"
7135c4bbdfSmrg#include "cursorstr.h"
7235c4bbdfSmrg#include "scrnintstr.h"
7335c4bbdfSmrg#include "swaprep.h"
7435c4bbdfSmrg#include "dgaproc.h"
7535c4bbdfSmrg#include "protocol-versions.h"
7635c4bbdfSmrg
7735c4bbdfSmrg#include <string.h>
7835c4bbdfSmrg
7935c4bbdfSmrg#define DGA_PROTOCOL_OLD_SUPPORT 1
8035c4bbdfSmrg
816747b715Smrgstatic DevPrivateKeyRec DGAScreenKeyRec;
8235c4bbdfSmrg
836747b715Smrg#define DGAScreenKeyRegistered dixPrivateKeyRegistered(&DGAScreenKeyRec)
8405b261ecSmrg
8535c4bbdfSmrgstatic Bool DGACloseScreen(ScreenPtr pScreen);
8605b261ecSmrgstatic void DGADestroyColormap(ColormapPtr pmap);
8705b261ecSmrgstatic void DGAInstallColormap(ColormapPtr pmap);
8805b261ecSmrgstatic void DGAUninstallColormap(ColormapPtr pmap);
896747b715Smrgstatic void DGAHandleEvent(int screen_num, InternalEvent *event,
906747b715Smrg                           DeviceIntPtr device);
9105b261ecSmrg
9205b261ecSmrgstatic void
9335c4bbdfSmrg DGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode);
9405b261ecSmrg
9535c4bbdfSmrgstatic unsigned char DGAReqCode = 0;
9635c4bbdfSmrgstatic int DGAErrorBase;
9735c4bbdfSmrgstatic int DGAEventBase;
9805b261ecSmrg
994642e01fSmrg#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
1006747b715Smrg    dixLookupPrivate(&(pScreen)->devPrivates, &DGAScreenKeyRec))
10105b261ecSmrg
10235c4bbdfSmrgtypedef struct _FakedVisualList {
10335c4bbdfSmrg    Bool free;
10435c4bbdfSmrg    VisualPtr pVisual;
10535c4bbdfSmrg    struct _FakedVisualList *next;
10605b261ecSmrg} FakedVisualList;
10705b261ecSmrg
10805b261ecSmrgtypedef struct {
10935c4bbdfSmrg    ScrnInfoPtr pScrn;
11035c4bbdfSmrg    int numModes;
11135c4bbdfSmrg    DGAModePtr modes;
11235c4bbdfSmrg    CloseScreenProcPtr CloseScreen;
11335c4bbdfSmrg    DestroyColormapProcPtr DestroyColormap;
11435c4bbdfSmrg    InstallColormapProcPtr InstallColormap;
11535c4bbdfSmrg    UninstallColormapProcPtr UninstallColormap;
11635c4bbdfSmrg    DGADevicePtr current;
11735c4bbdfSmrg    DGAFunctionPtr funcs;
11835c4bbdfSmrg    int input;
11935c4bbdfSmrg    ClientPtr client;
12035c4bbdfSmrg    int pixmapMode;
12135c4bbdfSmrg    FakedVisualList *fakedVisuals;
12235c4bbdfSmrg    ColormapPtr dgaColormap;
12335c4bbdfSmrg    ColormapPtr savedColormap;
12435c4bbdfSmrg    Bool grabMouse;
12535c4bbdfSmrg    Bool grabKeyboard;
12605b261ecSmrg} DGAScreenRec, *DGAScreenPtr;
12705b261ecSmrg
1286747b715SmrgBool
12935c4bbdfSmrgDGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes, int num)
13035c4bbdfSmrg{
13135c4bbdfSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
13205b261ecSmrg    DGAScreenPtr pScreenPriv;
13305b261ecSmrg    int i;
13405b261ecSmrg
13535c4bbdfSmrg    if (!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
13635c4bbdfSmrg        return FALSE;
13705b261ecSmrg
13835c4bbdfSmrg    if (!modes || num <= 0)
13935c4bbdfSmrg        return FALSE;
14005b261ecSmrg
1416747b715Smrg    if (!dixRegisterPrivateKey(&DGAScreenKeyRec, PRIVATE_SCREEN, 0))
14235c4bbdfSmrg        return FALSE;
14305b261ecSmrg
144b1d344b3Smrg    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
145b1d344b3Smrg
14635c4bbdfSmrg    if (!pScreenPriv) {
14735c4bbdfSmrg        if (!(pScreenPriv = (DGAScreenPtr) malloc(sizeof(DGAScreenRec))))
14835c4bbdfSmrg            return FALSE;
14935c4bbdfSmrg        dixSetPrivate(&pScreen->devPrivates, &DGAScreenKeyRec, pScreenPriv);
15035c4bbdfSmrg        pScreenPriv->CloseScreen = pScreen->CloseScreen;
15135c4bbdfSmrg        pScreen->CloseScreen = DGACloseScreen;
15235c4bbdfSmrg        pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
15335c4bbdfSmrg        pScreen->DestroyColormap = DGADestroyColormap;
15435c4bbdfSmrg        pScreenPriv->InstallColormap = pScreen->InstallColormap;
15535c4bbdfSmrg        pScreen->InstallColormap = DGAInstallColormap;
15635c4bbdfSmrg        pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
15735c4bbdfSmrg        pScreen->UninstallColormap = DGAUninstallColormap;
158b1d344b3Smrg    }
15905b261ecSmrg
16005b261ecSmrg    pScreenPriv->pScrn = pScrn;
16105b261ecSmrg    pScreenPriv->numModes = num;
16205b261ecSmrg    pScreenPriv->modes = modes;
16335c4bbdfSmrg    pScreenPriv->current = NULL;
16435c4bbdfSmrg
16505b261ecSmrg    pScreenPriv->funcs = funcs;
16605b261ecSmrg    pScreenPriv->input = 0;
16705b261ecSmrg    pScreenPriv->client = NULL;
16805b261ecSmrg    pScreenPriv->fakedVisuals = NULL;
16905b261ecSmrg    pScreenPriv->dgaColormap = NULL;
17005b261ecSmrg    pScreenPriv->savedColormap = NULL;
17105b261ecSmrg    pScreenPriv->grabMouse = FALSE;
17205b261ecSmrg    pScreenPriv->grabKeyboard = FALSE;
17335c4bbdfSmrg
17435c4bbdfSmrg    for (i = 0; i < num; i++)
17535c4bbdfSmrg        modes[i].num = i + 1;
17605b261ecSmrg
17705b261ecSmrg#ifdef PANORAMIX
17835c4bbdfSmrg    if (!noPanoramiXExtension)
17935c4bbdfSmrg        for (i = 0; i < num; i++)
18035c4bbdfSmrg            modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
18105b261ecSmrg#endif
18205b261ecSmrg
18305b261ecSmrg    return TRUE;
18405b261ecSmrg}
18505b261ecSmrg
18605b261ecSmrg/* DGAReInitModes allows the driver to re-initialize
18705b261ecSmrg * the DGA mode list.
18805b261ecSmrg */
18905b261ecSmrg
1906747b715SmrgBool
19135c4bbdfSmrgDGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num)
19235c4bbdfSmrg{
19305b261ecSmrg    DGAScreenPtr pScreenPriv;
19405b261ecSmrg    int i;
19505b261ecSmrg
19605b261ecSmrg    /* No DGA? Ignore call (but don't make it look like it failed) */
19735c4bbdfSmrg    if (!DGAScreenKeyRegistered)
19835c4bbdfSmrg        return TRUE;
19935c4bbdfSmrg
20005b261ecSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
20105b261ecSmrg
20205b261ecSmrg    /* Same as above */
20335c4bbdfSmrg    if (!pScreenPriv)
20435c4bbdfSmrg        return TRUE;
20505b261ecSmrg
20605b261ecSmrg    /* Can't do this while DGA is active */
20735c4bbdfSmrg    if (pScreenPriv->current)
20835c4bbdfSmrg        return FALSE;
20905b261ecSmrg
21005b261ecSmrg    /* Quick sanity check */
21135c4bbdfSmrg    if (!num)
21235c4bbdfSmrg        modes = NULL;
21335c4bbdfSmrg    else if (!modes)
21435c4bbdfSmrg        num = 0;
21505b261ecSmrg
21605b261ecSmrg    pScreenPriv->numModes = num;
21705b261ecSmrg    pScreenPriv->modes = modes;
21805b261ecSmrg
21905b261ecSmrg    /* This practically disables DGA. So be it. */
22035c4bbdfSmrg    if (!num)
22135c4bbdfSmrg        return TRUE;
22205b261ecSmrg
22335c4bbdfSmrg    for (i = 0; i < num; i++)
22435c4bbdfSmrg        modes[i].num = i + 1;
22505b261ecSmrg
22605b261ecSmrg#ifdef PANORAMIX
22735c4bbdfSmrg    if (!noPanoramiXExtension)
22835c4bbdfSmrg        for (i = 0; i < num; i++)
22935c4bbdfSmrg            modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
23005b261ecSmrg#endif
23105b261ecSmrg
23235c4bbdfSmrg    return TRUE;
23305b261ecSmrg}
23405b261ecSmrg
23505b261ecSmrgstatic void
23605b261ecSmrgFreeMarkedVisuals(ScreenPtr pScreen)
23705b261ecSmrg{
23805b261ecSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
23905b261ecSmrg    FakedVisualList *prev, *curr, *tmp;
24005b261ecSmrg
24135c4bbdfSmrg    if (!pScreenPriv->fakedVisuals)
24235c4bbdfSmrg        return;
24305b261ecSmrg
24405b261ecSmrg    prev = NULL;
24505b261ecSmrg    curr = pScreenPriv->fakedVisuals;
24605b261ecSmrg
24735c4bbdfSmrg    while (curr) {
24835c4bbdfSmrg        if (curr->free) {
24935c4bbdfSmrg            tmp = curr;
25035c4bbdfSmrg            curr = curr->next;
25135c4bbdfSmrg            if (prev)
25235c4bbdfSmrg                prev->next = curr;
25335c4bbdfSmrg            else
25435c4bbdfSmrg                pScreenPriv->fakedVisuals = curr;
25535c4bbdfSmrg            free(tmp->pVisual);
25635c4bbdfSmrg            free(tmp);
25735c4bbdfSmrg        }
25835c4bbdfSmrg        else {
25935c4bbdfSmrg            prev = curr;
26035c4bbdfSmrg            curr = curr->next;
26135c4bbdfSmrg        }
26205b261ecSmrg    }
26305b261ecSmrg}
26405b261ecSmrg
26535c4bbdfSmrgstatic Bool
26635c4bbdfSmrgDGACloseScreen(ScreenPtr pScreen)
26705b261ecSmrg{
26835c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
26905b261ecSmrg
2705a112b11Smrg    mieqSetHandler(ET_DGAEvent, NULL);
2715a112b11Smrg    pScreenPriv->pScrn->SetDGAMode(pScreenPriv->pScrn, 0, NULL);
27235c4bbdfSmrg    FreeMarkedVisuals(pScreen);
27305b261ecSmrg
27435c4bbdfSmrg    pScreen->CloseScreen = pScreenPriv->CloseScreen;
27535c4bbdfSmrg    pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
27635c4bbdfSmrg    pScreen->InstallColormap = pScreenPriv->InstallColormap;
27735c4bbdfSmrg    pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
27805b261ecSmrg
27935c4bbdfSmrg    free(pScreenPriv);
28005b261ecSmrg
28135c4bbdfSmrg    return ((*pScreen->CloseScreen) (pScreen));
28205b261ecSmrg}
28305b261ecSmrg
28435c4bbdfSmrgstatic void
28505b261ecSmrgDGADestroyColormap(ColormapPtr pmap)
28605b261ecSmrg{
28735c4bbdfSmrg    ScreenPtr pScreen = pmap->pScreen;
28835c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
28935c4bbdfSmrg    VisualPtr pVisual = pmap->pVisual;
29035c4bbdfSmrg
29135c4bbdfSmrg    if (pScreenPriv->fakedVisuals) {
29235c4bbdfSmrg        FakedVisualList *curr = pScreenPriv->fakedVisuals;
29335c4bbdfSmrg
29435c4bbdfSmrg        while (curr) {
29535c4bbdfSmrg            if (curr->pVisual == pVisual) {
29635c4bbdfSmrg                /* We can't get rid of them yet since FreeColormap
29735c4bbdfSmrg                   still needs the pVisual during the cleanup */
29835c4bbdfSmrg                curr->free = TRUE;
29935c4bbdfSmrg                break;
30035c4bbdfSmrg            }
30135c4bbdfSmrg            curr = curr->next;
30235c4bbdfSmrg        }
30335c4bbdfSmrg    }
30435c4bbdfSmrg
30535c4bbdfSmrg    if (pScreenPriv->DestroyColormap) {
30605b261ecSmrg        pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
30735c4bbdfSmrg        (*pScreen->DestroyColormap) (pmap);
30805b261ecSmrg        pScreen->DestroyColormap = DGADestroyColormap;
30935c4bbdfSmrg    }
31005b261ecSmrg}
31105b261ecSmrg
31235c4bbdfSmrgstatic void
31305b261ecSmrgDGAInstallColormap(ColormapPtr pmap)
31405b261ecSmrg{
31505b261ecSmrg    ScreenPtr pScreen = pmap->pScreen;
31605b261ecSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
31705b261ecSmrg
31835c4bbdfSmrg    if (pScreenPriv->current && pScreenPriv->dgaColormap) {
31935c4bbdfSmrg        if (pmap != pScreenPriv->dgaColormap) {
32035c4bbdfSmrg            pScreenPriv->savedColormap = pmap;
32135c4bbdfSmrg            pmap = pScreenPriv->dgaColormap;
32235c4bbdfSmrg        }
32305b261ecSmrg    }
32405b261ecSmrg
32505b261ecSmrg    pScreen->InstallColormap = pScreenPriv->InstallColormap;
32635c4bbdfSmrg    (*pScreen->InstallColormap) (pmap);
32705b261ecSmrg    pScreen->InstallColormap = DGAInstallColormap;
32805b261ecSmrg}
32905b261ecSmrg
33035c4bbdfSmrgstatic void
33105b261ecSmrgDGAUninstallColormap(ColormapPtr pmap)
33205b261ecSmrg{
33305b261ecSmrg    ScreenPtr pScreen = pmap->pScreen;
33405b261ecSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
33505b261ecSmrg
33635c4bbdfSmrg    if (pScreenPriv->current && pScreenPriv->dgaColormap) {
33735c4bbdfSmrg        if (pmap == pScreenPriv->dgaColormap) {
33835c4bbdfSmrg            pScreenPriv->dgaColormap = NULL;
33935c4bbdfSmrg        }
34005b261ecSmrg    }
34105b261ecSmrg
34205b261ecSmrg    pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
34335c4bbdfSmrg    (*pScreen->UninstallColormap) (pmap);
34405b261ecSmrg    pScreen->UninstallColormap = DGAUninstallColormap;
34505b261ecSmrg}
34605b261ecSmrg
34705b261ecSmrgint
34835c4bbdfSmrgxf86SetDGAMode(ScrnInfoPtr pScrn, int num, DGADevicePtr devRet)
34935c4bbdfSmrg{
35035c4bbdfSmrg    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
35135c4bbdfSmrg    DGAScreenPtr pScreenPriv;
35235c4bbdfSmrg    DGADevicePtr device;
35335c4bbdfSmrg    PixmapPtr pPix = NULL;
35435c4bbdfSmrg    DGAModePtr pMode = NULL;
35535c4bbdfSmrg
35635c4bbdfSmrg    /* First check if DGAInit was successful on this screen */
35735c4bbdfSmrg    if (!DGAScreenKeyRegistered)
35835c4bbdfSmrg        return BadValue;
35935c4bbdfSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
36035c4bbdfSmrg    if (!pScreenPriv)
36135c4bbdfSmrg        return BadValue;
36235c4bbdfSmrg
36335c4bbdfSmrg    if (!num) {
36435c4bbdfSmrg        if (pScreenPriv->current) {
36535c4bbdfSmrg            PixmapPtr oldPix = pScreenPriv->current->pPix;
36635c4bbdfSmrg
36735c4bbdfSmrg            if (oldPix) {
36835c4bbdfSmrg                if (oldPix->drawable.id)
36935c4bbdfSmrg                    FreeResource(oldPix->drawable.id, RT_NONE);
37035c4bbdfSmrg                else
37135c4bbdfSmrg                    (*pScreen->DestroyPixmap) (oldPix);
37235c4bbdfSmrg            }
37335c4bbdfSmrg            free(pScreenPriv->current);
37435c4bbdfSmrg            pScreenPriv->current = NULL;
37535c4bbdfSmrg            pScrn->vtSema = TRUE;
37635c4bbdfSmrg            (*pScreenPriv->funcs->SetMode) (pScrn, NULL);
37735c4bbdfSmrg            if (pScreenPriv->savedColormap) {
37835c4bbdfSmrg                (*pScreen->InstallColormap) (pScreenPriv->savedColormap);
37935c4bbdfSmrg                pScreenPriv->savedColormap = NULL;
38035c4bbdfSmrg            }
38135c4bbdfSmrg            pScreenPriv->dgaColormap = NULL;
38235c4bbdfSmrg            (*pScrn->EnableDisableFBAccess) (pScrn, TRUE);
38335c4bbdfSmrg
38435c4bbdfSmrg            FreeMarkedVisuals(pScreen);
38535c4bbdfSmrg        }
38635c4bbdfSmrg
38705b261ecSmrg        pScreenPriv->grabMouse = FALSE;
38805b261ecSmrg        pScreenPriv->grabKeyboard = FALSE;
38905b261ecSmrg
39035c4bbdfSmrg        return Success;
39135c4bbdfSmrg    }
39235c4bbdfSmrg
39335c4bbdfSmrg    if (!pScrn->vtSema && !pScreenPriv->current)        /* Really switched away */
39435c4bbdfSmrg        return BadAlloc;
39505b261ecSmrg
39635c4bbdfSmrg    if ((num > 0) && (num <= pScreenPriv->numModes))
39735c4bbdfSmrg        pMode = &(pScreenPriv->modes[num - 1]);
39835c4bbdfSmrg    else
39935c4bbdfSmrg        return BadValue;
40005b261ecSmrg
40135c4bbdfSmrg    if (!(device = (DGADevicePtr) malloc(sizeof(DGADeviceRec))))
40235c4bbdfSmrg        return BadAlloc;
4039ace9065Smrg
40435c4bbdfSmrg    if (!pScreenPriv->current) {
40535c4bbdfSmrg        Bool oldVTSema = pScrn->vtSema;
40635c4bbdfSmrg
40735c4bbdfSmrg        pScrn->vtSema = FALSE;  /* kludge until we rewrite VT switching */
40835c4bbdfSmrg        (*pScrn->EnableDisableFBAccess) (pScrn, FALSE);
40935c4bbdfSmrg        pScrn->vtSema = oldVTSema;
41035c4bbdfSmrg    }
41135c4bbdfSmrg
41235c4bbdfSmrg    if (!(*pScreenPriv->funcs->SetMode) (pScrn, pMode)) {
41335c4bbdfSmrg        free(device);
41435c4bbdfSmrg        return BadAlloc;
41535c4bbdfSmrg    }
41635c4bbdfSmrg
41735c4bbdfSmrg    pScrn->currentMode = pMode->mode;
41835c4bbdfSmrg
41935c4bbdfSmrg    if (!pScreenPriv->current && !pScreenPriv->input) {
42035c4bbdfSmrg        /* if it's multihead we need to warp the cursor off of
42135c4bbdfSmrg           our screen so it doesn't get trapped  */
42235c4bbdfSmrg    }
42335c4bbdfSmrg
42435c4bbdfSmrg    pScrn->vtSema = FALSE;
42505b261ecSmrg
42635c4bbdfSmrg    if (pScreenPriv->current) {
42735c4bbdfSmrg        PixmapPtr oldPix = pScreenPriv->current->pPix;
42805b261ecSmrg
42935c4bbdfSmrg        if (oldPix) {
43035c4bbdfSmrg            if (oldPix->drawable.id)
43135c4bbdfSmrg                FreeResource(oldPix->drawable.id, RT_NONE);
43235c4bbdfSmrg            else
43335c4bbdfSmrg                (*pScreen->DestroyPixmap) (oldPix);
43435c4bbdfSmrg        }
43535c4bbdfSmrg        free(pScreenPriv->current);
43635c4bbdfSmrg        pScreenPriv->current = NULL;
43735c4bbdfSmrg    }
43835c4bbdfSmrg
43935c4bbdfSmrg    if (pMode->flags & DGA_PIXMAP_AVAILABLE) {
44035c4bbdfSmrg        if ((pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pMode->depth, 0))) {
44135c4bbdfSmrg            (*pScreen->ModifyPixmapHeader) (pPix,
44235c4bbdfSmrg                                            pMode->pixmapWidth,
44335c4bbdfSmrg                                            pMode->pixmapHeight, pMode->depth,
44435c4bbdfSmrg                                            pMode->bitsPerPixel,
44535c4bbdfSmrg                                            pMode->bytesPerScanline,
44635c4bbdfSmrg                                            (void *) (pMode->address));
44735c4bbdfSmrg        }
44835c4bbdfSmrg    }
44935c4bbdfSmrg
45035c4bbdfSmrg    devRet->mode = device->mode = pMode;
45135c4bbdfSmrg    devRet->pPix = device->pPix = pPix;
45235c4bbdfSmrg    pScreenPriv->current = device;
45335c4bbdfSmrg    pScreenPriv->pixmapMode = FALSE;
45435c4bbdfSmrg    pScreenPriv->grabMouse = TRUE;
45535c4bbdfSmrg    pScreenPriv->grabKeyboard = TRUE;
45635c4bbdfSmrg
4575a112b11Smrg    mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
45835c4bbdfSmrg
45935c4bbdfSmrg    return Success;
46035c4bbdfSmrg}
46105b261ecSmrg
46205b261ecSmrg/*********** exported ones ***************/
46305b261ecSmrg
46435c4bbdfSmrgstatic void
46505b261ecSmrgDGASetInputMode(int index, Bool keyboard, Bool mouse)
46605b261ecSmrg{
46735c4bbdfSmrg    ScreenPtr pScreen = screenInfo.screens[index];
46835c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
46905b261ecSmrg
47035c4bbdfSmrg    if (pScreenPriv) {
47135c4bbdfSmrg        pScreenPriv->grabMouse = mouse;
47235c4bbdfSmrg        pScreenPriv->grabKeyboard = keyboard;
47305b261ecSmrg
4745a112b11Smrg        mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
47535c4bbdfSmrg    }
47605b261ecSmrg}
47705b261ecSmrg
47835c4bbdfSmrgstatic Bool
47905b261ecSmrgDGAChangePixmapMode(int index, int *x, int *y, int mode)
48005b261ecSmrg{
48135c4bbdfSmrg    DGAScreenPtr pScreenPriv;
48235c4bbdfSmrg    DGADevicePtr pDev;
48335c4bbdfSmrg    DGAModePtr pMode;
48435c4bbdfSmrg    PixmapPtr pPix;
48505b261ecSmrg
48635c4bbdfSmrg    if (!DGAScreenKeyRegistered)
48735c4bbdfSmrg        return FALSE;
48805b261ecSmrg
48935c4bbdfSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
49005b261ecSmrg
49135c4bbdfSmrg    if (!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
49235c4bbdfSmrg        return FALSE;
49305b261ecSmrg
49435c4bbdfSmrg    pDev = pScreenPriv->current;
49535c4bbdfSmrg    pPix = pDev->pPix;
49635c4bbdfSmrg    pMode = pDev->mode;
49735c4bbdfSmrg
49835c4bbdfSmrg    if (mode) {
49935c4bbdfSmrg        int shift = 2;
50035c4bbdfSmrg
50135c4bbdfSmrg        if (*x > (pMode->pixmapWidth - pMode->viewportWidth))
50235c4bbdfSmrg            *x = pMode->pixmapWidth - pMode->viewportWidth;
50335c4bbdfSmrg        if (*y > (pMode->pixmapHeight - pMode->viewportHeight))
50435c4bbdfSmrg            *y = pMode->pixmapHeight - pMode->viewportHeight;
50535c4bbdfSmrg
50635c4bbdfSmrg        switch (xf86Screens[index]->bitsPerPixel) {
50735c4bbdfSmrg        case 16:
50835c4bbdfSmrg            shift = 1;
50935c4bbdfSmrg            break;
51035c4bbdfSmrg        case 32:
51135c4bbdfSmrg            shift = 0;
51235c4bbdfSmrg            break;
51335c4bbdfSmrg        default:
51435c4bbdfSmrg            break;
51535c4bbdfSmrg        }
51605b261ecSmrg
51735c4bbdfSmrg        if (BITMAP_SCANLINE_PAD == 64)
51835c4bbdfSmrg            shift++;
51905b261ecSmrg
52035c4bbdfSmrg        *x = (*x >> shift) << shift;
52105b261ecSmrg
52235c4bbdfSmrg        pPix->drawable.x = *x;
52335c4bbdfSmrg        pPix->drawable.y = *y;
52435c4bbdfSmrg        pPix->drawable.width = pMode->viewportWidth;
52535c4bbdfSmrg        pPix->drawable.height = pMode->viewportHeight;
52635c4bbdfSmrg    }
52735c4bbdfSmrg    else {
52835c4bbdfSmrg        pPix->drawable.x = 0;
52935c4bbdfSmrg        pPix->drawable.y = 0;
53035c4bbdfSmrg        pPix->drawable.width = pMode->pixmapWidth;
53135c4bbdfSmrg        pPix->drawable.height = pMode->pixmapHeight;
53235c4bbdfSmrg    }
53335c4bbdfSmrg    pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
53435c4bbdfSmrg    pScreenPriv->pixmapMode = mode;
53505b261ecSmrg
53635c4bbdfSmrg    return TRUE;
53735c4bbdfSmrg}
53805b261ecSmrg
53935c4bbdfSmrgBool
54035c4bbdfSmrgDGAScreenAvailable(ScreenPtr pScreen)
54135c4bbdfSmrg{
54235c4bbdfSmrg    if (!DGAScreenKeyRegistered)
54335c4bbdfSmrg        return FALSE;
54405b261ecSmrg
54535c4bbdfSmrg    if (DGA_GET_SCREEN_PRIV(pScreen))
54635c4bbdfSmrg        return TRUE;
54735c4bbdfSmrg    return FALSE;
54805b261ecSmrg}
54905b261ecSmrg
55035c4bbdfSmrgstatic Bool
55135c4bbdfSmrgDGAAvailable(int index)
55205b261ecSmrg{
55335c4bbdfSmrg    ScreenPtr pScreen;
55405b261ecSmrg
55535c4bbdfSmrg    assert(index < MAXSCREENS);
55635c4bbdfSmrg    pScreen = screenInfo.screens[index];
55735c4bbdfSmrg    return DGAScreenAvailable(pScreen);
55805b261ecSmrg}
55905b261ecSmrg
5606747b715SmrgBool
56135c4bbdfSmrgDGAActive(int index)
56205b261ecSmrg{
56335c4bbdfSmrg    DGAScreenPtr pScreenPriv;
56405b261ecSmrg
56535c4bbdfSmrg    if (!DGAScreenKeyRegistered)
56635c4bbdfSmrg        return FALSE;
56705b261ecSmrg
56835c4bbdfSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
56905b261ecSmrg
57035c4bbdfSmrg    if (pScreenPriv && pScreenPriv->current)
57135c4bbdfSmrg        return TRUE;
57205b261ecSmrg
57335c4bbdfSmrg    return FALSE;
57405b261ecSmrg}
57505b261ecSmrg
57605b261ecSmrg/* Called by the extension to initialize a mode */
57705b261ecSmrg
57835c4bbdfSmrgstatic int
57935c4bbdfSmrgDGASetMode(int index, int num, XDGAModePtr mode, PixmapPtr *pPix)
58035c4bbdfSmrg{
58105b261ecSmrg    ScrnInfoPtr pScrn = xf86Screens[index];
58205b261ecSmrg    DGADeviceRec device;
58305b261ecSmrg    int ret;
58405b261ecSmrg
58535c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
58605b261ecSmrg
58735c4bbdfSmrg    ret = (*pScrn->SetDGAMode) (pScrn, num, &device);
58835c4bbdfSmrg    if ((ret == Success) && num) {
58935c4bbdfSmrg        DGACopyModeInfo(device.mode, mode);
59035c4bbdfSmrg        *pPix = device.pPix;
59105b261ecSmrg    }
59205b261ecSmrg
59305b261ecSmrg    return ret;
59405b261ecSmrg}
59505b261ecSmrg
59605b261ecSmrg/* Called from the extension to let the DDX know which events are requested */
59705b261ecSmrg
59835c4bbdfSmrgstatic void
59935c4bbdfSmrgDGASelectInput(int index, ClientPtr client, long mask)
60035c4bbdfSmrg{
60135c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
60205b261ecSmrg
60335c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
60435c4bbdfSmrg    pScreenPriv->client = client;
60535c4bbdfSmrg    pScreenPriv->input = mask;
60605b261ecSmrg}
60705b261ecSmrg
60835c4bbdfSmrgstatic int
60935c4bbdfSmrgDGAGetViewportStatus(int index)
61005b261ecSmrg{
61135c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
61205b261ecSmrg
61335c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
61405b261ecSmrg
61535c4bbdfSmrg    if (!pScreenPriv->funcs->GetViewport)
61635c4bbdfSmrg        return 0;
61705b261ecSmrg
61835c4bbdfSmrg    return (*pScreenPriv->funcs->GetViewport) (pScreenPriv->pScrn);
61905b261ecSmrg}
62005b261ecSmrg
62135c4bbdfSmrgstatic int
62235c4bbdfSmrgDGASetViewport(int index, int x, int y, int mode)
62335c4bbdfSmrg{
62435c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
62505b261ecSmrg
62635c4bbdfSmrg    if (pScreenPriv->funcs->SetViewport)
62735c4bbdfSmrg        (*pScreenPriv->funcs->SetViewport) (pScreenPriv->pScrn, x, y, mode);
62835c4bbdfSmrg    return Success;
62905b261ecSmrg}
63005b261ecSmrg
63105b261ecSmrgstatic int
63205b261ecSmrgBitsClear(CARD32 data)
63305b261ecSmrg{
63435c4bbdfSmrg    int bits = 0;
63535c4bbdfSmrg    CARD32 mask;
63635c4bbdfSmrg
63735c4bbdfSmrg    for (mask = 1; mask; mask <<= 1) {
63835c4bbdfSmrg        if (!(data & mask))
63935c4bbdfSmrg            bits++;
64035c4bbdfSmrg        else
64135c4bbdfSmrg            break;
64235c4bbdfSmrg    }
64305b261ecSmrg
64435c4bbdfSmrg    return bits;
64505b261ecSmrg}
64605b261ecSmrg
64735c4bbdfSmrgstatic int
64805b261ecSmrgDGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
64905b261ecSmrg{
65035c4bbdfSmrg    ScreenPtr pScreen = screenInfo.screens[index];
65135c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
65235c4bbdfSmrg    FakedVisualList *fvlp;
65335c4bbdfSmrg    VisualPtr pVisual;
65435c4bbdfSmrg    DGAModePtr pMode;
65535c4bbdfSmrg    ColormapPtr pmap;
65635c4bbdfSmrg
65735c4bbdfSmrg    if (!mode || (mode > pScreenPriv->numModes))
65835c4bbdfSmrg        return BadValue;
65935c4bbdfSmrg
66035c4bbdfSmrg    if ((alloc != AllocNone) && (alloc != AllocAll))
66135c4bbdfSmrg        return BadValue;
66235c4bbdfSmrg
66335c4bbdfSmrg    pMode = &(pScreenPriv->modes[mode - 1]);
66435c4bbdfSmrg
66535c4bbdfSmrg    if (!(pVisual = malloc(sizeof(VisualRec))))
66635c4bbdfSmrg        return BadAlloc;
66735c4bbdfSmrg
66835c4bbdfSmrg    pVisual->vid = FakeClientID(0);
66935c4bbdfSmrg    pVisual->class = pMode->visualClass;
67035c4bbdfSmrg    pVisual->nplanes = pMode->depth;
67135c4bbdfSmrg    pVisual->ColormapEntries = 1 << pMode->depth;
67235c4bbdfSmrg    pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
67335c4bbdfSmrg
67435c4bbdfSmrg    switch (pVisual->class) {
67535c4bbdfSmrg    case PseudoColor:
67635c4bbdfSmrg    case GrayScale:
67735c4bbdfSmrg    case StaticGray:
67835c4bbdfSmrg        pVisual->bitsPerRGBValue = 8;   /* not quite */
67935c4bbdfSmrg        pVisual->redMask = 0;
68035c4bbdfSmrg        pVisual->greenMask = 0;
68135c4bbdfSmrg        pVisual->blueMask = 0;
68235c4bbdfSmrg        pVisual->offsetRed = 0;
68335c4bbdfSmrg        pVisual->offsetGreen = 0;
68435c4bbdfSmrg        pVisual->offsetBlue = 0;
68535c4bbdfSmrg        break;
68635c4bbdfSmrg    case DirectColor:
68735c4bbdfSmrg    case TrueColor:
68835c4bbdfSmrg        pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
68935c4bbdfSmrg        /* fall through */
69035c4bbdfSmrg    case StaticColor:
69135c4bbdfSmrg        pVisual->redMask = pMode->red_mask;
69235c4bbdfSmrg        pVisual->greenMask = pMode->green_mask;
69335c4bbdfSmrg        pVisual->blueMask = pMode->blue_mask;
69435c4bbdfSmrg        pVisual->offsetRed = BitsClear(pVisual->redMask);
69535c4bbdfSmrg        pVisual->offsetGreen = BitsClear(pVisual->greenMask);
69635c4bbdfSmrg        pVisual->offsetBlue = BitsClear(pVisual->blueMask);
69735c4bbdfSmrg    }
69835c4bbdfSmrg
69935c4bbdfSmrg    if (!(fvlp = malloc(sizeof(FakedVisualList)))) {
70035c4bbdfSmrg        free(pVisual);
70135c4bbdfSmrg        return BadAlloc;
70235c4bbdfSmrg    }
70335c4bbdfSmrg
70435c4bbdfSmrg    fvlp->free = FALSE;
70535c4bbdfSmrg    fvlp->pVisual = pVisual;
70635c4bbdfSmrg    fvlp->next = pScreenPriv->fakedVisuals;
70735c4bbdfSmrg    pScreenPriv->fakedVisuals = fvlp;
70835c4bbdfSmrg
70935c4bbdfSmrg    LEGAL_NEW_RESOURCE(id, client);
71035c4bbdfSmrg
71135c4bbdfSmrg    return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
71205b261ecSmrg}
71305b261ecSmrg
71405b261ecSmrg/*  Called by the extension to install a colormap on DGA active screens */
71505b261ecSmrg
71635c4bbdfSmrgstatic void
71705b261ecSmrgDGAInstallCmap(ColormapPtr cmap)
71805b261ecSmrg{
71905b261ecSmrg    ScreenPtr pScreen = cmap->pScreen;
72005b261ecSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
72105b261ecSmrg
72235c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
72305b261ecSmrg
72435c4bbdfSmrg    if (!pScreenPriv->dgaColormap)
72535c4bbdfSmrg        pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
72605b261ecSmrg
72735c4bbdfSmrg    pScreenPriv->dgaColormap = cmap;
72805b261ecSmrg
72935c4bbdfSmrg    (*pScreen->InstallColormap) (cmap);
73005b261ecSmrg}
73105b261ecSmrg
73235c4bbdfSmrgstatic int
73305b261ecSmrgDGASync(int index)
73405b261ecSmrg{
73535c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
73635c4bbdfSmrg
73735c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
73805b261ecSmrg
73935c4bbdfSmrg    if (pScreenPriv->funcs->Sync)
74035c4bbdfSmrg        (*pScreenPriv->funcs->Sync) (pScreenPriv->pScrn);
74105b261ecSmrg
74235c4bbdfSmrg    return Success;
74305b261ecSmrg}
74405b261ecSmrg
74535c4bbdfSmrgstatic int
74635c4bbdfSmrgDGAFillRect(int index, int x, int y, int w, int h, unsigned long color)
74735c4bbdfSmrg{
74835c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
74905b261ecSmrg
75035c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
75105b261ecSmrg
75235c4bbdfSmrg    if (pScreenPriv->funcs->FillRect &&
75335c4bbdfSmrg        (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
75405b261ecSmrg
75535c4bbdfSmrg        (*pScreenPriv->funcs->FillRect) (pScreenPriv->pScrn, x, y, w, h, color);
75635c4bbdfSmrg        return Success;
75735c4bbdfSmrg    }
75835c4bbdfSmrg    return BadMatch;
75905b261ecSmrg}
76005b261ecSmrg
76135c4bbdfSmrgstatic int
76235c4bbdfSmrgDGABlitRect(int index, int srcx, int srcy, int w, int h, int dstx, int dsty)
76335c4bbdfSmrg{
76435c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
76535c4bbdfSmrg
76635c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
76705b261ecSmrg
76835c4bbdfSmrg    if (pScreenPriv->funcs->BlitRect &&
76935c4bbdfSmrg        (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
77005b261ecSmrg
77135c4bbdfSmrg        (*pScreenPriv->funcs->BlitRect) (pScreenPriv->pScrn,
77235c4bbdfSmrg                                         srcx, srcy, w, h, dstx, dsty);
77335c4bbdfSmrg        return Success;
77435c4bbdfSmrg    }
77535c4bbdfSmrg    return BadMatch;
77605b261ecSmrg}
77705b261ecSmrg
77835c4bbdfSmrgstatic int
77935c4bbdfSmrgDGABlitTransRect(int index,
78035c4bbdfSmrg                 int srcx, int srcy,
78135c4bbdfSmrg                 int w, int h, int dstx, int dsty, unsigned long color)
78235c4bbdfSmrg{
78335c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
78405b261ecSmrg
78535c4bbdfSmrg    /* We rely on the extension to check that DGA is active */
78635c4bbdfSmrg
78735c4bbdfSmrg    if (pScreenPriv->funcs->BlitTransRect &&
78835c4bbdfSmrg        (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
78935c4bbdfSmrg
79035c4bbdfSmrg        (*pScreenPriv->funcs->BlitTransRect) (pScreenPriv->pScrn,
79135c4bbdfSmrg                                              srcx, srcy, w, h, dstx, dsty,
79235c4bbdfSmrg                                              color);
79335c4bbdfSmrg        return Success;
79435c4bbdfSmrg    }
79535c4bbdfSmrg    return BadMatch;
79635c4bbdfSmrg}
79735c4bbdfSmrg
79835c4bbdfSmrgstatic int
79905b261ecSmrgDGAGetModes(int index)
80005b261ecSmrg{
80135c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
80205b261ecSmrg
80335c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
80435c4bbdfSmrg
80535c4bbdfSmrg    return pScreenPriv->numModes;
80605b261ecSmrg}
80705b261ecSmrg
80835c4bbdfSmrgstatic int
80935c4bbdfSmrgDGAGetModeInfo(int index, XDGAModePtr mode, int num)
81035c4bbdfSmrg{
81135c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
81205b261ecSmrg
81335c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
81405b261ecSmrg
81535c4bbdfSmrg    if ((num <= 0) || (num > pScreenPriv->numModes))
81635c4bbdfSmrg        return BadValue;
81705b261ecSmrg
81835c4bbdfSmrg    DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
81905b261ecSmrg
82035c4bbdfSmrg    return Success;
82105b261ecSmrg}
82205b261ecSmrg
82305b261ecSmrgstatic void
82435c4bbdfSmrgDGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode)
82535c4bbdfSmrg{
82635c4bbdfSmrg    DisplayModePtr dmode = mode->mode;
82735c4bbdfSmrg
82835c4bbdfSmrg    xmode->num = mode->num;
82935c4bbdfSmrg    xmode->name = dmode->name;
83035c4bbdfSmrg    xmode->VSync_num = (int) (dmode->VRefresh * 1000.0);
83135c4bbdfSmrg    xmode->VSync_den = 1000;
83235c4bbdfSmrg    xmode->flags = mode->flags;
83335c4bbdfSmrg    xmode->imageWidth = mode->imageWidth;
83435c4bbdfSmrg    xmode->imageHeight = mode->imageHeight;
83535c4bbdfSmrg    xmode->pixmapWidth = mode->pixmapWidth;
83635c4bbdfSmrg    xmode->pixmapHeight = mode->pixmapHeight;
83735c4bbdfSmrg    xmode->bytesPerScanline = mode->bytesPerScanline;
83835c4bbdfSmrg    xmode->byteOrder = mode->byteOrder;
83935c4bbdfSmrg    xmode->depth = mode->depth;
84035c4bbdfSmrg    xmode->bitsPerPixel = mode->bitsPerPixel;
84135c4bbdfSmrg    xmode->red_mask = mode->red_mask;
84235c4bbdfSmrg    xmode->green_mask = mode->green_mask;
84335c4bbdfSmrg    xmode->blue_mask = mode->blue_mask;
84435c4bbdfSmrg    xmode->visualClass = mode->visualClass;
84535c4bbdfSmrg    xmode->viewportWidth = mode->viewportWidth;
84635c4bbdfSmrg    xmode->viewportHeight = mode->viewportHeight;
84735c4bbdfSmrg    xmode->xViewportStep = mode->xViewportStep;
84835c4bbdfSmrg    xmode->yViewportStep = mode->yViewportStep;
84935c4bbdfSmrg    xmode->maxViewportX = mode->maxViewportX;
85035c4bbdfSmrg    xmode->maxViewportY = mode->maxViewportY;
85135c4bbdfSmrg    xmode->viewportFlags = mode->viewportFlags;
85235c4bbdfSmrg    xmode->reserved1 = mode->reserved1;
85335c4bbdfSmrg    xmode->reserved2 = mode->reserved2;
85435c4bbdfSmrg    xmode->offset = mode->offset;
85535c4bbdfSmrg
85635c4bbdfSmrg    if (dmode->Flags & V_INTERLACE)
85735c4bbdfSmrg        xmode->flags |= DGA_INTERLACED;
85835c4bbdfSmrg    if (dmode->Flags & V_DBLSCAN)
85935c4bbdfSmrg        xmode->flags |= DGA_DOUBLESCAN;
86005b261ecSmrg}
86105b261ecSmrg
8626747b715SmrgBool
86305b261ecSmrgDGAVTSwitch(void)
86405b261ecSmrg{
86505b261ecSmrg    ScreenPtr pScreen;
86605b261ecSmrg    int i;
86705b261ecSmrg
86835c4bbdfSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
86935c4bbdfSmrg        pScreen = screenInfo.screens[i];
87005b261ecSmrg
87135c4bbdfSmrg        /* Alternatively, this could send events to DGA clients */
87205b261ecSmrg
87335c4bbdfSmrg        if (DGAScreenKeyRegistered) {
87435c4bbdfSmrg            DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
87505b261ecSmrg
87635c4bbdfSmrg            if (pScreenPriv && pScreenPriv->current)
87735c4bbdfSmrg                return FALSE;
87835c4bbdfSmrg        }
87905b261ecSmrg    }
88005b261ecSmrg
88135c4bbdfSmrg    return TRUE;
88205b261ecSmrg}
88305b261ecSmrg
88405b261ecSmrgBool
8854642e01fSmrgDGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
88605b261ecSmrg{
88735c4bbdfSmrg    DGAScreenPtr pScreenPriv;
88835c4bbdfSmrg    DGAEvent event;
8896747b715Smrg
89035c4bbdfSmrg    if (!DGAScreenKeyRegistered)        /* no DGA */
89105b261ecSmrg        return FALSE;
89205b261ecSmrg
89335c4bbdfSmrg    if (key_code < 8 || key_code > 255)
89435c4bbdfSmrg        return FALSE;
8954642e01fSmrg
89635c4bbdfSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
89705b261ecSmrg
89835c4bbdfSmrg    if (!pScreenPriv || !pScreenPriv->grabKeyboard)     /* no direct mode */
89935c4bbdfSmrg        return FALSE;
90005b261ecSmrg
90135c4bbdfSmrg    event = (DGAEvent) {
90235c4bbdfSmrg        .header = ET_Internal,
90335c4bbdfSmrg        .type = ET_DGAEvent,
90435c4bbdfSmrg        .length = sizeof(event),
90535c4bbdfSmrg        .time = GetTimeInMillis(),
90635c4bbdfSmrg        .subtype = (is_down ? ET_KeyPress : ET_KeyRelease),
90735c4bbdfSmrg        .detail = key_code,
90835c4bbdfSmrg        .dx = 0,
90935c4bbdfSmrg        .dy = 0
91035c4bbdfSmrg    };
91135c4bbdfSmrg    mieqEnqueue(dev, (InternalEvent *) &event);
91205b261ecSmrg
91335c4bbdfSmrg    return TRUE;
91435c4bbdfSmrg}
91505b261ecSmrg
91605b261ecSmrgBool
9174642e01fSmrgDGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
91805b261ecSmrg{
91935c4bbdfSmrg    DGAScreenPtr pScreenPriv;
92035c4bbdfSmrg    DGAEvent event;
92105b261ecSmrg
92235c4bbdfSmrg    if (!DGAScreenKeyRegistered)        /* no DGA */
92305b261ecSmrg        return FALSE;
92405b261ecSmrg
92535c4bbdfSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
92635c4bbdfSmrg
92735c4bbdfSmrg    if (!pScreenPriv || !pScreenPriv->grabMouse)        /* no direct mode */
92805b261ecSmrg        return FALSE;
92905b261ecSmrg
93035c4bbdfSmrg    event = (DGAEvent) {
93135c4bbdfSmrg        .header = ET_Internal,
93235c4bbdfSmrg        .type = ET_DGAEvent,
93335c4bbdfSmrg        .length = sizeof(event),
93435c4bbdfSmrg        .time = GetTimeInMillis(),
93535c4bbdfSmrg        .subtype = ET_Motion,
93635c4bbdfSmrg        .detail = 0,
93735c4bbdfSmrg        .dx = dx,
93835c4bbdfSmrg        .dy = dy
93935c4bbdfSmrg    };
94035c4bbdfSmrg    mieqEnqueue(dev, (InternalEvent *) &event);
94105b261ecSmrg    return TRUE;
94205b261ecSmrg}
94305b261ecSmrg
94405b261ecSmrgBool
9454642e01fSmrgDGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
94605b261ecSmrg{
94705b261ecSmrg    DGAScreenPtr pScreenPriv;
9486747b715Smrg    DGAEvent event;
94905b261ecSmrg
95035c4bbdfSmrg    if (!DGAScreenKeyRegistered)        /* no DGA */
95105b261ecSmrg        return FALSE;
95235c4bbdfSmrg
95305b261ecSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
95405b261ecSmrg
95505b261ecSmrg    if (!pScreenPriv || !pScreenPriv->grabMouse)
95605b261ecSmrg        return FALSE;
95705b261ecSmrg
95835c4bbdfSmrg    event = (DGAEvent) {
95935c4bbdfSmrg        .header = ET_Internal,
96035c4bbdfSmrg        .type = ET_DGAEvent,
96135c4bbdfSmrg        .length = sizeof(event),
96235c4bbdfSmrg        .time = GetTimeInMillis(),
96335c4bbdfSmrg        .subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease),
96435c4bbdfSmrg        .detail = button,
96535c4bbdfSmrg        .dx = 0,
96635c4bbdfSmrg        .dy = 0
96735c4bbdfSmrg    };
96835c4bbdfSmrg    mieqEnqueue(dev, (InternalEvent *) &event);
96905b261ecSmrg
97005b261ecSmrg    return TRUE;
97105b261ecSmrg}
97205b261ecSmrg
97305b261ecSmrg/* We have the power to steal or modify events that are about to get queued */
97405b261ecSmrg
97535c4bbdfSmrg#define NoSuchEvent 0x80000000  /* so doesn't match NoEventMask */
97635c4bbdfSmrgstatic Mask filters[] = {
97735c4bbdfSmrg    NoSuchEvent,                /* 0 */
97835c4bbdfSmrg    NoSuchEvent,                /* 1 */
97935c4bbdfSmrg    KeyPressMask,               /* KeyPress */
98035c4bbdfSmrg    KeyReleaseMask,             /* KeyRelease */
98135c4bbdfSmrg    ButtonPressMask,            /* ButtonPress */
98235c4bbdfSmrg    ButtonReleaseMask,          /* ButtonRelease */
98335c4bbdfSmrg    PointerMotionMask,          /* MotionNotify (initial state) */
98405b261ecSmrg};
98505b261ecSmrg
98605b261ecSmrgstatic void
98735c4bbdfSmrgDGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd)
98835c4bbdfSmrg{
98935c4bbdfSmrg    KeyClassPtr keyc = keybd->key;
99035c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
99135c4bbdfSmrg    DeviceIntPtr pointer = GetMaster(keybd, POINTER_OR_FLOAT);
99235c4bbdfSmrg    DeviceEvent ev = {
99335c4bbdfSmrg        .header = ET_Internal,
99435c4bbdfSmrg        .length = sizeof(ev),
99535c4bbdfSmrg        .detail.key = event->detail,
99635c4bbdfSmrg        .type = event->subtype,
99735c4bbdfSmrg        .root_x = 0,
99835c4bbdfSmrg        .root_y = 0,
99935c4bbdfSmrg        .corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state)
100035c4bbdfSmrg    };
10016747b715Smrg    ev.corestate |= pointer->button->state;
10024642e01fSmrg
10036747b715Smrg    UpdateDeviceState(keybd, &ev);
100405b261ecSmrg
100535c4bbdfSmrg    if (!IsMaster(keybd))
100635c4bbdfSmrg        return;
100735c4bbdfSmrg
100805b261ecSmrg    /*
100905b261ecSmrg     * Deliver the DGA event
101005b261ecSmrg     */
101135c4bbdfSmrg    if (pScreenPriv->client) {
101235c4bbdfSmrg        dgaEvent de = {
101335c4bbdfSmrg            .u.event.time = event->time,
101435c4bbdfSmrg            .u.event.dx = event->dx,
101535c4bbdfSmrg            .u.event.dy = event->dy,
101635c4bbdfSmrg            .u.event.screen = pScreen->myNum,
101735c4bbdfSmrg            .u.event.state = ev.corestate
101835c4bbdfSmrg        };
101935c4bbdfSmrg        de.u.u.type = DGAEventBase + GetCoreType(ev.type);
10206747b715Smrg        de.u.u.detail = event->detail;
102135c4bbdfSmrg
102235c4bbdfSmrg        /* If the DGA client has selected input, then deliver based on the usual filter */
102335c4bbdfSmrg        TryClientEvents(pScreenPriv->client, keybd, (xEvent *) &de, 1,
102435c4bbdfSmrg                        filters[ev.type], pScreenPriv->input, 0);
102505b261ecSmrg    }
102635c4bbdfSmrg    else {
102735c4bbdfSmrg        /* If the keyboard is actively grabbed, deliver a grabbed core event */
102835c4bbdfSmrg        if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab) {
10296747b715Smrg            ev.detail.key = event->detail;
103035c4bbdfSmrg            ev.time = event->time;
103135c4bbdfSmrg            ev.root_x = event->dx;
103235c4bbdfSmrg            ev.root_y = event->dy;
103335c4bbdfSmrg            ev.corestate = event->state;
103435c4bbdfSmrg            ev.deviceid = keybd->id;
103535c4bbdfSmrg            DeliverGrabbedEvent((InternalEvent *) &ev, keybd, FALSE);
103635c4bbdfSmrg        }
103705b261ecSmrg    }
103805b261ecSmrg}
103905b261ecSmrg
104005b261ecSmrgstatic void
104135c4bbdfSmrgDGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
104235c4bbdfSmrg{
104335c4bbdfSmrg    ButtonClassPtr butc = mouse->button;
104435c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
104535c4bbdfSmrg    DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
104635c4bbdfSmrg    DeviceEvent ev = {
104735c4bbdfSmrg        .header = ET_Internal,
104835c4bbdfSmrg        .length = sizeof(ev),
104935c4bbdfSmrg        .detail.key = event->detail,
105035c4bbdfSmrg        .type = event->subtype,
105135c4bbdfSmrg        .corestate = butc ? butc->state : 0
105235c4bbdfSmrg    };
105335c4bbdfSmrg
10546747b715Smrg    if (master && master->key)
10556747b715Smrg        ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
10564642e01fSmrg
10576747b715Smrg    UpdateDeviceState(mouse, &ev);
10584642e01fSmrg
105935c4bbdfSmrg    if (!IsMaster(mouse))
106035c4bbdfSmrg        return;
106135c4bbdfSmrg
106205b261ecSmrg    /*
106305b261ecSmrg     * Deliver the DGA event
106405b261ecSmrg     */
106535c4bbdfSmrg    if (pScreenPriv->client) {
106635c4bbdfSmrg        int coreEquiv = GetCoreType(ev.type);
106735c4bbdfSmrg        dgaEvent de = {
106835c4bbdfSmrg            .u.event.time = event->time,
106935c4bbdfSmrg            .u.event.dx = event->dx,
107035c4bbdfSmrg            .u.event.dy = event->dy,
107135c4bbdfSmrg            .u.event.screen = pScreen->myNum,
107235c4bbdfSmrg            .u.event.state = ev.corestate
107335c4bbdfSmrg        };
107435c4bbdfSmrg        de.u.u.type = DGAEventBase + coreEquiv;
10756747b715Smrg        de.u.u.detail = event->detail;
107635c4bbdfSmrg
107735c4bbdfSmrg        /* If the DGA client has selected input, then deliver based on the usual filter */
107835c4bbdfSmrg        TryClientEvents(pScreenPriv->client, mouse, (xEvent *) &de, 1,
107935c4bbdfSmrg                        filters[coreEquiv], pScreenPriv->input, 0);
108005b261ecSmrg    }
108135c4bbdfSmrg    else {
108235c4bbdfSmrg        /* If the pointer is actively grabbed, deliver a grabbed core event */
108335c4bbdfSmrg        if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab) {
108435c4bbdfSmrg            ev.detail.button = event->detail;
108535c4bbdfSmrg            ev.time = event->time;
108635c4bbdfSmrg            ev.root_x = event->dx;
108735c4bbdfSmrg            ev.root_y = event->dy;
108835c4bbdfSmrg            ev.corestate = event->state;
10898223e2f2Smrg            /* DGA is core only, so valuators.data doesn't actually matter.
10908223e2f2Smrg             * Mask must be set for EventToCore to create motion events. */
10918223e2f2Smrg            SetBit(ev.valuators.mask, 0);
10928223e2f2Smrg            SetBit(ev.valuators.mask, 1);
109335c4bbdfSmrg            DeliverGrabbedEvent((InternalEvent *) &ev, mouse, FALSE);
109435c4bbdfSmrg        }
109505b261ecSmrg    }
109605b261ecSmrg}
109705b261ecSmrg
109835c4bbdfSmrgstatic Bool
109935c4bbdfSmrgDGAOpenFramebuffer(int index,
110035c4bbdfSmrg                   char **name,
110135c4bbdfSmrg                   unsigned char **mem, int *size, int *offset, int *flags)
110235c4bbdfSmrg{
110335c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
110405b261ecSmrg
110535c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
110605b261ecSmrg
110735c4bbdfSmrg    return (*pScreenPriv->funcs->OpenFramebuffer) (pScreenPriv->pScrn,
110835c4bbdfSmrg                                                   name, mem, size, offset,
110935c4bbdfSmrg                                                   flags);
111005b261ecSmrg}
111105b261ecSmrg
111235c4bbdfSmrgstatic void
111305b261ecSmrgDGACloseFramebuffer(int index)
111405b261ecSmrg{
111535c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
111605b261ecSmrg
111735c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
111835c4bbdfSmrg    if (pScreenPriv->funcs->CloseFramebuffer)
111935c4bbdfSmrg        (*pScreenPriv->funcs->CloseFramebuffer) (pScreenPriv->pScrn);
112005b261ecSmrg}
112105b261ecSmrg
112205b261ecSmrg/*  For DGA 1.0 backwards compatibility only */
112305b261ecSmrg
112435c4bbdfSmrgstatic int
112505b261ecSmrgDGAGetOldDGAMode(int index)
112605b261ecSmrg{
112735c4bbdfSmrg    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
112835c4bbdfSmrg    ScrnInfoPtr pScrn = pScreenPriv->pScrn;
112935c4bbdfSmrg    DGAModePtr mode;
113035c4bbdfSmrg    int i, w, h, p;
113135c4bbdfSmrg
113235c4bbdfSmrg    /* We rely on the extension to check that DGA is available */
113305b261ecSmrg
113435c4bbdfSmrg    w = pScrn->currentMode->HDisplay;
113535c4bbdfSmrg    h = pScrn->currentMode->VDisplay;
113635c4bbdfSmrg    p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
113705b261ecSmrg
113835c4bbdfSmrg    for (i = 0; i < pScreenPriv->numModes; i++) {
113935c4bbdfSmrg        mode = &(pScreenPriv->modes[i]);
114005b261ecSmrg
114135c4bbdfSmrg        if ((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
114235c4bbdfSmrg            (mode->bytesPerScanline == p) &&
114335c4bbdfSmrg            (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
114435c4bbdfSmrg            (mode->depth == pScrn->depth)) {
114505b261ecSmrg
114635c4bbdfSmrg            return mode->num;
114735c4bbdfSmrg        }
114835c4bbdfSmrg    }
114905b261ecSmrg
115035c4bbdfSmrg    return 0;
115105b261ecSmrg}
115205b261ecSmrg
115305b261ecSmrgstatic void
11546747b715SmrgDGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
115505b261ecSmrg{
115635c4bbdfSmrg    DGAEvent *event = &ev->dga_event;
115735c4bbdfSmrg    ScreenPtr pScreen = screenInfo.screens[screen_num];
115835c4bbdfSmrg    DGAScreenPtr pScreenPriv;
115905b261ecSmrg
116005b261ecSmrg    /* no DGA */
116135c4bbdfSmrg    if (!DGAScreenKeyRegistered || noXFree86DGAExtension)
116205b261ecSmrg	return;
116305b261ecSmrg    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
11646747b715Smrg
116505b261ecSmrg    /* DGA not initialized on this screen */
116605b261ecSmrg    if (!pScreenPriv)
116735c4bbdfSmrg        return;
11689ace9065Smrg
11696747b715Smrg    switch (event->subtype) {
117005b261ecSmrg    case KeyPress:
117105b261ecSmrg    case KeyRelease:
117235c4bbdfSmrg        DGAProcessKeyboardEvent(pScreen, event, device);
117335c4bbdfSmrg        break;
11746747b715Smrg    case MotionNotify:
11756747b715Smrg    case ButtonPress:
11766747b715Smrg    case ButtonRelease:
117735c4bbdfSmrg        DGAProcessPointerEvent(pScreen, event, device);
11786747b715Smrg        break;
117905b261ecSmrg    default:
118035c4bbdfSmrg        break;
118135c4bbdfSmrg    }
118235c4bbdfSmrg}
118335c4bbdfSmrg
118435c4bbdfSmrgstatic void XDGAResetProc(ExtensionEntry * extEntry);
118535c4bbdfSmrg
118635c4bbdfSmrgstatic void DGAClientStateChange(CallbackListPtr *, void *, void *);
118735c4bbdfSmrg
118835c4bbdfSmrgstatic DevPrivateKeyRec DGAScreenPrivateKeyRec;
118935c4bbdfSmrg
119035c4bbdfSmrg#define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec)
119135c4bbdfSmrg#define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized)
119235c4bbdfSmrgstatic DevPrivateKeyRec DGAClientPrivateKeyRec;
119335c4bbdfSmrg
119435c4bbdfSmrg#define DGAClientPrivateKey (&DGAClientPrivateKeyRec)
119535c4bbdfSmrgstatic int DGACallbackRefCount = 0;
119635c4bbdfSmrg
119735c4bbdfSmrg/* This holds the client's version information */
119835c4bbdfSmrgtypedef struct {
119935c4bbdfSmrg    int major;
120035c4bbdfSmrg    int minor;
120135c4bbdfSmrg} DGAPrivRec, *DGAPrivPtr;
120235c4bbdfSmrg
120335c4bbdfSmrg#define DGA_GETCLIENT(idx) ((ClientPtr) \
120435c4bbdfSmrg    dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
120535c4bbdfSmrg#define DGA_SETCLIENT(idx,p) \
120635c4bbdfSmrg    dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
120735c4bbdfSmrg
120835c4bbdfSmrg#define DGA_GETPRIV(c) ((DGAPrivPtr) \
120935c4bbdfSmrg    dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
121035c4bbdfSmrg#define DGA_SETPRIV(c,p) \
121135c4bbdfSmrg    dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
121235c4bbdfSmrg
121335c4bbdfSmrgstatic void
121435c4bbdfSmrgXDGAResetProc(ExtensionEntry * extEntry)
121535c4bbdfSmrg{
121635c4bbdfSmrg    DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
121735c4bbdfSmrg    DGACallbackRefCount = 0;
121835c4bbdfSmrg}
121935c4bbdfSmrg
122035c4bbdfSmrgstatic int
122135c4bbdfSmrgProcXDGAQueryVersion(ClientPtr client)
122235c4bbdfSmrg{
122335c4bbdfSmrg    xXDGAQueryVersionReply rep;
122435c4bbdfSmrg
122535c4bbdfSmrg    REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
122635c4bbdfSmrg    rep.type = X_Reply;
122735c4bbdfSmrg    rep.length = 0;
122835c4bbdfSmrg    rep.sequenceNumber = client->sequence;
122935c4bbdfSmrg    rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
123035c4bbdfSmrg    rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
123135c4bbdfSmrg
123235c4bbdfSmrg    WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *) &rep);
123335c4bbdfSmrg    return Success;
123435c4bbdfSmrg}
123535c4bbdfSmrg
123635c4bbdfSmrgstatic int
123735c4bbdfSmrgProcXDGAOpenFramebuffer(ClientPtr client)
123835c4bbdfSmrg{
123935c4bbdfSmrg    REQUEST(xXDGAOpenFramebufferReq);
124035c4bbdfSmrg    xXDGAOpenFramebufferReply rep;
124135c4bbdfSmrg    char *deviceName;
124235c4bbdfSmrg    int nameSize;
124335c4bbdfSmrg
12446e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
12456e78d31fSmrg
124635c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
124735c4bbdfSmrg        return BadValue;
124835c4bbdfSmrg
124935c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
125035c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
125135c4bbdfSmrg
125235c4bbdfSmrg    rep.type = X_Reply;
125335c4bbdfSmrg    rep.length = 0;
125435c4bbdfSmrg    rep.sequenceNumber = client->sequence;
125535c4bbdfSmrg
125635c4bbdfSmrg    if (!DGAOpenFramebuffer(stuff->screen, &deviceName,
125735c4bbdfSmrg                            (unsigned char **) (&rep.mem1),
125835c4bbdfSmrg                            (int *) &rep.size, (int *) &rep.offset,
125935c4bbdfSmrg                            (int *) &rep.extra)) {
126035c4bbdfSmrg        return BadAlloc;
126135c4bbdfSmrg    }
126235c4bbdfSmrg
126335c4bbdfSmrg    nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
126435c4bbdfSmrg    rep.length = bytes_to_int32(nameSize);
126535c4bbdfSmrg
126635c4bbdfSmrg    WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *) &rep);
126735c4bbdfSmrg    if (rep.length)
126835c4bbdfSmrg        WriteToClient(client, nameSize, deviceName);
126935c4bbdfSmrg
127035c4bbdfSmrg    return Success;
127135c4bbdfSmrg}
127235c4bbdfSmrg
127335c4bbdfSmrgstatic int
127435c4bbdfSmrgProcXDGACloseFramebuffer(ClientPtr client)
127535c4bbdfSmrg{
127635c4bbdfSmrg    REQUEST(xXDGACloseFramebufferReq);
127735c4bbdfSmrg
12786e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
12796e78d31fSmrg
128035c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
128135c4bbdfSmrg        return BadValue;
128235c4bbdfSmrg
128335c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
128435c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
128535c4bbdfSmrg
128635c4bbdfSmrg    DGACloseFramebuffer(stuff->screen);
128735c4bbdfSmrg
128835c4bbdfSmrg    return Success;
128935c4bbdfSmrg}
129035c4bbdfSmrg
129135c4bbdfSmrgstatic int
129235c4bbdfSmrgProcXDGAQueryModes(ClientPtr client)
129335c4bbdfSmrg{
129435c4bbdfSmrg    int i, num, size;
129535c4bbdfSmrg
129635c4bbdfSmrg    REQUEST(xXDGAQueryModesReq);
129735c4bbdfSmrg    xXDGAQueryModesReply rep;
129835c4bbdfSmrg    xXDGAModeInfo info;
129935c4bbdfSmrg    XDGAModePtr mode;
130035c4bbdfSmrg
13016e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
13026e78d31fSmrg
130335c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
130435c4bbdfSmrg        return BadValue;
130535c4bbdfSmrg
130635c4bbdfSmrg    rep.type = X_Reply;
130735c4bbdfSmrg    rep.length = 0;
130835c4bbdfSmrg    rep.number = 0;
130935c4bbdfSmrg    rep.sequenceNumber = client->sequence;
131035c4bbdfSmrg
131135c4bbdfSmrg    if (!DGAAvailable(stuff->screen)) {
131235c4bbdfSmrg        rep.number = 0;
131335c4bbdfSmrg        rep.length = 0;
131435c4bbdfSmrg        WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
131535c4bbdfSmrg        return Success;
131635c4bbdfSmrg    }
131735c4bbdfSmrg
131835c4bbdfSmrg    if (!(num = DGAGetModes(stuff->screen))) {
131935c4bbdfSmrg        WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
132035c4bbdfSmrg        return Success;
132135c4bbdfSmrg    }
132235c4bbdfSmrg
132335c4bbdfSmrg    if (!(mode = xallocarray(num, sizeof(XDGAModeRec))))
132435c4bbdfSmrg        return BadAlloc;
132535c4bbdfSmrg
132635c4bbdfSmrg    for (i = 0; i < num; i++)
132735c4bbdfSmrg        DGAGetModeInfo(stuff->screen, mode + i, i + 1);
132835c4bbdfSmrg
132935c4bbdfSmrg    size = num * sz_xXDGAModeInfo;
133035c4bbdfSmrg    for (i = 0; i < num; i++)
133135c4bbdfSmrg        size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
133235c4bbdfSmrg
133335c4bbdfSmrg    rep.number = num;
133435c4bbdfSmrg    rep.length = bytes_to_int32(size);
133535c4bbdfSmrg
133635c4bbdfSmrg    WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep);
133735c4bbdfSmrg
133835c4bbdfSmrg    for (i = 0; i < num; i++) {
133935c4bbdfSmrg        size = strlen(mode[i].name) + 1;
134035c4bbdfSmrg
134135c4bbdfSmrg        info.byte_order = mode[i].byteOrder;
134235c4bbdfSmrg        info.depth = mode[i].depth;
134335c4bbdfSmrg        info.num = mode[i].num;
134435c4bbdfSmrg        info.bpp = mode[i].bitsPerPixel;
134535c4bbdfSmrg        info.name_size = (size + 3) & ~3L;
134635c4bbdfSmrg        info.vsync_num = mode[i].VSync_num;
134735c4bbdfSmrg        info.vsync_den = mode[i].VSync_den;
134835c4bbdfSmrg        info.flags = mode[i].flags;
134935c4bbdfSmrg        info.image_width = mode[i].imageWidth;
135035c4bbdfSmrg        info.image_height = mode[i].imageHeight;
135135c4bbdfSmrg        info.pixmap_width = mode[i].pixmapWidth;
135235c4bbdfSmrg        info.pixmap_height = mode[i].pixmapHeight;
135335c4bbdfSmrg        info.bytes_per_scanline = mode[i].bytesPerScanline;
135435c4bbdfSmrg        info.red_mask = mode[i].red_mask;
135535c4bbdfSmrg        info.green_mask = mode[i].green_mask;
135635c4bbdfSmrg        info.blue_mask = mode[i].blue_mask;
135735c4bbdfSmrg        info.visual_class = mode[i].visualClass;
135835c4bbdfSmrg        info.viewport_width = mode[i].viewportWidth;
135935c4bbdfSmrg        info.viewport_height = mode[i].viewportHeight;
136035c4bbdfSmrg        info.viewport_xstep = mode[i].xViewportStep;
136135c4bbdfSmrg        info.viewport_ystep = mode[i].yViewportStep;
136235c4bbdfSmrg        info.viewport_xmax = mode[i].maxViewportX;
136335c4bbdfSmrg        info.viewport_ymax = mode[i].maxViewportY;
136435c4bbdfSmrg        info.viewport_flags = mode[i].viewportFlags;
136535c4bbdfSmrg        info.reserved1 = mode[i].reserved1;
136635c4bbdfSmrg        info.reserved2 = mode[i].reserved2;
136735c4bbdfSmrg
136835c4bbdfSmrg        WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info));
136935c4bbdfSmrg        WriteToClient(client, size, mode[i].name);
137035c4bbdfSmrg    }
137135c4bbdfSmrg
137235c4bbdfSmrg    free(mode);
137335c4bbdfSmrg
137435c4bbdfSmrg    return Success;
137535c4bbdfSmrg}
137635c4bbdfSmrg
137735c4bbdfSmrgstatic void
137835c4bbdfSmrgDGAClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata)
137935c4bbdfSmrg{
138035c4bbdfSmrg    NewClientInfoRec *pci = (NewClientInfoRec *) calldata;
138135c4bbdfSmrg    ClientPtr client = NULL;
138235c4bbdfSmrg    int i;
138335c4bbdfSmrg
138435c4bbdfSmrg    for (i = 0; i < screenInfo.numScreens; i++) {
138535c4bbdfSmrg        if (DGA_GETCLIENT(i) == pci->client) {
138635c4bbdfSmrg            client = pci->client;
138735c4bbdfSmrg            break;
138835c4bbdfSmrg        }
138935c4bbdfSmrg    }
139035c4bbdfSmrg
139135c4bbdfSmrg    if (client &&
139235c4bbdfSmrg        ((client->clientState == ClientStateGone) ||
139335c4bbdfSmrg         (client->clientState == ClientStateRetained))) {
139435c4bbdfSmrg        XDGAModeRec mode;
139535c4bbdfSmrg        PixmapPtr pPix;
139635c4bbdfSmrg
139735c4bbdfSmrg        DGA_SETCLIENT(i, NULL);
139835c4bbdfSmrg        DGASelectInput(i, NULL, 0);
139935c4bbdfSmrg        DGASetMode(i, 0, &mode, &pPix);
140035c4bbdfSmrg
140135c4bbdfSmrg        if (--DGACallbackRefCount == 0)
140235c4bbdfSmrg            DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
140335c4bbdfSmrg    }
140435c4bbdfSmrg}
140535c4bbdfSmrg
140635c4bbdfSmrgstatic int
140735c4bbdfSmrgProcXDGASetMode(ClientPtr client)
140835c4bbdfSmrg{
140935c4bbdfSmrg    REQUEST(xXDGASetModeReq);
141035c4bbdfSmrg    xXDGASetModeReply rep;
141135c4bbdfSmrg    XDGAModeRec mode;
141235c4bbdfSmrg    xXDGAModeInfo info;
141335c4bbdfSmrg    PixmapPtr pPix;
141435c4bbdfSmrg    ClientPtr owner;
141535c4bbdfSmrg    int size;
141635c4bbdfSmrg
14176e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGASetModeReq);
14186e78d31fSmrg
141935c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
142035c4bbdfSmrg        return BadValue;
142135c4bbdfSmrg    owner = DGA_GETCLIENT(stuff->screen);
142235c4bbdfSmrg
142335c4bbdfSmrg    rep.type = X_Reply;
142435c4bbdfSmrg    rep.length = 0;
142535c4bbdfSmrg    rep.offset = 0;
142635c4bbdfSmrg    rep.flags = 0;
142735c4bbdfSmrg    rep.sequenceNumber = client->sequence;
142835c4bbdfSmrg
142935c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
143035c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
143135c4bbdfSmrg
143235c4bbdfSmrg    if (owner && owner != client)
143335c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
143435c4bbdfSmrg
143535c4bbdfSmrg    if (!stuff->mode) {
143635c4bbdfSmrg        if (owner) {
143735c4bbdfSmrg            if (--DGACallbackRefCount == 0)
143835c4bbdfSmrg                DeleteCallback(&ClientStateCallback, DGAClientStateChange,
143935c4bbdfSmrg                               NULL);
144035c4bbdfSmrg        }
144135c4bbdfSmrg        DGA_SETCLIENT(stuff->screen, NULL);
144235c4bbdfSmrg        DGASelectInput(stuff->screen, NULL, 0);
144335c4bbdfSmrg        DGASetMode(stuff->screen, 0, &mode, &pPix);
144435c4bbdfSmrg        WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep);
144535c4bbdfSmrg        return Success;
144635c4bbdfSmrg    }
144735c4bbdfSmrg
144835c4bbdfSmrg    if (Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
144935c4bbdfSmrg        return BadValue;
145035c4bbdfSmrg
145135c4bbdfSmrg    if (!owner) {
145235c4bbdfSmrg        if (DGACallbackRefCount++ == 0)
145335c4bbdfSmrg            AddCallback(&ClientStateCallback, DGAClientStateChange, NULL);
145435c4bbdfSmrg    }
145535c4bbdfSmrg
145635c4bbdfSmrg    DGA_SETCLIENT(stuff->screen, client);
145735c4bbdfSmrg
145835c4bbdfSmrg    if (pPix) {
145935c4bbdfSmrg        if (AddResource(stuff->pid, RT_PIXMAP, (void *) (pPix))) {
146035c4bbdfSmrg            pPix->drawable.id = (int) stuff->pid;
146135c4bbdfSmrg            rep.flags = DGA_PIXMAP_AVAILABLE;
146235c4bbdfSmrg        }
146335c4bbdfSmrg    }
146435c4bbdfSmrg
146535c4bbdfSmrg    size = strlen(mode.name) + 1;
146635c4bbdfSmrg
146735c4bbdfSmrg    info.byte_order = mode.byteOrder;
146835c4bbdfSmrg    info.depth = mode.depth;
146935c4bbdfSmrg    info.num = mode.num;
147035c4bbdfSmrg    info.bpp = mode.bitsPerPixel;
147135c4bbdfSmrg    info.name_size = (size + 3) & ~3L;
147235c4bbdfSmrg    info.vsync_num = mode.VSync_num;
147335c4bbdfSmrg    info.vsync_den = mode.VSync_den;
147435c4bbdfSmrg    info.flags = mode.flags;
147535c4bbdfSmrg    info.image_width = mode.imageWidth;
147635c4bbdfSmrg    info.image_height = mode.imageHeight;
147735c4bbdfSmrg    info.pixmap_width = mode.pixmapWidth;
147835c4bbdfSmrg    info.pixmap_height = mode.pixmapHeight;
147935c4bbdfSmrg    info.bytes_per_scanline = mode.bytesPerScanline;
148035c4bbdfSmrg    info.red_mask = mode.red_mask;
148135c4bbdfSmrg    info.green_mask = mode.green_mask;
148235c4bbdfSmrg    info.blue_mask = mode.blue_mask;
148335c4bbdfSmrg    info.visual_class = mode.visualClass;
148435c4bbdfSmrg    info.viewport_width = mode.viewportWidth;
148535c4bbdfSmrg    info.viewport_height = mode.viewportHeight;
148635c4bbdfSmrg    info.viewport_xstep = mode.xViewportStep;
148735c4bbdfSmrg    info.viewport_ystep = mode.yViewportStep;
148835c4bbdfSmrg    info.viewport_xmax = mode.maxViewportX;
148935c4bbdfSmrg    info.viewport_ymax = mode.maxViewportY;
149035c4bbdfSmrg    info.viewport_flags = mode.viewportFlags;
149135c4bbdfSmrg    info.reserved1 = mode.reserved1;
149235c4bbdfSmrg    info.reserved2 = mode.reserved2;
149335c4bbdfSmrg
149435c4bbdfSmrg    rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
149535c4bbdfSmrg
149635c4bbdfSmrg    WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep);
149735c4bbdfSmrg    WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info));
149835c4bbdfSmrg    WriteToClient(client, size, mode.name);
149935c4bbdfSmrg
150035c4bbdfSmrg    return Success;
150135c4bbdfSmrg}
150235c4bbdfSmrg
150335c4bbdfSmrgstatic int
150435c4bbdfSmrgProcXDGASetViewport(ClientPtr client)
150535c4bbdfSmrg{
150635c4bbdfSmrg    REQUEST(xXDGASetViewportReq);
150735c4bbdfSmrg
15086e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGASetViewportReq);
15096e78d31fSmrg
151035c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
151135c4bbdfSmrg        return BadValue;
151235c4bbdfSmrg
151335c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
151435c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
151535c4bbdfSmrg
151635c4bbdfSmrg    DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
151735c4bbdfSmrg
151835c4bbdfSmrg    return Success;
151935c4bbdfSmrg}
152035c4bbdfSmrg
152135c4bbdfSmrgstatic int
152235c4bbdfSmrgProcXDGAInstallColormap(ClientPtr client)
152335c4bbdfSmrg{
152435c4bbdfSmrg    ColormapPtr cmap;
152535c4bbdfSmrg    int rc;
152635c4bbdfSmrg
152735c4bbdfSmrg    REQUEST(xXDGAInstallColormapReq);
152835c4bbdfSmrg
15296e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
15306e78d31fSmrg
153135c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
153235c4bbdfSmrg        return BadValue;
153335c4bbdfSmrg
153435c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
153535c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
153635c4bbdfSmrg
153735c4bbdfSmrg    rc = dixLookupResourceByType((void **) &cmap, stuff->cmap, RT_COLORMAP,
153835c4bbdfSmrg                                 client, DixInstallAccess);
153935c4bbdfSmrg    if (rc != Success)
154035c4bbdfSmrg        return rc;
154135c4bbdfSmrg    DGAInstallCmap(cmap);
154235c4bbdfSmrg    return Success;
154335c4bbdfSmrg}
154435c4bbdfSmrg
154535c4bbdfSmrgstatic int
154635c4bbdfSmrgProcXDGASelectInput(ClientPtr client)
154735c4bbdfSmrg{
154835c4bbdfSmrg    REQUEST(xXDGASelectInputReq);
154935c4bbdfSmrg
15506e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGASelectInputReq);
15516e78d31fSmrg
155235c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
155335c4bbdfSmrg        return BadValue;
155435c4bbdfSmrg
155535c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
155635c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
155735c4bbdfSmrg
155835c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) == client)
155935c4bbdfSmrg        DGASelectInput(stuff->screen, client, stuff->mask);
156035c4bbdfSmrg
156135c4bbdfSmrg    return Success;
156235c4bbdfSmrg}
156335c4bbdfSmrg
156435c4bbdfSmrgstatic int
156535c4bbdfSmrgProcXDGAFillRectangle(ClientPtr client)
156635c4bbdfSmrg{
156735c4bbdfSmrg    REQUEST(xXDGAFillRectangleReq);
156835c4bbdfSmrg
15696e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
15706e78d31fSmrg
157135c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
157235c4bbdfSmrg        return BadValue;
157335c4bbdfSmrg
157435c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
157535c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
157635c4bbdfSmrg
157735c4bbdfSmrg    if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
157835c4bbdfSmrg                               stuff->width, stuff->height, stuff->color))
157935c4bbdfSmrg        return BadMatch;
158035c4bbdfSmrg
158135c4bbdfSmrg    return Success;
158235c4bbdfSmrg}
158335c4bbdfSmrg
158435c4bbdfSmrgstatic int
158535c4bbdfSmrgProcXDGACopyArea(ClientPtr client)
158635c4bbdfSmrg{
158735c4bbdfSmrg    REQUEST(xXDGACopyAreaReq);
158835c4bbdfSmrg
15896e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
15906e78d31fSmrg
159135c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
159235c4bbdfSmrg        return BadValue;
159335c4bbdfSmrg
159435c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
159535c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
159635c4bbdfSmrg
159735c4bbdfSmrg    if (Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
159835c4bbdfSmrg                               stuff->width, stuff->height, stuff->dstx,
159935c4bbdfSmrg                               stuff->dsty))
160035c4bbdfSmrg        return BadMatch;
160135c4bbdfSmrg
160235c4bbdfSmrg    return Success;
160335c4bbdfSmrg}
160435c4bbdfSmrg
160535c4bbdfSmrgstatic int
160635c4bbdfSmrgProcXDGACopyTransparentArea(ClientPtr client)
160735c4bbdfSmrg{
160835c4bbdfSmrg    REQUEST(xXDGACopyTransparentAreaReq);
160935c4bbdfSmrg
16106e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
16116e78d31fSmrg
161235c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
161335c4bbdfSmrg        return BadValue;
161435c4bbdfSmrg
161535c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
161635c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
161735c4bbdfSmrg
161835c4bbdfSmrg    if (Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
161935c4bbdfSmrg                                    stuff->width, stuff->height, stuff->dstx,
162035c4bbdfSmrg                                    stuff->dsty, stuff->key))
162135c4bbdfSmrg        return BadMatch;
162235c4bbdfSmrg
162335c4bbdfSmrg    return Success;
162435c4bbdfSmrg}
162535c4bbdfSmrg
162635c4bbdfSmrgstatic int
162735c4bbdfSmrgProcXDGAGetViewportStatus(ClientPtr client)
162835c4bbdfSmrg{
162935c4bbdfSmrg    REQUEST(xXDGAGetViewportStatusReq);
163035c4bbdfSmrg    xXDGAGetViewportStatusReply rep;
163135c4bbdfSmrg
16326e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
16336e78d31fSmrg
163435c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
163535c4bbdfSmrg        return BadValue;
163635c4bbdfSmrg
163735c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
163835c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
163935c4bbdfSmrg
164035c4bbdfSmrg    rep.type = X_Reply;
164135c4bbdfSmrg    rep.length = 0;
164235c4bbdfSmrg    rep.sequenceNumber = client->sequence;
164335c4bbdfSmrg
164435c4bbdfSmrg    rep.status = DGAGetViewportStatus(stuff->screen);
164535c4bbdfSmrg
164635c4bbdfSmrg    WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *) &rep);
164735c4bbdfSmrg    return Success;
164835c4bbdfSmrg}
164935c4bbdfSmrg
165035c4bbdfSmrgstatic int
165135c4bbdfSmrgProcXDGASync(ClientPtr client)
165235c4bbdfSmrg{
165335c4bbdfSmrg    REQUEST(xXDGASyncReq);
165435c4bbdfSmrg    xXDGASyncReply rep;
165535c4bbdfSmrg
16566e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGASyncReq);
16576e78d31fSmrg
165835c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
165935c4bbdfSmrg        return BadValue;
166035c4bbdfSmrg
166135c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
166235c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
166335c4bbdfSmrg
166435c4bbdfSmrg    rep.type = X_Reply;
166535c4bbdfSmrg    rep.length = 0;
166635c4bbdfSmrg    rep.sequenceNumber = client->sequence;
166735c4bbdfSmrg
166835c4bbdfSmrg    DGASync(stuff->screen);
166935c4bbdfSmrg
167035c4bbdfSmrg    WriteToClient(client, sizeof(xXDGASyncReply), (char *) &rep);
167135c4bbdfSmrg    return Success;
167235c4bbdfSmrg}
167335c4bbdfSmrg
167435c4bbdfSmrgstatic int
167535c4bbdfSmrgProcXDGASetClientVersion(ClientPtr client)
167635c4bbdfSmrg{
167735c4bbdfSmrg    REQUEST(xXDGASetClientVersionReq);
167835c4bbdfSmrg
167935c4bbdfSmrg    DGAPrivPtr pPriv;
168035c4bbdfSmrg
168135c4bbdfSmrg    REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
168235c4bbdfSmrg    if ((pPriv = DGA_GETPRIV(client)) == NULL) {
168335c4bbdfSmrg        pPriv = malloc(sizeof(DGAPrivRec));
168435c4bbdfSmrg        /* XXX Need to look into freeing this */
168535c4bbdfSmrg        if (!pPriv)
168635c4bbdfSmrg            return BadAlloc;
168735c4bbdfSmrg        DGA_SETPRIV(client, pPriv);
168835c4bbdfSmrg    }
168935c4bbdfSmrg    pPriv->major = stuff->major;
169035c4bbdfSmrg    pPriv->minor = stuff->minor;
169135c4bbdfSmrg
169235c4bbdfSmrg    return Success;
169335c4bbdfSmrg}
169435c4bbdfSmrg
169535c4bbdfSmrgstatic int
169635c4bbdfSmrgProcXDGAChangePixmapMode(ClientPtr client)
169735c4bbdfSmrg{
169835c4bbdfSmrg    REQUEST(xXDGAChangePixmapModeReq);
169935c4bbdfSmrg    xXDGAChangePixmapModeReply rep;
170035c4bbdfSmrg    int x, y;
170135c4bbdfSmrg
17026e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
17036e78d31fSmrg
170435c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
170535c4bbdfSmrg        return BadValue;
170635c4bbdfSmrg
170735c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
170835c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
170935c4bbdfSmrg
171035c4bbdfSmrg    rep.type = X_Reply;
171135c4bbdfSmrg    rep.length = 0;
171235c4bbdfSmrg    rep.sequenceNumber = client->sequence;
171335c4bbdfSmrg
171435c4bbdfSmrg    x = stuff->x;
171535c4bbdfSmrg    y = stuff->y;
171635c4bbdfSmrg
171735c4bbdfSmrg    if (!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
171835c4bbdfSmrg        return BadMatch;
171935c4bbdfSmrg
172035c4bbdfSmrg    rep.x = x;
172135c4bbdfSmrg    rep.y = y;
172235c4bbdfSmrg    WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *) &rep);
172335c4bbdfSmrg
172435c4bbdfSmrg    return Success;
172535c4bbdfSmrg}
172635c4bbdfSmrg
172735c4bbdfSmrgstatic int
172835c4bbdfSmrgProcXDGACreateColormap(ClientPtr client)
172935c4bbdfSmrg{
173035c4bbdfSmrg    REQUEST(xXDGACreateColormapReq);
173135c4bbdfSmrg    int result;
173235c4bbdfSmrg
17336e78d31fSmrg    REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
17346e78d31fSmrg
173535c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
173635c4bbdfSmrg        return BadValue;
173735c4bbdfSmrg
173835c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
173935c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
174035c4bbdfSmrg
174135c4bbdfSmrg    if (!stuff->mode)
174235c4bbdfSmrg        return BadValue;
174335c4bbdfSmrg
174435c4bbdfSmrg    result = DGACreateColormap(stuff->screen, client, stuff->id,
174535c4bbdfSmrg                               stuff->mode, stuff->alloc);
174635c4bbdfSmrg    if (result != Success)
174735c4bbdfSmrg        return result;
174835c4bbdfSmrg
174935c4bbdfSmrg    return Success;
175035c4bbdfSmrg}
175135c4bbdfSmrg
175235c4bbdfSmrg/*
175335c4bbdfSmrg *
175435c4bbdfSmrg * Support for the old DGA protocol, used to live in xf86dga.c
175535c4bbdfSmrg *
175635c4bbdfSmrg */
175735c4bbdfSmrg
175835c4bbdfSmrg#ifdef DGA_PROTOCOL_OLD_SUPPORT
175935c4bbdfSmrg
176035c4bbdfSmrgstatic int
176135c4bbdfSmrgProcXF86DGAGetVideoLL(ClientPtr client)
176235c4bbdfSmrg{
176335c4bbdfSmrg    REQUEST(xXF86DGAGetVideoLLReq);
176435c4bbdfSmrg    xXF86DGAGetVideoLLReply rep;
176535c4bbdfSmrg    XDGAModeRec mode;
176635c4bbdfSmrg    int num, offset, flags;
176735c4bbdfSmrg    char *name;
176835c4bbdfSmrg
17696e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
17706e78d31fSmrg
177135c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
177235c4bbdfSmrg        return BadValue;
177335c4bbdfSmrg
177435c4bbdfSmrg    rep.type = X_Reply;
177535c4bbdfSmrg    rep.length = 0;
177635c4bbdfSmrg    rep.sequenceNumber = client->sequence;
177735c4bbdfSmrg
177835c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
177935c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
178035c4bbdfSmrg
178135c4bbdfSmrg    if (!(num = DGAGetOldDGAMode(stuff->screen)))
178235c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
178335c4bbdfSmrg
178435c4bbdfSmrg    /* get the parameters for the mode that best matches */
178535c4bbdfSmrg    DGAGetModeInfo(stuff->screen, &mode, num);
178635c4bbdfSmrg
178735c4bbdfSmrg    if (!DGAOpenFramebuffer(stuff->screen, &name,
178835c4bbdfSmrg                            (unsigned char **) (&rep.offset),
178935c4bbdfSmrg                            (int *) (&rep.bank_size), &offset, &flags))
179035c4bbdfSmrg        return BadAlloc;
179135c4bbdfSmrg
179235c4bbdfSmrg    rep.offset += mode.offset;
179335c4bbdfSmrg    rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
179435c4bbdfSmrg    rep.ram_size = rep.bank_size >> 10;
179535c4bbdfSmrg
179635c4bbdfSmrg    WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *) &rep);
179735c4bbdfSmrg    return Success;
179835c4bbdfSmrg}
179935c4bbdfSmrg
180035c4bbdfSmrgstatic int
180135c4bbdfSmrgProcXF86DGADirectVideo(ClientPtr client)
180235c4bbdfSmrg{
180335c4bbdfSmrg    int num;
180435c4bbdfSmrg    PixmapPtr pix;
180535c4bbdfSmrg    XDGAModeRec mode;
180635c4bbdfSmrg    ClientPtr owner;
180735c4bbdfSmrg
180835c4bbdfSmrg    REQUEST(xXF86DGADirectVideoReq);
180935c4bbdfSmrg
18106e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
18116e78d31fSmrg
181235c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
181335c4bbdfSmrg        return BadValue;
181435c4bbdfSmrg
181535c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
181635c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
181735c4bbdfSmrg
181835c4bbdfSmrg    owner = DGA_GETCLIENT(stuff->screen);
181935c4bbdfSmrg
182035c4bbdfSmrg    if (owner && owner != client)
182135c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
182235c4bbdfSmrg
182335c4bbdfSmrg    if (stuff->enable & XF86DGADirectGraphics) {
182435c4bbdfSmrg        if (!(num = DGAGetOldDGAMode(stuff->screen)))
182535c4bbdfSmrg            return DGAErrorBase + XF86DGANoDirectVideoMode;
182635c4bbdfSmrg    }
182735c4bbdfSmrg    else
182835c4bbdfSmrg        num = 0;
182935c4bbdfSmrg
183035c4bbdfSmrg    if (Success != DGASetMode(stuff->screen, num, &mode, &pix))
183135c4bbdfSmrg        return DGAErrorBase + XF86DGAScreenNotActive;
183235c4bbdfSmrg
183335c4bbdfSmrg    DGASetInputMode(stuff->screen,
183435c4bbdfSmrg                    (stuff->enable & XF86DGADirectKeyb) != 0,
183535c4bbdfSmrg                    (stuff->enable & XF86DGADirectMouse) != 0);
183635c4bbdfSmrg
183735c4bbdfSmrg    /* We need to track the client and attach the teardown callback */
183835c4bbdfSmrg    if (stuff->enable &
183935c4bbdfSmrg        (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
184035c4bbdfSmrg        if (!owner) {
184135c4bbdfSmrg            if (DGACallbackRefCount++ == 0)
184235c4bbdfSmrg                AddCallback(&ClientStateCallback, DGAClientStateChange, NULL);
184335c4bbdfSmrg        }
184435c4bbdfSmrg
184535c4bbdfSmrg        DGA_SETCLIENT(stuff->screen, client);
184635c4bbdfSmrg    }
184735c4bbdfSmrg    else {
184835c4bbdfSmrg        if (owner) {
184935c4bbdfSmrg            if (--DGACallbackRefCount == 0)
185035c4bbdfSmrg                DeleteCallback(&ClientStateCallback, DGAClientStateChange,
185135c4bbdfSmrg                               NULL);
185235c4bbdfSmrg        }
185335c4bbdfSmrg
185435c4bbdfSmrg        DGA_SETCLIENT(stuff->screen, NULL);
185535c4bbdfSmrg    }
185635c4bbdfSmrg
185735c4bbdfSmrg    return Success;
185835c4bbdfSmrg}
185935c4bbdfSmrg
186035c4bbdfSmrgstatic int
186135c4bbdfSmrgProcXF86DGAGetViewPortSize(ClientPtr client)
186235c4bbdfSmrg{
186335c4bbdfSmrg    int num;
186435c4bbdfSmrg    XDGAModeRec mode;
186535c4bbdfSmrg
186635c4bbdfSmrg    REQUEST(xXF86DGAGetViewPortSizeReq);
186735c4bbdfSmrg    xXF86DGAGetViewPortSizeReply rep;
186835c4bbdfSmrg
18696e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
18706e78d31fSmrg
187135c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
187235c4bbdfSmrg        return BadValue;
187335c4bbdfSmrg
187435c4bbdfSmrg    rep.type = X_Reply;
187535c4bbdfSmrg    rep.length = 0;
187635c4bbdfSmrg    rep.sequenceNumber = client->sequence;
187735c4bbdfSmrg
187835c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
187935c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
188035c4bbdfSmrg
188135c4bbdfSmrg    if (!(num = DGAGetOldDGAMode(stuff->screen)))
188235c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
188335c4bbdfSmrg
188435c4bbdfSmrg    DGAGetModeInfo(stuff->screen, &mode, num);
188535c4bbdfSmrg
188635c4bbdfSmrg    rep.width = mode.viewportWidth;
188735c4bbdfSmrg    rep.height = mode.viewportHeight;
188835c4bbdfSmrg
188935c4bbdfSmrg    WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *) &rep);
189035c4bbdfSmrg    return Success;
189135c4bbdfSmrg}
189235c4bbdfSmrg
189335c4bbdfSmrgstatic int
189435c4bbdfSmrgProcXF86DGASetViewPort(ClientPtr client)
189535c4bbdfSmrg{
189635c4bbdfSmrg    REQUEST(xXF86DGASetViewPortReq);
189735c4bbdfSmrg
18986e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
18996e78d31fSmrg
190035c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
190135c4bbdfSmrg        return BadValue;
190235c4bbdfSmrg
190335c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
190435c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
190535c4bbdfSmrg
190635c4bbdfSmrg    if (!DGAAvailable(stuff->screen))
190735c4bbdfSmrg        return DGAErrorBase + XF86DGANoDirectVideoMode;
190835c4bbdfSmrg
190935c4bbdfSmrg    if (!DGAActive(stuff->screen))
191035c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
191135c4bbdfSmrg
191235c4bbdfSmrg    if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
191335c4bbdfSmrg        != Success)
191435c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
191535c4bbdfSmrg
191635c4bbdfSmrg    return Success;
191735c4bbdfSmrg}
191835c4bbdfSmrg
191935c4bbdfSmrgstatic int
192035c4bbdfSmrgProcXF86DGAGetVidPage(ClientPtr client)
192135c4bbdfSmrg{
192235c4bbdfSmrg    REQUEST(xXF86DGAGetVidPageReq);
192335c4bbdfSmrg    xXF86DGAGetVidPageReply rep;
192435c4bbdfSmrg
19256e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
19266e78d31fSmrg
192735c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
192835c4bbdfSmrg        return BadValue;
192935c4bbdfSmrg
193035c4bbdfSmrg    rep.type = X_Reply;
193135c4bbdfSmrg    rep.length = 0;
193235c4bbdfSmrg    rep.sequenceNumber = client->sequence;
193335c4bbdfSmrg    rep.vpage = 0;              /* silently fail */
193435c4bbdfSmrg
193535c4bbdfSmrg    WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *) &rep);
193635c4bbdfSmrg    return Success;
193735c4bbdfSmrg}
193835c4bbdfSmrg
193935c4bbdfSmrgstatic int
194035c4bbdfSmrgProcXF86DGASetVidPage(ClientPtr client)
194135c4bbdfSmrg{
194235c4bbdfSmrg    REQUEST(xXF86DGASetVidPageReq);
194335c4bbdfSmrg
19446e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
19456e78d31fSmrg
194635c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
194735c4bbdfSmrg        return BadValue;
194835c4bbdfSmrg
194935c4bbdfSmrg    /* silently fail */
195035c4bbdfSmrg
195135c4bbdfSmrg    return Success;
195235c4bbdfSmrg}
195335c4bbdfSmrg
195435c4bbdfSmrgstatic int
195535c4bbdfSmrgProcXF86DGAInstallColormap(ClientPtr client)
195635c4bbdfSmrg{
195735c4bbdfSmrg    ColormapPtr pcmp;
195835c4bbdfSmrg    int rc;
195935c4bbdfSmrg
196035c4bbdfSmrg    REQUEST(xXF86DGAInstallColormapReq);
196135c4bbdfSmrg
19626e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
19636e78d31fSmrg
196435c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
196535c4bbdfSmrg        return BadValue;
196635c4bbdfSmrg
196735c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
196835c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
196935c4bbdfSmrg
197035c4bbdfSmrg    if (!DGAActive(stuff->screen))
197135c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
197235c4bbdfSmrg
197335c4bbdfSmrg    rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
197435c4bbdfSmrg                                 client, DixInstallAccess);
197535c4bbdfSmrg    if (rc == Success) {
197635c4bbdfSmrg        DGAInstallCmap(pcmp);
197735c4bbdfSmrg        return Success;
197835c4bbdfSmrg    }
197935c4bbdfSmrg    else {
198035c4bbdfSmrg        return rc;
198135c4bbdfSmrg    }
198235c4bbdfSmrg}
198335c4bbdfSmrg
198435c4bbdfSmrgstatic int
198535c4bbdfSmrgProcXF86DGAQueryDirectVideo(ClientPtr client)
198635c4bbdfSmrg{
198735c4bbdfSmrg    REQUEST(xXF86DGAQueryDirectVideoReq);
198835c4bbdfSmrg    xXF86DGAQueryDirectVideoReply rep;
198935c4bbdfSmrg
19906e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
19916e78d31fSmrg
199235c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
199335c4bbdfSmrg        return BadValue;
199435c4bbdfSmrg
199535c4bbdfSmrg    rep.type = X_Reply;
199635c4bbdfSmrg    rep.length = 0;
199735c4bbdfSmrg    rep.sequenceNumber = client->sequence;
199835c4bbdfSmrg    rep.flags = 0;
199935c4bbdfSmrg
200035c4bbdfSmrg    if (DGAAvailable(stuff->screen))
200135c4bbdfSmrg        rep.flags = XF86DGADirectPresent;
200235c4bbdfSmrg
200335c4bbdfSmrg    WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *) &rep);
200435c4bbdfSmrg    return Success;
200535c4bbdfSmrg}
200635c4bbdfSmrg
200735c4bbdfSmrgstatic int
200835c4bbdfSmrgProcXF86DGAViewPortChanged(ClientPtr client)
200935c4bbdfSmrg{
201035c4bbdfSmrg    REQUEST(xXF86DGAViewPortChangedReq);
201135c4bbdfSmrg    xXF86DGAViewPortChangedReply rep;
201235c4bbdfSmrg
20136e78d31fSmrg    REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
20146e78d31fSmrg
201535c4bbdfSmrg    if (stuff->screen >= screenInfo.numScreens)
201635c4bbdfSmrg        return BadValue;
201735c4bbdfSmrg
201835c4bbdfSmrg    if (DGA_GETCLIENT(stuff->screen) != client)
201935c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
202035c4bbdfSmrg
202135c4bbdfSmrg    if (!DGAActive(stuff->screen))
202235c4bbdfSmrg        return DGAErrorBase + XF86DGADirectNotActivated;
202335c4bbdfSmrg
202435c4bbdfSmrg    rep.type = X_Reply;
202535c4bbdfSmrg    rep.length = 0;
202635c4bbdfSmrg    rep.sequenceNumber = client->sequence;
202735c4bbdfSmrg    rep.result = 1;
202835c4bbdfSmrg
202935c4bbdfSmrg    WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *) &rep);
203035c4bbdfSmrg    return Success;
203135c4bbdfSmrg}
203235c4bbdfSmrg
203335c4bbdfSmrg#endif                          /* DGA_PROTOCOL_OLD_SUPPORT */
203435c4bbdfSmrg
20357e31ba66Smrgstatic int _X_COLD
203635c4bbdfSmrgSProcXDGADispatch(ClientPtr client)
203735c4bbdfSmrg{
203835c4bbdfSmrg    return DGAErrorBase + XF86DGAClientNotLocal;
203935c4bbdfSmrg}
204035c4bbdfSmrg
204135c4bbdfSmrg#if 0
204235c4bbdfSmrg#define DGA_REQ_DEBUG
204335c4bbdfSmrg#endif
204435c4bbdfSmrg
204535c4bbdfSmrg#ifdef DGA_REQ_DEBUG
204635c4bbdfSmrgstatic char *dgaMinor[] = {
204735c4bbdfSmrg    "QueryVersion",
204835c4bbdfSmrg    "GetVideoLL",
204935c4bbdfSmrg    "DirectVideo",
205035c4bbdfSmrg    "GetViewPortSize",
205135c4bbdfSmrg    "SetViewPort",
205235c4bbdfSmrg    "GetVidPage",
205335c4bbdfSmrg    "SetVidPage",
205435c4bbdfSmrg    "InstallColormap",
205535c4bbdfSmrg    "QueryDirectVideo",
205635c4bbdfSmrg    "ViewPortChanged",
205735c4bbdfSmrg    "10",
205835c4bbdfSmrg    "11",
205935c4bbdfSmrg    "QueryModes",
206035c4bbdfSmrg    "SetMode",
206135c4bbdfSmrg    "SetViewport",
206235c4bbdfSmrg    "InstallColormap",
206335c4bbdfSmrg    "SelectInput",
206435c4bbdfSmrg    "FillRectangle",
206535c4bbdfSmrg    "CopyArea",
206635c4bbdfSmrg    "CopyTransparentArea",
206735c4bbdfSmrg    "GetViewportStatus",
206835c4bbdfSmrg    "Sync",
206935c4bbdfSmrg    "OpenFramebuffer",
207035c4bbdfSmrg    "CloseFramebuffer",
207135c4bbdfSmrg    "SetClientVersion",
207235c4bbdfSmrg    "ChangePixmapMode",
207335c4bbdfSmrg    "CreateColormap",
207435c4bbdfSmrg};
207535c4bbdfSmrg#endif
207635c4bbdfSmrg
207735c4bbdfSmrgstatic int
207835c4bbdfSmrgProcXDGADispatch(ClientPtr client)
207935c4bbdfSmrg{
208035c4bbdfSmrg    REQUEST(xReq);
208135c4bbdfSmrg
208235c4bbdfSmrg    if (!client->local)
208335c4bbdfSmrg        return DGAErrorBase + XF86DGAClientNotLocal;
208435c4bbdfSmrg
208535c4bbdfSmrg#ifdef DGA_REQ_DEBUG
208635c4bbdfSmrg    if (stuff->data <= X_XDGACreateColormap)
208735c4bbdfSmrg        fprintf(stderr, "    DGA %s\n", dgaMinor[stuff->data]);
208835c4bbdfSmrg#endif
208935c4bbdfSmrg
209035c4bbdfSmrg    switch (stuff->data) {
209135c4bbdfSmrg        /*
209235c4bbdfSmrg         * DGA2 Protocol
209335c4bbdfSmrg         */
209435c4bbdfSmrg    case X_XDGAQueryVersion:
209535c4bbdfSmrg        return ProcXDGAQueryVersion(client);
209635c4bbdfSmrg    case X_XDGAQueryModes:
209735c4bbdfSmrg        return ProcXDGAQueryModes(client);
209835c4bbdfSmrg    case X_XDGASetMode:
209935c4bbdfSmrg        return ProcXDGASetMode(client);
210035c4bbdfSmrg    case X_XDGAOpenFramebuffer:
210135c4bbdfSmrg        return ProcXDGAOpenFramebuffer(client);
210235c4bbdfSmrg    case X_XDGACloseFramebuffer:
210335c4bbdfSmrg        return ProcXDGACloseFramebuffer(client);
210435c4bbdfSmrg    case X_XDGASetViewport:
210535c4bbdfSmrg        return ProcXDGASetViewport(client);
210635c4bbdfSmrg    case X_XDGAInstallColormap:
210735c4bbdfSmrg        return ProcXDGAInstallColormap(client);
210835c4bbdfSmrg    case X_XDGASelectInput:
210935c4bbdfSmrg        return ProcXDGASelectInput(client);
211035c4bbdfSmrg    case X_XDGAFillRectangle:
211135c4bbdfSmrg        return ProcXDGAFillRectangle(client);
211235c4bbdfSmrg    case X_XDGACopyArea:
211335c4bbdfSmrg        return ProcXDGACopyArea(client);
211435c4bbdfSmrg    case X_XDGACopyTransparentArea:
211535c4bbdfSmrg        return ProcXDGACopyTransparentArea(client);
211635c4bbdfSmrg    case X_XDGAGetViewportStatus:
211735c4bbdfSmrg        return ProcXDGAGetViewportStatus(client);
211835c4bbdfSmrg    case X_XDGASync:
211935c4bbdfSmrg        return ProcXDGASync(client);
212035c4bbdfSmrg    case X_XDGASetClientVersion:
212135c4bbdfSmrg        return ProcXDGASetClientVersion(client);
212235c4bbdfSmrg    case X_XDGAChangePixmapMode:
212335c4bbdfSmrg        return ProcXDGAChangePixmapMode(client);
212435c4bbdfSmrg    case X_XDGACreateColormap:
212535c4bbdfSmrg        return ProcXDGACreateColormap(client);
212635c4bbdfSmrg        /*
212735c4bbdfSmrg         * Old DGA Protocol
212835c4bbdfSmrg         */
212935c4bbdfSmrg#ifdef DGA_PROTOCOL_OLD_SUPPORT
213035c4bbdfSmrg    case X_XF86DGAGetVideoLL:
213135c4bbdfSmrg        return ProcXF86DGAGetVideoLL(client);
213235c4bbdfSmrg    case X_XF86DGADirectVideo:
213335c4bbdfSmrg        return ProcXF86DGADirectVideo(client);
213435c4bbdfSmrg    case X_XF86DGAGetViewPortSize:
213535c4bbdfSmrg        return ProcXF86DGAGetViewPortSize(client);
213635c4bbdfSmrg    case X_XF86DGASetViewPort:
213735c4bbdfSmrg        return ProcXF86DGASetViewPort(client);
213835c4bbdfSmrg    case X_XF86DGAGetVidPage:
213935c4bbdfSmrg        return ProcXF86DGAGetVidPage(client);
214035c4bbdfSmrg    case X_XF86DGASetVidPage:
214135c4bbdfSmrg        return ProcXF86DGASetVidPage(client);
214235c4bbdfSmrg    case X_XF86DGAInstallColormap:
214335c4bbdfSmrg        return ProcXF86DGAInstallColormap(client);
214435c4bbdfSmrg    case X_XF86DGAQueryDirectVideo:
214535c4bbdfSmrg        return ProcXF86DGAQueryDirectVideo(client);
214635c4bbdfSmrg    case X_XF86DGAViewPortChanged:
214735c4bbdfSmrg        return ProcXF86DGAViewPortChanged(client);
214835c4bbdfSmrg#endif                          /* DGA_PROTOCOL_OLD_SUPPORT */
214935c4bbdfSmrg    default:
215035c4bbdfSmrg        return BadRequest;
215135c4bbdfSmrg    }
215235c4bbdfSmrg}
215335c4bbdfSmrg
215435c4bbdfSmrgvoid
215535c4bbdfSmrgXFree86DGAExtensionInit(void)
215635c4bbdfSmrg{
215735c4bbdfSmrg    ExtensionEntry *extEntry;
215835c4bbdfSmrg
215935c4bbdfSmrg    if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0))
216035c4bbdfSmrg        return;
216135c4bbdfSmrg
216235c4bbdfSmrg    if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
216335c4bbdfSmrg        return;
216435c4bbdfSmrg
216535c4bbdfSmrg    if ((extEntry = AddExtension(XF86DGANAME,
216635c4bbdfSmrg                                 XF86DGANumberEvents,
216735c4bbdfSmrg                                 XF86DGANumberErrors,
216835c4bbdfSmrg                                 ProcXDGADispatch,
216935c4bbdfSmrg                                 SProcXDGADispatch,
217035c4bbdfSmrg                                 XDGAResetProc, StandardMinorOpcode))) {
217135c4bbdfSmrg        int i;
217235c4bbdfSmrg
217335c4bbdfSmrg        DGAReqCode = (unsigned char) extEntry->base;
217435c4bbdfSmrg        DGAErrorBase = extEntry->errorBase;
217535c4bbdfSmrg        DGAEventBase = extEntry->eventBase;
217635c4bbdfSmrg        for (i = KeyPress; i <= MotionNotify; i++)
217735c4bbdfSmrg            SetCriticalEvent(DGAEventBase + i);
217805b261ecSmrg    }
217905b261ecSmrg}
2180