xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

wincmap.c (18626B)


      1 /*
      2  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
      3  *
      4  *Permission is hereby granted, free of charge, to any person obtaining
      5  * a copy of this software and associated documentation files (the
      6  *"Software"), to deal in the Software without restriction, including
      7  *without limitation the rights to use, copy, modify, merge, publish,
      8  *distribute, sublicense, and/or sell copies of the Software, and to
      9  *permit persons to whom the Software is furnished to do so, subject to
     10  *the following conditions:
     11  *
     12  *The above copyright notice and this permission notice shall be
     13  *included in all copies or substantial portions of the Software.
     14  *
     15  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
     19  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
     20  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     21  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     22  *
     23  *Except as contained in this notice, the name of the XFree86 Project
     24  *shall not be used in advertising or otherwise to promote the sale, use
     25  *or other dealings in this Software without prior written authorization
     26  *from the XFree86 Project.
     27  *
     28  * Authors:	Dakshinamurthy Karra
     29  *		Suhaib M Siddiqi
     30  *		Peter Busch
     31  *		Harold L Hunt II
     32  */
     33 
     34 #ifdef HAVE_XWIN_CONFIG_H
     35 #include <xwin-config.h>
     36 #endif
     37 #include "win.h"
     38 
     39 /*
     40  * Local prototypes
     41  */
     42 
     43 static int
     44  winListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps);
     45 
     46 static void
     47  winStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs);
     48 
     49 static void
     50  winInstallColormap(ColormapPtr pmap);
     51 
     52 static void
     53  winUninstallColormap(ColormapPtr pmap);
     54 
     55 static void
     56 
     57 winResolveColor(unsigned short *pred,
     58                 unsigned short *pgreen,
     59                 unsigned short *pblue, VisualPtr pVisual);
     60 
     61 static Bool
     62  winCreateColormap(ColormapPtr pmap);
     63 
     64 static void
     65  winDestroyColormap(ColormapPtr pmap);
     66 
     67 static Bool
     68  winGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap);
     69 
     70 static Bool
     71  winGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap);
     72 
     73 /*
     74  * Set screen functions for colormaps
     75  */
     76 
     77 void
     78 winSetColormapFunctions(ScreenPtr pScreen)
     79 {
     80     pScreen->CreateColormap = winCreateColormap;
     81     pScreen->DestroyColormap = winDestroyColormap;
     82     pScreen->InstallColormap = winInstallColormap;
     83     pScreen->UninstallColormap = winUninstallColormap;
     84     pScreen->ListInstalledColormaps = winListInstalledColormaps;
     85     pScreen->StoreColors = winStoreColors;
     86     pScreen->ResolveColor = winResolveColor;
     87 }
     88 
     89 /* See Porting Layer Definition - p. 30 */
     90 /*
     91  * Walk the list of installed colormaps, filling the pmaps list
     92  * with the resource ids of the installed maps, and return
     93  * a count of the total number of installed maps.
     94  */
     95 static int
     96 winListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
     97 {
     98     winScreenPriv(pScreen);
     99 
    100     /*
    101      * There will only be one installed colormap, so we only need
    102      * to return one id, and the count of installed maps will always
    103      * be one.
    104      */
    105     *pmaps = pScreenPriv->pcmapInstalled->mid;
    106     return 1;
    107 }
    108 
    109 /* See Porting Layer Definition - p. 30 */
    110 /* See Programming Windows - p. 663 */
    111 static void
    112 winInstallColormap(ColormapPtr pColormap)
    113 {
    114     ScreenPtr pScreen = pColormap->pScreen;
    115 
    116     winScreenPriv(pScreen);
    117     ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
    118 
    119 #if CYGDEBUG
    120     winDebug("winInstallColormap\n");
    121 #endif
    122 
    123     /* Did the colormap actually change? */
    124     if (pColormap != oldpmap) {
    125 #if CYGDEBUG
    126         winDebug("winInstallColormap - Colormap has changed, attempt "
    127                  "to install.\n");
    128 #endif
    129 
    130         /* Was there a previous colormap? */
    131         if (oldpmap != (ColormapPtr) None) {
    132             /* There was a previous colormap; tell clients it is gone */
    133             WalkTree(pColormap->pScreen, TellLostMap, (char *) &oldpmap->mid);
    134         }
    135 
    136         /* Install new colormap */
    137         pScreenPriv->pcmapInstalled = pColormap;
    138         WalkTree(pColormap->pScreen, TellGainedMap, (char *) &pColormap->mid);
    139 
    140         /* Call the engine specific colormap install procedure */
    141         if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) {
    142             winErrorFVerb(2,
    143                           "winInstallColormap - Screen specific colormap install "
    144                           "procedure failed.  Continuing, but colors may be "
    145                           "messed up from now on.\n");
    146         }
    147     }
    148 
    149     /* Save a pointer to the newly installed colormap */
    150     pScreenPriv->pcmapInstalled = pColormap;
    151 }
    152 
    153 /* See Porting Layer Definition - p. 30 */
    154 static void
    155 winUninstallColormap(ColormapPtr pmap)
    156 {
    157     winScreenPriv(pmap->pScreen);
    158     ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
    159 
    160 #if CYGDEBUG
    161     winDebug("winUninstallColormap\n");
    162 #endif
    163 
    164     /* Is the colormap currently installed? */
    165     if (pmap != curpmap) {
    166         /* Colormap not installed, nothing to do */
    167         return;
    168     }
    169 
    170     /* Clear the installed colormap flag */
    171     pScreenPriv->pcmapInstalled = NULL;
    172 
    173     /*
    174      * NOTE: The default colormap does not get "uninstalled" before
    175      * it is destroyed.
    176      */
    177 
    178     /* Install the default cmap in place of the cmap to be uninstalled */
    179     if (pmap->mid != pmap->pScreen->defColormap) {
    180         dixLookupResourceByType((void *) &curpmap, pmap->pScreen->defColormap,
    181                                 RT_COLORMAP, NullClient, DixUnknownAccess);
    182         (*pmap->pScreen->InstallColormap) (curpmap);
    183     }
    184 }
    185 
    186 /* See Porting Layer Definition - p. 30 */
    187 static void
    188 winStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
    189 {
    190     ScreenPtr pScreen = pmap->pScreen;
    191 
    192     winScreenPriv(pScreen);
    193     winCmapPriv(pmap);
    194     int i;
    195     unsigned short nRed, nGreen, nBlue;
    196 
    197 #if CYGDEBUG
    198     if (ndef != 1)
    199         winDebug("winStoreColors - ndef: %d\n", ndef);
    200 #endif
    201 
    202     /* Save the new colors in the colormap privates */
    203     for (i = 0; i < ndef; ++i) {
    204         /* Adjust the colors from the X color spec to the Windows color spec */
    205         nRed = pdefs[i].red >> 8;
    206         nGreen = pdefs[i].green >> 8;
    207         nBlue = pdefs[i].blue >> 8;
    208 
    209         /* Copy the colors to a palette entry table */
    210         pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed;
    211         pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen;
    212         pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue;
    213 
    214         /* Copy the colors to a RGBQUAD table */
    215         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed;
    216         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen;
    217         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue;
    218 
    219 #if CYGDEBUG
    220         winDebug("winStoreColors - nRed %d nGreen %d nBlue %d\n",
    221                  nRed, nGreen, nBlue);
    222 #endif
    223     }
    224 
    225     /* Call the engine specific store colors procedure */
    226     if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) {
    227         winErrorFVerb(2,
    228                       "winStoreColors - Engine cpecific color storage procedure "
    229                       "failed.  Continuing, but colors may be messed up from now "
    230                       "on.\n");
    231     }
    232 }
    233 
    234 /* See Porting Layer Definition - p. 30 */
    235 static void
    236 winResolveColor(unsigned short *pred,
    237                 unsigned short *pgreen,
    238                 unsigned short *pblue, VisualPtr pVisual)
    239 {
    240 #if CYGDEBUG
    241     winDebug("winResolveColor ()\n");
    242 #endif
    243 
    244     miResolveColor(pred, pgreen, pblue, pVisual);
    245 }
    246 
    247 /* See Porting Layer Definition - p. 29 */
    248 static Bool
    249 winCreateColormap(ColormapPtr pmap)
    250 {
    251     winPrivCmapPtr pCmapPriv = NULL;
    252     ScreenPtr pScreen = pmap->pScreen;
    253 
    254     winScreenPriv(pScreen);
    255 
    256 #if CYGDEBUG
    257     winDebug("winCreateColormap\n");
    258 #endif
    259 
    260     /* Allocate colormap privates */
    261     if (!winAllocateCmapPrivates(pmap)) {
    262         ErrorF("winCreateColorma - Couldn't allocate cmap privates\n");
    263         return FALSE;
    264     }
    265 
    266     /* Get a pointer to the newly allocated privates */
    267     pCmapPriv = winGetCmapPriv(pmap);
    268 
    269     /*
    270      * FIXME: This is some evil hackery to help in handling some X clients
    271      * that expect the top pixel to be white.  This "help" only lasts until
    272      * some client overwrites the top colormap entry.
    273      *
    274      * We don't want to actually allocate the top entry, as that causes
    275      * problems with X clients that need 7 planes (128 colors) in the default
    276      * colormap, such as Magic 7.1.
    277      */
    278     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255;
    279     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255;
    280     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255;
    281     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255;
    282     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255;
    283     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255;
    284 
    285     /* Call the engine specific colormap initialization procedure */
    286     if (!((*pScreenPriv->pwinCreateColormap) (pmap))) {
    287         ErrorF("winCreateColormap - Engine specific colormap creation "
    288                "procedure failed.  Aborting.\n");
    289         return FALSE;
    290     }
    291 
    292     return TRUE;
    293 }
    294 
    295 /* See Porting Layer Definition - p. 29, 30 */
    296 static void
    297 winDestroyColormap(ColormapPtr pColormap)
    298 {
    299     winScreenPriv(pColormap->pScreen);
    300     winCmapPriv(pColormap);
    301 
    302     /* Call the engine specific colormap destruction procedure */
    303     if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) {
    304         winErrorFVerb(2,
    305                       "winDestroyColormap - Engine specific colormap destruction "
    306                       "procedure failed.  Continuing, but it is possible that memory "
    307                       "was leaked, or that colors will be messed up from now on.\n");
    308     }
    309 
    310     /* Free the colormap privates */
    311     free(pCmapPriv);
    312     winSetCmapPriv(pColormap, NULL);
    313 
    314 #if CYGDEBUG
    315     winDebug("winDestroyColormap - Returning\n");
    316 #endif
    317 }
    318 
    319 /*
    320  * Internal function to load the palette used by the Shadow DIB
    321  */
    322 
    323 static Bool
    324 winGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap)
    325 {
    326     winScreenPriv(pScreen);
    327     int i;
    328     Pixel pixel;                /* Pixel == CARD32 */
    329     CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
    330     UINT uiColorsRetrieved = 0;
    331     RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
    332 
    333     /* Get the color table for the screen */
    334     uiColorsRetrieved = GetDIBColorTable(pScreenPriv->hdcScreen,
    335                                          0, WIN_NUM_PALETTE_ENTRIES, rgbColors);
    336     if (uiColorsRetrieved == 0) {
    337         ErrorF("winGetPaletteDIB - Could not retrieve screen color table\n");
    338         return FALSE;
    339     }
    340 
    341 #if CYGDEBUG
    342     winDebug("winGetPaletteDIB - Retrieved %d colors from DIB\n",
    343              uiColorsRetrieved);
    344 #endif
    345 
    346     /* Set the DIB color table to the default screen palette */
    347     if (SetDIBColorTable(pScreenPriv->hdcShadow,
    348                          0, uiColorsRetrieved, rgbColors) == 0) {
    349         ErrorF("winGetPaletteDIB - SetDIBColorTable () failed\n");
    350         return FALSE;
    351     }
    352 
    353     /* Alloc each color in the DIB color table */
    354     for (i = 0; i < uiColorsRetrieved; ++i) {
    355         pixel = i;
    356 
    357         /* Extract the color values for current palette entry */
    358         nRed = rgbColors[i].rgbRed << 8;
    359         nGreen = rgbColors[i].rgbGreen << 8;
    360         nBlue = rgbColors[i].rgbBlue << 8;
    361 
    362 #if CYGDEBUG
    363         winDebug("winGetPaletteDIB - Allocating a color: %u; "
    364                  "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
    365 #endif
    366 
    367         /* Allocate a entry in the X colormap */
    368         if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
    369             ErrorF("winGetPaletteDIB - AllocColor () failed, pixel %d\n", i);
    370             return FALSE;
    371         }
    372 
    373         if (i != pixel
    374             || nRed != rgbColors[i].rgbRed
    375             || nGreen != rgbColors[i].rgbGreen
    376             || nBlue != rgbColors[i].rgbBlue) {
    377             winDebug("winGetPaletteDIB - Got: %d; "
    378                      "%d %d %d\n", (int) pixel, nRed, nGreen, nBlue);
    379         }
    380 
    381         /* FIXME: Not sure that this bit is needed at all */
    382         pcmap->red[i].co.local.red = nRed;
    383         pcmap->red[i].co.local.green = nGreen;
    384         pcmap->red[i].co.local.blue = nBlue;
    385     }
    386 
    387     /* System is using a colormap */
    388     /* Set the black and white pixel indices */
    389     pScreen->whitePixel = uiColorsRetrieved - 1;
    390     pScreen->blackPixel = 0;
    391 
    392     return TRUE;
    393 }
    394 
    395 /*
    396  * Internal function to load the standard system palette being used by DD
    397  */
    398 
    399 static Bool
    400 winGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap)
    401 {
    402     int i;
    403     Pixel pixel;                /* Pixel == CARD32 */
    404     CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
    405     UINT uiSystemPaletteEntries;
    406     LPPALETTEENTRY ppeColors = NULL;
    407     HDC hdc = NULL;
    408 
    409     /* Get a DC to obtain the default palette */
    410     hdc = GetDC(NULL);
    411     if (hdc == NULL) {
    412         ErrorF("winGetPaletteDD - Couldn't get a DC\n");
    413         return FALSE;
    414     }
    415 
    416     /* Get the number of entries in the system palette */
    417     uiSystemPaletteEntries = GetSystemPaletteEntries(hdc, 0, 0, NULL);
    418     if (uiSystemPaletteEntries == 0) {
    419         ErrorF("winGetPaletteDD - Unable to determine number of "
    420                "system palette entries\n");
    421         return FALSE;
    422     }
    423 
    424 #if CYGDEBUG
    425     winDebug("winGetPaletteDD - uiSystemPaletteEntries %d\n",
    426              uiSystemPaletteEntries);
    427 #endif
    428 
    429     /* Allocate palette entries structure */
    430     ppeColors = malloc(uiSystemPaletteEntries * sizeof(PALETTEENTRY));
    431     if (ppeColors == NULL) {
    432         ErrorF("winGetPaletteDD - malloc () for colormap failed\n");
    433         return FALSE;
    434     }
    435 
    436     /* Get system palette entries */
    437     GetSystemPaletteEntries(hdc, 0, uiSystemPaletteEntries, ppeColors);
    438 
    439     /* Allocate an X colormap entry for every system palette entry */
    440     for (i = 0; i < uiSystemPaletteEntries; ++i) {
    441         pixel = i;
    442 
    443         /* Extract the color values for current palette entry */
    444         nRed = ppeColors[i].peRed << 8;
    445         nGreen = ppeColors[i].peGreen << 8;
    446         nBlue = ppeColors[i].peBlue << 8;
    447 #if CYGDEBUG
    448         winDebug("winGetPaletteDD - Allocating a color: %u; "
    449                  "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
    450 #endif
    451         if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
    452             ErrorF("winGetPaletteDD - AllocColor () failed, pixel %d\n", i);
    453             free(ppeColors);
    454             ppeColors = NULL;
    455             return FALSE;
    456         }
    457 
    458         pcmap->red[i].co.local.red = nRed;
    459         pcmap->red[i].co.local.green = nGreen;
    460         pcmap->red[i].co.local.blue = nBlue;
    461     }
    462 
    463     /* System is using a colormap */
    464     /* Set the black and white pixel indices */
    465     pScreen->whitePixel = uiSystemPaletteEntries - 1;
    466     pScreen->blackPixel = 0;
    467 
    468     /* Free colormap */
    469     free(ppeColors);
    470     ppeColors = NULL;
    471 
    472     /* Free the DC */
    473     if (hdc != NULL) {
    474         ReleaseDC(NULL, hdc);
    475         hdc = NULL;
    476     }
    477 
    478     return TRUE;
    479 }
    480 
    481 /*
    482  * Install the standard fb colormap, or the GDI colormap,
    483  * depending on the current screen depth.
    484  */
    485 
    486 Bool
    487 winCreateDefColormap(ScreenPtr pScreen)
    488 {
    489     winScreenPriv(pScreen);
    490     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
    491     unsigned short zero = 0, ones = 0xFFFF;
    492     VisualPtr pVisual = pScreenPriv->pRootVisual;
    493     ColormapPtr pcmap = NULL;
    494     Pixel wp, bp;
    495 
    496 #if CYGDEBUG
    497     winDebug("winCreateDefColormap\n");
    498 #endif
    499 
    500     /* Use standard fb colormaps for non palettized color modes */
    501     if (pScreenInfo->dwBPP > 8) {
    502         winDebug("winCreateDefColormap - Deferring to "
    503                  "fbCreateDefColormap ()\n");
    504         return fbCreateDefColormap(pScreen);
    505     }
    506 
    507     /*
    508      *  AllocAll for non-Dynamic visual classes,
    509      *  AllocNone for Dynamic visual classes.
    510      */
    511 
    512     /*
    513      * Dynamic visual classes allow the colors of the color map
    514      * to be changed by clients.
    515      */
    516 
    517 #if CYGDEBUG
    518     winDebug("winCreateDefColormap - defColormap: %lu\n", pScreen->defColormap);
    519 #endif
    520 
    521     /* Allocate an X colormap, owned by client 0 */
    522     if (CreateColormap(pScreen->defColormap,
    523                        pScreen,
    524                        pVisual,
    525                        &pcmap,
    526                        (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
    527                        0) != Success) {
    528         ErrorF("winCreateDefColormap - CreateColormap failed\n");
    529         return FALSE;
    530     }
    531     if (pcmap == NULL) {
    532         ErrorF("winCreateDefColormap - Colormap could not be created\n");
    533         return FALSE;
    534     }
    535 
    536 #if CYGDEBUG
    537     winDebug("winCreateDefColormap - Created a colormap\n");
    538 #endif
    539 
    540     /* Branch on the visual class */
    541     if (!(pVisual->class & DynamicClass)) {
    542         /* Branch on engine type */
    543         if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) {
    544             /* Load the colors being used by the Shadow DIB */
    545             if (!winGetPaletteDIB(pScreen, pcmap)) {
    546                 ErrorF("winCreateDefColormap - Couldn't get DIB colors\n");
    547                 return FALSE;
    548             }
    549         }
    550         else {
    551             /* Load the colors from the default system palette */
    552             if (!winGetPaletteDD(pScreen, pcmap)) {
    553                 ErrorF("winCreateDefColormap - Couldn't get colors "
    554                        "for DD\n");
    555                 return FALSE;
    556             }
    557         }
    558     }
    559     else {
    560         wp = pScreen->whitePixel;
    561         bp = pScreen->blackPixel;
    562 
    563         /* Allocate a black and white pixel */
    564         if ((AllocColor(pcmap, &ones, &ones, &ones, &wp, 0) != Success)
    565             || (AllocColor(pcmap, &zero, &zero, &zero, &bp, 0) != Success)) {
    566             ErrorF("winCreateDefColormap - Couldn't allocate bp or wp\n");
    567             return FALSE;
    568         }
    569 
    570         pScreen->whitePixel = wp;
    571         pScreen->blackPixel = bp;
    572 
    573 #if 0
    574         /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
    575         if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) {
    576             int k;
    577             Pixel p;
    578 
    579             for (k = 1; k < 10; ++k) {
    580                 p = k;
    581                 if (AllocColor(pcmap, &ones, &ones, &ones, &p, 0) != Success)
    582                     FatalError("Foo!\n");
    583             }
    584 
    585             for (k = 245; k < 255; ++k) {
    586                 p = k;
    587                 if (AllocColor(pcmap, &zero, &zero, &zero, &p, 0) != Success)
    588                     FatalError("Baz!\n");
    589             }
    590         }
    591 #endif
    592     }
    593 
    594     /* Install the created colormap */
    595     (*pScreen->InstallColormap) (pcmap);
    596 
    597 #if CYGDEBUG
    598     winDebug("winCreateDefColormap - Returning\n");
    599 #endif
    600 
    601     return TRUE;
    602 }