home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tk42r2s.zip / tk4.2 / os2 / tkOS2Color.c < prev    next >
C/C++ Source or Header  |  1999-07-26  |  20KB  |  728 lines

  1. /* 
  2.  * tkOS2Color.c --
  3.  *
  4.  *    Functions to map color names to system color values.
  5.  *
  6.  * Copyright (c) 1996-1998 Illya Vaes
  7.  * Copyright (c) 1995 Sun Microsystems, Inc.
  8.  * Copyright (c) 1994 Software Research Associates, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  */
  13.  
  14. #include "tkOS2Int.h"
  15. #include "xcolors.h"
  16.  
  17. /*
  18.  * This variable indicates whether the color table has been initialized.
  19.  */
  20.  
  21. static int initialized = 0;
  22.  
  23. /*
  24.  * colorTable is a hash table used to look up X colors by name.
  25.  */
  26.  
  27. static Tcl_HashTable colorTable;
  28.  
  29. /*
  30.  * The SystemColorEntries array contains the names and index values for the
  31.  * OS/2 PM indirect system color names.
  32.  */
  33.  
  34. typedef struct {
  35.     char *name;
  36.     int index;
  37. } SystemColorEntry;
  38.  
  39. static SystemColorEntry sysColorEntries[] = {
  40.     { "SystemActiveBorder",        SYSCLR_ACTIVEBORDER },
  41.     { "SystemActiveCaption",        SYSCLR_ACTIVETITLE },
  42.     { "SystemAppWorkspace",        SYSCLR_APPWORKSPACE },
  43.     { "SystemBackground",        SYSCLR_BACKGROUND },
  44.     { "SystemButtonFace",        SYSCLR_BUTTONMIDDLE },
  45.     { "SystemButtonHighlight",        SYSCLR_BUTTONLIGHT },
  46.     { "SystemButtonShadow",        SYSCLR_BUTTONDARK },
  47.     { "SystemButtonText",        SYSCLR_MENUTEXT },
  48.     { "SystemCaptionText",        SYSCLR_TITLETEXT },
  49.     { "SystemDisabledText",        SYSCLR_MENUDISABLEDTEXT },
  50.     { "SystemHighlight",        SYSCLR_HILITEBACKGROUND },
  51.     { "SystemHighlightText",        SYSCLR_HILITEFOREGROUND },
  52.     { "SystemInactiveBorder",        SYSCLR_INACTIVEBORDER },
  53.     { "SystemInactiveCaption",        SYSCLR_INACTIVETITLE },
  54.     { "SystemInactiveCaptionText",    SYSCLR_INACTIVETITLETEXTBGND },
  55.     { "SystemMenu",            SYSCLR_MENU },
  56.     { "SystemMenuText",            SYSCLR_MENUTEXT },
  57.     { "SystemScrollbar",        SYSCLR_SCROLLBAR },
  58.     { "SystemWindow",            SYSCLR_WINDOW },
  59.     { "SystemWindowFrame",        SYSCLR_WINDOWFRAME },
  60.     { "SystemWindowText",        SYSCLR_WINDOWTEXT },
  61.     { NULL,                0 }
  62. };
  63.  
  64. /*
  65.  * The sysColors array is initialized by SetSystemColors().
  66.  */
  67.  
  68. static XColorEntry sysColors[] = {
  69.     { 0, 0, 0, "SystemActiveBorder" },
  70.     { 0, 0, 0, "SystemActiveCaption" },
  71.     { 0, 0, 0, "SystemAppWorkspace" },
  72.     { 0, 0, 0, "SystemBackground" },
  73.     { 0, 0, 0, "SystemButtonFace" },
  74.     { 0, 0, 0, "SystemButtonHighlight" },
  75.     { 0, 0, 0, "SystemButtonShadow" },
  76.     { 0, 0, 0, "SystemButtonText" },
  77.     { 0, 0, 0, "SystemCaptionText" },
  78.     { 0, 0, 0, "SystemDisabledText" },
  79.     { 0, 0, 0, "SystemHighlight" },
  80.     { 0, 0, 0, "SystemHighlightText" },
  81.     { 0, 0, 0, "SystemInactiveBorder" },
  82.     { 0, 0, 0, "SystemInactiveCaption" },
  83.     { 0, 0, 0, "SystemInactiveCaptionText" },
  84.     { 0, 0, 0, "SystemMenu" },
  85.     { 0, 0, 0, "SystemMenuText" },
  86.     { 0, 0, 0, "SystemScrollbar" },
  87.     { 0, 0, 0, "SystemWindow" },
  88.     { 0, 0, 0, "SystemWindowFrame" },
  89.     { 0, 0, 0, "SystemWindowText" },
  90.     { 0, 0, 0, NULL }
  91. };
  92.  
  93. /*
  94.  * Forward declarations for functions defined later in this file.
  95.  */
  96. static int GetColorByName _ANSI_ARGS_((char *name, XColor *color));
  97. static int GetColorByValue _ANSI_ARGS_((char *value, XColor *color));
  98. static void InitColorTable _ANSI_ARGS_((void));
  99. static void SetSystemColors _ANSI_ARGS_((void));
  100.  
  101.  
  102.  
  103. /*
  104.  *----------------------------------------------------------------------
  105.  *
  106.  * SetSystemColors --
  107.  *
  108.  *    Initializes the sysColors array with the current values for
  109.  *    the system colors.
  110.  *
  111.  * Results:
  112.  *    None.
  113.  *
  114.  * Side effects:
  115.  *    Changes the RGB values stored in the sysColors array.
  116.  *
  117.  *----------------------------------------------------------------------
  118.  */
  119.  
  120. static void
  121. SetSystemColors()
  122. {
  123.     SystemColorEntry *sPtr;
  124.     XColorEntry *ePtr;
  125.     LONG color;
  126.  
  127.     for (ePtr = sysColors, sPtr = sysColorEntries;
  128.      sPtr->name != NULL; ePtr++, sPtr++)
  129.     {
  130.     color = WinQuerySysColor(HWND_DESKTOP, sPtr->index, 0);
  131.     ePtr->red = GetRValue(color);
  132.     ePtr->green = GetGValue(color);
  133.     ePtr->blue = GetBValue(color);
  134.     }
  135. }
  136.  
  137. /*
  138.  *----------------------------------------------------------------------
  139.  *
  140.  * InitColorTable --
  141.  *
  142.  *    Initialize color name database.
  143.  *
  144.  * Results:
  145.  *    None.
  146.  *
  147.  * Side effects:
  148.  *    Builds a hash table of color names and RGB values.
  149.  *
  150.  *----------------------------------------------------------------------
  151.  */
  152.  
  153. static void
  154. InitColorTable()
  155. {
  156.     XColorEntry *colorPtr;
  157.     Tcl_HashEntry *hPtr;
  158.     int dummy;
  159.     char localname[32];
  160.  
  161.     Tcl_InitHashTable(&colorTable, TCL_STRING_KEYS);
  162.  
  163.     /*
  164.      * Add X colors to table.
  165.      */
  166.  
  167.     for (colorPtr = xColors; colorPtr->name != NULL; colorPtr++) {
  168.         /* We need a *modifiable* copy of the string from xColors! */
  169.         strncpy(localname, colorPtr->name, 32);
  170.         hPtr = Tcl_CreateHashEntry(&colorTable, strlwr(localname), &dummy);
  171.         Tcl_SetHashValue(hPtr, colorPtr);
  172.     }
  173.     
  174.     /*
  175.      * Add OS/2 PM indirect system colors to table.
  176.      */
  177.  
  178.     SetSystemColors();
  179.     for (colorPtr = sysColors; colorPtr->name != NULL; colorPtr++) {
  180.         /* We need a *modifiable* copy of the string from sysColors! */
  181.         strncpy(localname, colorPtr->name, 32);
  182.         hPtr = Tcl_CreateHashEntry(&colorTable, strlwr(localname), &dummy);
  183.         Tcl_SetHashValue(hPtr, colorPtr);
  184.     }
  185.  
  186.     initialized = 1;
  187. }
  188.  
  189. /*
  190.  *----------------------------------------------------------------------
  191.  *
  192.  * GetColorByName --
  193.  *
  194.  *    Looks for a color in the color table by name, then finds the
  195.  *    closest available color in the palette and converts it to an
  196.  *    XColor structure.
  197.  *
  198.  * Results:
  199.  *    If it finds a match, the color is returned in the color
  200.  *    parameter and the return value is 1.  Otherwise the return
  201.  *    value is 0.
  202.  *
  203.  * Side effects:
  204.  *    None.
  205.  *
  206.  *----------------------------------------------------------------------
  207.  */
  208.  
  209. static int
  210. GetColorByName(name, color)
  211.     char *name;            /* An X color name, e.g. "red" */
  212.     XColor *color;        /* The closest available color. */
  213. {
  214.     Tcl_HashEntry *hPtr;
  215.     XColorEntry *colorPtr;
  216.     char localname[32];
  217.  
  218.     if (!initialized) {
  219.     InitColorTable();
  220.     }
  221.  
  222.     /* We need a *modifiable* copy of the string name! */
  223.     strncpy(localname, name, 32);
  224.     hPtr = Tcl_FindHashEntry(&colorTable, (char *) strlwr(localname));
  225.  
  226.     if (hPtr == NULL) {
  227.     return 0;
  228.     }
  229.  
  230.     colorPtr = (XColorEntry *) Tcl_GetHashValue(hPtr);
  231.     color->pixel = RGB(colorPtr->red, colorPtr->green, colorPtr->blue);
  232.     color->red = colorPtr->red << 8;
  233.     color->green = colorPtr->green << 8;
  234.     color->blue = colorPtr->blue << 8;
  235.     color->flags = DoRed|DoGreen|DoBlue;
  236.     color->pad = 0;
  237.  
  238.     return 1;
  239. }      
  240.  
  241. /*
  242.  *----------------------------------------------------------------------
  243.  *
  244.  * GetColorByValue --
  245.  *
  246.  *    Parses an X RGB color string and finds the closest available
  247.  *    color in the palette and converts it to an XColor structure.
  248.  *    The returned color will have RGB values in the range 0 to 255.
  249.  *
  250.  * Results:
  251.  *    If it finds a match, the color is returned in the color
  252.  *    parameter and the return value is 1.  Otherwise the return
  253.  *    value is 0.
  254.  *
  255.  * Side effects:
  256.  *    None.
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260.  
  261. static int
  262. GetColorByValue(value, color)
  263.     char *value;        /* a string of the form "#RGB", "#RRGGBB", */
  264.                 /* "#RRRGGGBBB", or "#RRRRGGGGBBBB" */
  265.     XColor *color;        /* The closest available color. */
  266. {
  267.     char fmt[16];
  268.     int i;
  269.  
  270.     i = strlen(value+1);
  271.     if (i % 3) {
  272.     return 0;
  273.     }
  274.     i /= 3;
  275.     if (i == 0) {
  276.     return 0;
  277.     }
  278.     sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i);
  279.     sscanf(value+1, fmt, &color->red, &color->green, &color->blue);
  280.     /*
  281.      * Scale the parse values into 8 bits.
  282.      */
  283.     if (i == 1) {
  284.     color->red <<= 4;
  285.     color->green <<= 4;
  286.     color->blue <<= 4;
  287.     } else if (i != 2) {
  288.     color->red >>= (4*(i-2));
  289.     color->green >>= (4*(i-2));
  290.     color->blue >>= (4*(i-2));
  291.     }    
  292.     color->pad = 0;
  293.     color->pixel = RGB(color->red, color->green, color->blue); 
  294.     color->red = color->red << 8;
  295.     color->green = color->green << 8;
  296.     color->blue = color->blue << 8;
  297.  
  298.     return 1;
  299. }
  300.  
  301. /*
  302.  *----------------------------------------------------------------------
  303.  *
  304.  * XParseColor --
  305.  *
  306.  *    Decodes an X color specification.
  307.  *
  308.  * Results:
  309.  *    Sets exact_def_return to the parsed color.
  310.  *
  311.  * Side effects:
  312.  *    None.
  313.  *
  314.  *----------------------------------------------------------------------
  315.  */
  316.  
  317. int
  318. XParseColor(display, colormap, spec, exact_def_return)
  319.     Display* display;
  320.     Colormap colormap;
  321.     _Xconst char* spec;
  322.     XColor* exact_def_return;
  323. {
  324.     /*
  325.      * Note that we are violating the const-ness of spec.  This is
  326.      * probably OK in most cases.  But this is a bug in general.
  327.      */
  328.  
  329.     if (spec[0] == '#') {
  330.     return GetColorByValue((char *)spec, exact_def_return);
  331.     } else {
  332.     return GetColorByName((char *)spec, exact_def_return);
  333.     }
  334. }
  335.  
  336. /*
  337.  *----------------------------------------------------------------------
  338.  *
  339.  * XAllocColor --
  340.  *
  341.  *    Find the closest available color to the specified XColor.
  342.  *
  343.  * Results:
  344.  *    Updates the color argument and returns 1 on success.  Otherwise
  345.  *    returns 0.
  346.  *
  347.  * Side effects:
  348.  *    Allocates a new color in the palette.
  349.  *
  350.  *----------------------------------------------------------------------
  351.  */
  352.  
  353. int
  354. XAllocColor(display, colormap, color)
  355.     Display* display;
  356.     Colormap colormap;
  357.     XColor* color;
  358. {
  359.     TkOS2Colormap *cmap = (TkOS2Colormap *) colormap;
  360.     RGB entry;
  361.     HPAL oldPal;
  362.     ULONG *palInfo;
  363.     LONG i, found = -1;
  364.  
  365.     /* We lose significance when converting to PM, 256 values per color */
  366.     /*
  367.     entry.bRed = (color->red) / 256;
  368.     entry.bGreen = (color->green) / 256;
  369.     entry.bBlue = (color->blue) / 256;
  370.     */
  371.     entry.bRed = (color->red) >> 8;
  372.     entry.bGreen = (color->green) >> 8;
  373.     entry.bBlue = (color->blue) >> 8;
  374.  
  375.     if (aDevCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) {
  376.     /*
  377.      * Palette support
  378.      */
  379.     ULONG newPixel;
  380.         HPS hps;
  381.     int new, refCount;
  382.     Tcl_HashEntry *entryPtr;
  383.  
  384.         hps = WinGetScreenPS(HWND_DESKTOP);
  385.  
  386.     /*
  387.      * Find the nearest existing palette entry.
  388.      */
  389.     
  390.     newPixel = RGB(entry.bRed, entry.bGreen, entry.bBlue);
  391.     oldPal= GpiSelectPalette(hps, cmap->palette);
  392.     if (oldPal == PAL_ERROR) {
  393.             WinReleasePS(hps);
  394.             return 0;
  395.     }
  396.     palInfo= (ULONG *) ckalloc(sizeof(ULONG) * (cmap->size+1));
  397.  
  398.     if (GpiQueryPaletteInfo(cmap->palette, hps, 0L, 0L, cmap->size,
  399.                             palInfo) == PAL_ERROR) {
  400.         GpiSelectPalette(hps, oldPal);
  401.             WinReleasePS(hps);
  402.         ckfree((char *) palInfo);
  403.             return 0;
  404.     }
  405.  
  406.     /*
  407.      * If this is not a duplicate, allocate a new entry.
  408.      */
  409.     
  410.         for (i=0; i<cmap->size; i++) {
  411.             if (palInfo[i] == newPixel) {
  412.                 found = i;
  413.             }
  414.         }
  415.  
  416.     if (found == -1) {
  417.  
  418.         /*
  419.          * Fails if the palette is full.
  420.          */
  421.         if (cmap->size == aDevCaps[CAPS_COLOR_INDEX]) {
  422.             GpiSelectPalette(hps, oldPal);
  423.                 WinReleasePS(hps);
  424.             ckfree((char *) palInfo);
  425.         return 0;
  426.         }
  427.     
  428.         cmap->size++;
  429.         palInfo[cmap->size-1]= newPixel;
  430.         GpiSetPaletteEntries(cmap->palette, LCOLF_CONSECRGB, 0L, cmap->size,
  431.                              palInfo);
  432.     }
  433.  
  434.     ckfree((char *) palInfo);
  435.         /*
  436.          * Assign the _index_ in the palette as the pixel, for later use in
  437.          * GpiSetColor et al. ()
  438.          */
  439.         color->pixel = cmap->size-1;
  440.     entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,
  441.         (char *)color->pixel, &new);
  442.     if (new) {
  443.         refCount = 1;
  444.     } else {
  445.         refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1;
  446.     }
  447.     Tcl_SetHashValue(entryPtr, (ClientData)refCount);
  448.  
  449.     WinReleasePS(hps);
  450.  
  451.     } else {
  452.        LONG index, iColor;
  453.  
  454.     /*
  455.      * Determine what color will actually be used on non-colormap systems.
  456.      */
  457.  
  458.     color->pixel = GpiQueryNearestColor(globalPS, 0L,
  459.         RGB(entry.bRed, entry.bGreen, entry.bBlue));
  460.     color->red = (GetRValue(color->pixel) << 8);
  461.     color->green = (GetGValue(color->pixel) << 8);
  462.     color->blue = (GetBValue(color->pixel) << 8);
  463.         if (display->screens->root_visual->class != TrueColor){
  464.         /* See if this color is already in the color table */
  465.             index = GpiQueryColorIndex(globalPS, 0L, color->pixel);
  466.         rc = GpiQueryLogColorTable(globalPS, 0L, index, 1, &iColor);
  467.         /*
  468.          * If the color isn't in the table yet and loadable color table
  469.          * support, add this color to the table, else just use what's
  470.              * available.
  471.          */
  472.         if (iColor != color->pixel && aDevCaps[CAPS_COLOR_TABLE_SUPPORT]
  473.             && (nextColor <= aDevCaps[CAPS_COLOR_INDEX])) {
  474.             rc = GpiCreateLogColorTable(globalPS, 0L, LCOLF_RGB, nextColor,
  475.                                         1, &color->pixel);
  476.                 if (rc==TRUE) {
  477.                     color->pixel = nextColor;
  478.                     nextColor++;
  479.                 } else {
  480.                     color->pixel = index;
  481.                 }
  482.             } else {
  483.                 color->pixel = index;
  484.             }
  485.         } /* TrueColor */
  486.     }
  487.  
  488.     return 1;
  489. }
  490.  
  491. /*
  492.  *----------------------------------------------------------------------
  493.  *
  494.  * XAllocNamedColor --
  495.  *
  496.  *    Find the closest color of the given name.
  497.  *
  498.  * Results:
  499.  *    Returns 1 on success with the resulting color in
  500.  *    exact_def_return.  Returns 0 on failure.
  501.  *
  502.  * Side effects:
  503.  *    Allocates a new color in the palette.
  504.  *
  505.  *----------------------------------------------------------------------
  506.  */
  507.  
  508. int
  509. XAllocNamedColor(display, colormap, color_name, screen_def_return,
  510.     exact_def_return)
  511.     Display* display;
  512.     Colormap colormap;
  513.     _Xconst char* color_name;
  514.     XColor* screen_def_return;
  515.     XColor* exact_def_return;
  516. {
  517.     int rval = GetColorByName((char *)color_name, exact_def_return);
  518.  
  519.     if (rval) {
  520.     *screen_def_return = *exact_def_return;
  521.     return XAllocColor(display, colormap, exact_def_return);
  522.     } 
  523.     return 0;
  524. }
  525.  
  526. /*
  527.  *----------------------------------------------------------------------
  528.  *
  529.  * XFreeColors --
  530.  *
  531.  *    Deallocate a block of colors.
  532.  *
  533.  * Results:
  534.  *    None.
  535.  *
  536.  * Side effects:
  537.  *    Removes entries for the current palette and compacts the
  538.  *    remaining set.
  539.  *
  540.  *----------------------------------------------------------------------
  541.  */
  542.  
  543. void
  544. XFreeColors(display, colormap, pixels, npixels, planes)
  545.     Display* display;
  546.     Colormap colormap;
  547.     unsigned long* pixels;
  548.     int npixels;
  549.     unsigned long planes;
  550. {
  551.     TkOS2Colormap *cmap = (TkOS2Colormap *) colormap;
  552.     ULONG cref;
  553.     ULONG refCount;
  554.     int i, old, new;
  555.     ULONG *entries;
  556.     Tcl_HashEntry *entryPtr;
  557.  
  558.     /*
  559.      * We don't have to do anything for non-palette devices.
  560.      */
  561.     
  562.     if (aDevCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) {
  563.  
  564.     /*
  565.      * This is really slow for large values of npixels.
  566.      */
  567.     for (i = 0; i < npixels; i++) {
  568.         entryPtr = Tcl_FindHashEntry(&cmap->refCounts,
  569.             (char *) pixels[i]);
  570.         if (!entryPtr) {
  571.         panic("Tried to free a color that isn't allocated.");
  572.         }
  573.         refCount = (int) Tcl_GetHashValue(entryPtr) - 1;
  574.         if (refCount == 0) {
  575.         cref = pixels[i] & 0x00ffffff;
  576.                 entries = (ULONG *) ckalloc(sizeof(ULONG) * cmap->size);
  577.                 /* hps value ignored for specific values of palette */
  578.                 if (GpiQueryPaletteInfo(cmap->palette, NULLHANDLE, 0L, 0L,
  579.                                         cmap->size, entries) == PAL_ERROR) {
  580.                    ckfree((char *)entries);
  581.                    return;
  582.             }
  583.         /* Copy all entries except the one to delete */
  584.         for (old= new= 0; old<cmap->size; old++) {
  585.             if (entries[old] != cref) {
  586.                 entries[new] = entries[old];
  587.                 new++;
  588.             }
  589.         }
  590.         cmap->size--;
  591.             GpiSetPaletteEntries(cmap->palette, LCOLF_CONSECRGB, 0,
  592.                                  cmap->size, entries);
  593.         ckfree((char *) entries);
  594.         Tcl_DeleteHashEntry(entryPtr);
  595.         }
  596.     }
  597.     }
  598. }
  599.  
  600. /*
  601.  *----------------------------------------------------------------------
  602.  *
  603.  * XCreateColormap --
  604.  *
  605.  *    Allocate a new colormap.
  606.  *
  607.  * Results:
  608.  *    Returns a newly allocated colormap.
  609.  *
  610.  * Side effects:
  611.  *    Allocates an empty palette and color list.
  612.  *
  613.  *----------------------------------------------------------------------
  614.  */
  615.  
  616. Colormap
  617. XCreateColormap(display, w, visual, alloc)
  618.     Display* display;
  619.     Window w;
  620.     Visual* visual;
  621.     int alloc;
  622. {
  623.     TkOS2Colormap *cmap = (TkOS2Colormap *) ckalloc(sizeof(TkOS2Colormap));
  624.  
  625.     /*
  626.      * Create a palette when we have palette management. Otherwise store the
  627.      * presentation space handle of the window, since color tables are PS-
  628.      * specific.
  629.      */
  630.     if (aDevCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) {
  631.         ULONG logPalette[1];
  632.  
  633.         logPalette[0] = 0;
  634.         cmap->palette = GpiCreatePalette(hab, 0L, LCOLF_CONSECRGB, 1L,
  635.                                          logPalette);
  636.     } else {
  637.         cmap->palette = (HPAL)NULLHANDLE;
  638.     }
  639.     cmap->size = 0;
  640.     cmap->stale = 0;
  641.     Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
  642.     return (Colormap)cmap;
  643. }
  644.  
  645. /*
  646.  *----------------------------------------------------------------------
  647.  *
  648.  * XFreeColormap --
  649.  *
  650.  *    Frees the resources associated with the given colormap.
  651.  *
  652.  * Results:
  653.  *    None.
  654.  *
  655.  * Side effects:
  656.  *    Deletes the palette associated with the colormap.  Note that
  657.  *    the palette must not be selected into a device context when
  658.  *    this occurs.
  659.  *
  660.  *----------------------------------------------------------------------
  661.  */
  662.  
  663. void
  664. XFreeColormap(display, colormap)
  665.     Display* display;
  666.     Colormap colormap;
  667. {
  668.     TkOS2Colormap *cmap = (TkOS2Colormap *) colormap;
  669.  
  670.     if (aDevCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) {
  671.         /* Palette management */
  672.         if (!GpiDeletePalette(cmap->palette)) {
  673.             /* Try to free memory anyway */
  674.             ckfree((char *) cmap);
  675.         panic("Unable to free colormap, palette is still selected.");
  676.         }
  677.     }
  678.     Tcl_DeleteHashTable(&cmap->refCounts);
  679.     ckfree((char *) cmap);
  680. }
  681.  
  682. /*
  683.  *----------------------------------------------------------------------
  684.  *
  685.  * TkOS2SelectPalette --
  686.  *
  687.  *    This function sets up the specified device context with a
  688.  *    given palette.  If the palette is stale, it realizes it in
  689.  *    the background unless the palette is the current global
  690.  *    palette.
  691.  *
  692.  * Results:
  693.  *    Returns the previous palette selected into the device context.
  694.  *
  695.  * Side effects:
  696.  *    May change the system palette.
  697.  *
  698.  *----------------------------------------------------------------------
  699.  */
  700.  
  701. HPAL
  702. TkOS2SelectPalette(hps, hwnd, colormap)
  703.     HPS hps;
  704.     HWND hwnd;
  705.     Colormap colormap;
  706. {
  707.     TkOS2Colormap *cmap = (TkOS2Colormap *) colormap;
  708.     HPAL oldPalette;
  709.     ULONG mapped, changed;
  710.  
  711.     if (aDevCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER) {
  712.         oldPalette = GpiSelectPalette(hps, cmap->palette);
  713.         mapped = WinRealizePalette(hwnd, hps, &changed);
  714.         return oldPalette;
  715.     } else {
  716.         PULONG alArray;
  717.         /* Retrieve the "global" color table and create it in this PS */
  718.         alArray = (PLONG) ckalloc ((unsigned)(sizeof(LONG) * (nextColor)));
  719.         rc = GpiQueryLogColorTable(globalPS, 0L, 0L, nextColor, alArray);
  720.         if (rc > 0) {
  721.             rc = GpiCreateLogColorTable(hps, 0L, LCOLF_RGB, 0,
  722.                                         nextColor, alArray);
  723.         }
  724.         ckfree((char *)alArray);
  725.         return (HPAL)0;
  726.     }
  727. }
  728.