105b261ecSmrg/*
235c4bbdfSmrg * Copyright © 1999 Keith Packard
305b261ecSmrg *
405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
605b261ecSmrg * the above copyright notice appear in all copies and that both that
705b261ecSmrg * copyright notice and this permission notice appear in supporting
805b261ecSmrg * documentation, and that the name of Keith Packard not be used in
905b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1005b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1105b261ecSmrg * representations about the suitability of this software for any purpose.  It
1205b261ecSmrg * is provided "as is" without express or implied warranty.
1305b261ecSmrg *
1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg */
2205b261ecSmrg
231b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H
241b5d61b8Smrg#include <dix-config.h>
2505b261ecSmrg#endif
2605b261ecSmrg#include "kdrive.h"
2705b261ecSmrg
2805b261ecSmrg/*
2905b261ecSmrg * Put the entire colormap into the DAC
3005b261ecSmrg */
3105b261ecSmrg
321b5d61b8Smrgstatic void
3335c4bbdfSmrgKdSetColormap(ScreenPtr pScreen)
3405b261ecSmrg{
3505b261ecSmrg    KdScreenPriv(pScreen);
3635c4bbdfSmrg    ColormapPtr pCmap = pScreenPriv->pInstalledmap;
3735c4bbdfSmrg    Pixel pixels[KD_MAX_PSEUDO_SIZE];
3835c4bbdfSmrg    xrgb colors[KD_MAX_PSEUDO_SIZE];
3935c4bbdfSmrg    xColorItem defs[KD_MAX_PSEUDO_SIZE];
4035c4bbdfSmrg    int i;
4105b261ecSmrg
4205b261ecSmrg    if (!pScreenPriv->card->cfuncs->putColors)
4335c4bbdfSmrg        return;
446747b715Smrg    if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
4535c4bbdfSmrg        return;
466747b715Smrg
4705b261ecSmrg    if (!pScreenPriv->enabled)
4835c4bbdfSmrg        return;
496747b715Smrg
5005b261ecSmrg    if (!pCmap)
5135c4bbdfSmrg        return;
5205b261ecSmrg
5305b261ecSmrg    /*
5405b261ecSmrg     * Make DIX convert pixels into RGB values -- this handles
5505b261ecSmrg     * true/direct as well as pseudo/static visuals
5605b261ecSmrg     */
576747b715Smrg
586747b715Smrg    for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
5935c4bbdfSmrg        pixels[i] = i;
6005b261ecSmrg
6135c4bbdfSmrg    QueryColors(pCmap, (1 << pScreenPriv->screen->fb.depth), pixels, colors,
6235c4bbdfSmrg                serverClient);
636747b715Smrg
6435c4bbdfSmrg    for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++) {
6535c4bbdfSmrg        defs[i].pixel = i;
6635c4bbdfSmrg        defs[i].red = colors[i].red;
6735c4bbdfSmrg        defs[i].green = colors[i].green;
6835c4bbdfSmrg        defs[i].blue = colors[i].blue;
6935c4bbdfSmrg        defs[i].flags = DoRed | DoGreen | DoBlue;
7005b261ecSmrg    }
7105b261ecSmrg
726747b715Smrg    (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
7335c4bbdfSmrg                                             (1 << pScreenPriv->screen->fb.
7435c4bbdfSmrg                                              depth), defs);
7505b261ecSmrg}
7605b261ecSmrg
7705b261ecSmrg/*
7805b261ecSmrg * When the hardware is enabled, save the hardware colors and store
7905b261ecSmrg * the current colormap
8005b261ecSmrg */
8105b261ecSmrgvoid
8235c4bbdfSmrgKdEnableColormap(ScreenPtr pScreen)
8305b261ecSmrg{
8405b261ecSmrg    KdScreenPriv(pScreen);
8535c4bbdfSmrg    int i;
8605b261ecSmrg
8705b261ecSmrg    if (!pScreenPriv->card->cfuncs->putColors)
8835c4bbdfSmrg        return;
8935c4bbdfSmrg
9035c4bbdfSmrg    if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH) {
9135c4bbdfSmrg        for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
9235c4bbdfSmrg            pScreenPriv->systemPalette[i].pixel = i;
9335c4bbdfSmrg        (*pScreenPriv->card->cfuncs->getColors) (pScreen,
9435c4bbdfSmrg                                                 (1 << pScreenPriv->screen->fb.
9535c4bbdfSmrg                                                  depth),
9635c4bbdfSmrg                                                 pScreenPriv->systemPalette);
9705b261ecSmrg    }
9835c4bbdfSmrg    KdSetColormap(pScreen);
9905b261ecSmrg}
10005b261ecSmrg
10105b261ecSmrgvoid
10235c4bbdfSmrgKdDisableColormap(ScreenPtr pScreen)
10305b261ecSmrg{
10405b261ecSmrg    KdScreenPriv(pScreen);
10505b261ecSmrg
10605b261ecSmrg    if (!pScreenPriv->card->cfuncs->putColors)
10735c4bbdfSmrg        return;
10805b261ecSmrg
10935c4bbdfSmrg    if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH) {
11035c4bbdfSmrg        (*pScreenPriv->card->cfuncs->putColors) (pScreen,
11135c4bbdfSmrg                                                 (1 << pScreenPriv->screen->fb.
11235c4bbdfSmrg                                                  depth),
11335c4bbdfSmrg                                                 pScreenPriv->systemPalette);
11405b261ecSmrg    }
11505b261ecSmrg}
11605b261ecSmrg
11705b261ecSmrg/*
11805b261ecSmrg * KdInstallColormap
11905b261ecSmrg *
12005b261ecSmrg * This function is called when the server receives a request to install a
12105b261ecSmrg * colormap or when the server needs to install one on its own, like when
12205b261ecSmrg * there's no window manager running and the user has moved the pointer over
12305b261ecSmrg * an X client window.  It needs to build an identity Windows palette for the
12405b261ecSmrg * colormap and realize it into the Windows system palette.
12505b261ecSmrg */
12605b261ecSmrgvoid
12735c4bbdfSmrgKdInstallColormap(ColormapPtr pCmap)
12805b261ecSmrg{
12905b261ecSmrg    KdScreenPriv(pCmap->pScreen);
13005b261ecSmrg
1316747b715Smrg    if (pCmap == pScreenPriv->pInstalledmap)
13235c4bbdfSmrg        return;
13305b261ecSmrg
13405b261ecSmrg    /* Tell X clients that the installed colormap is going away. */
1356747b715Smrg    if (pScreenPriv->pInstalledmap)
13635c4bbdfSmrg        WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
13735c4bbdfSmrg                 (void *) &(pScreenPriv->pInstalledmap->mid));
13805b261ecSmrg
13905b261ecSmrg    /* Take note of the new installed colorscreen-> */
1406747b715Smrg    pScreenPriv->pInstalledmap = pCmap;
1416747b715Smrg
14235c4bbdfSmrg    KdSetColormap(pCmap->pScreen);
14305b261ecSmrg
14405b261ecSmrg    /* Tell X clients of the new colormap */
14535c4bbdfSmrg    WalkTree(pCmap->pScreen, TellGainedMap, (void *) &(pCmap->mid));
14605b261ecSmrg}
14705b261ecSmrg
14805b261ecSmrg/*
14905b261ecSmrg * KdUninstallColormap
15005b261ecSmrg *
1516747b715Smrg * This function uninstalls a colormap by either installing
15205b261ecSmrg * the default X colormap or erasing the installed colormap pointer.
15305b261ecSmrg * The default X colormap itself cannot be uninstalled.
15405b261ecSmrg */
15505b261ecSmrgvoid
15635c4bbdfSmrgKdUninstallColormap(ColormapPtr pCmap)
15705b261ecSmrg{
15805b261ecSmrg    KdScreenPriv(pCmap->pScreen);
15935c4bbdfSmrg    Colormap defMapID;
16005b261ecSmrg    ColormapPtr defMap;
16105b261ecSmrg
16205b261ecSmrg    /* ignore if not installed */
1636747b715Smrg    if (pCmap != pScreenPriv->pInstalledmap)
16435c4bbdfSmrg        return;
16505b261ecSmrg
16605b261ecSmrg    /* ignore attempts to uninstall default colormap */
16705b261ecSmrg    defMapID = pCmap->pScreen->defColormap;
16805b261ecSmrg    if ((Colormap) pCmap->mid == defMapID)
16935c4bbdfSmrg        return;
17005b261ecSmrg
1716747b715Smrg    /* install default */
17235c4bbdfSmrg    dixLookupResourceByType((void **) &defMap, defMapID, RT_COLORMAP,
17335c4bbdfSmrg                            serverClient, DixInstallAccess);
1746747b715Smrg    if (defMap)
17535c4bbdfSmrg        (*pCmap->pScreen->InstallColormap) (defMap);
17635c4bbdfSmrg    else {
17735c4bbdfSmrg        /* uninstall and clear colormap pointer */
17835c4bbdfSmrg        WalkTree(pCmap->pScreen, TellLostMap, (void *) &(pCmap->mid));
17935c4bbdfSmrg        pScreenPriv->pInstalledmap = 0;
18005b261ecSmrg    }
18105b261ecSmrg}
18205b261ecSmrg
18305b261ecSmrgint
18435c4bbdfSmrgKdListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmaps)
18505b261ecSmrg{
18605b261ecSmrg    KdScreenPriv(pScreen);
18735c4bbdfSmrg    int n = 0;
1886747b715Smrg
18935c4bbdfSmrg    if (pScreenPriv->pInstalledmap) {
19035c4bbdfSmrg        *pCmaps++ = pScreenPriv->pInstalledmap->mid;
19135c4bbdfSmrg        n++;
19205b261ecSmrg    }
19305b261ecSmrg    return n;
19405b261ecSmrg}
19505b261ecSmrg
19605b261ecSmrg/*
19705b261ecSmrg * KdStoreColors
19805b261ecSmrg *
19905b261ecSmrg * This function is called whenever the server receives a request to store
20005b261ecSmrg * color values into one or more entries in the currently installed X
20105b261ecSmrg * colormap; it can be either the default colormap or a private colorscreen->
20205b261ecSmrg */
20305b261ecSmrgvoid
20435c4bbdfSmrgKdStoreColors(ColormapPtr pCmap, int ndef, xColorItem * pdefs)
20505b261ecSmrg{
20605b261ecSmrg    KdScreenPriv(pCmap->pScreen);
20735c4bbdfSmrg    VisualPtr pVisual;
20835c4bbdfSmrg    xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
20905b261ecSmrg
2106747b715Smrg    if (pCmap != pScreenPriv->pInstalledmap)
21135c4bbdfSmrg        return;
2126747b715Smrg
21305b261ecSmrg    if (!pScreenPriv->card->cfuncs->putColors)
21435c4bbdfSmrg        return;
2156747b715Smrg
2166747b715Smrg    if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
21735c4bbdfSmrg        return;
2186747b715Smrg
21905b261ecSmrg    if (!pScreenPriv->enabled)
22035c4bbdfSmrg        return;
2216747b715Smrg
22205b261ecSmrg    /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
22305b261ecSmrg    pVisual = pCmap->pVisual;
22435c4bbdfSmrg    if ((pVisual->class | DynamicClass) == DirectColor) {
22535c4bbdfSmrg        /*
22635c4bbdfSmrg         * Expand DirectColor or TrueColor color values into a PseudoColor
22735c4bbdfSmrg         * format.  Defer to the Color Framebuffer (CFB) code to do that.
22835c4bbdfSmrg         */
22935c4bbdfSmrg        ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
23035c4bbdfSmrg        pdefs = expanddefs;
23105b261ecSmrg    }
23205b261ecSmrg
2336747b715Smrg    (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
23405b261ecSmrg}
235