/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkwincolor.c
ViewVC logotype

Diff of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkwincolor.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkWinColor.c --   * tkWinColor.c --
5   *   *
6   *      Functions to map color names to system color values.   *      Functions to map color names to system color values.
7   *   *
8   * Copyright (c) 1995 Sun Microsystems, Inc.   * Copyright (c) 1995 Sun Microsystems, Inc.
9   * Copyright (c) 1994 Software Research Associates, Inc.   * Copyright (c) 1994 Software Research Associates, Inc.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * RCS: @(#) $Id: tkwincolor.c,v 1.1.1.1 2001/06/13 05:12:03 dtashley Exp $   * RCS: @(#) $Id: tkwincolor.c,v 1.1.1.1 2001/06/13 05:12:03 dtashley Exp $
15   */   */
16    
17  #include "tkWinInt.h"  #include "tkWinInt.h"
18  #include "tkColor.h"  #include "tkColor.h"
19    
20  /*  /*
21   * The following structure is used to keep track of each color that is   * The following structure is used to keep track of each color that is
22   * allocated by this module.   * allocated by this module.
23   */   */
24    
25  typedef struct WinColor {  typedef struct WinColor {
26      TkColor info;               /* Generic color information. */      TkColor info;               /* Generic color information. */
27      int index;                  /* Index for GetSysColor(), -1 if color      int index;                  /* Index for GetSysColor(), -1 if color
28                                   * is not a "live" system color. */                                   * is not a "live" system color. */
29  } WinColor;  } WinColor;
30    
31  /*  /*
32   * The sysColors array contains the names and index values for the   * The sysColors array contains the names and index values for the
33   * Windows indirect system color names.  In use, all of the names   * Windows indirect system color names.  In use, all of the names
34   * will have the string "System" prepended, but we omit it in the table   * will have the string "System" prepended, but we omit it in the table
35   * to save space.   * to save space.
36   */   */
37    
38  typedef struct {  typedef struct {
39      char *name;      char *name;
40      int index;      int index;
41  } SystemColorEntry;  } SystemColorEntry;
42    
43    
44  static SystemColorEntry sysColors[] = {  static SystemColorEntry sysColors[] = {
45      "3dDarkShadow",             COLOR_3DDKSHADOW,      "3dDarkShadow",             COLOR_3DDKSHADOW,
46      "3dLight",                  COLOR_3DLIGHT,      "3dLight",                  COLOR_3DLIGHT,
47      "ActiveBorder",             COLOR_ACTIVEBORDER,      "ActiveBorder",             COLOR_ACTIVEBORDER,
48      "ActiveCaption",            COLOR_ACTIVECAPTION,      "ActiveCaption",            COLOR_ACTIVECAPTION,
49      "AppWorkspace",             COLOR_APPWORKSPACE,      "AppWorkspace",             COLOR_APPWORKSPACE,
50      "Background",               COLOR_BACKGROUND,      "Background",               COLOR_BACKGROUND,
51      "ButtonFace",               COLOR_BTNFACE,      "ButtonFace",               COLOR_BTNFACE,
52      "ButtonHighlight",          COLOR_BTNHIGHLIGHT,      "ButtonHighlight",          COLOR_BTNHIGHLIGHT,
53      "ButtonShadow",             COLOR_BTNSHADOW,      "ButtonShadow",             COLOR_BTNSHADOW,
54      "ButtonText",               COLOR_BTNTEXT,      "ButtonText",               COLOR_BTNTEXT,
55      "CaptionText",              COLOR_CAPTIONTEXT,      "CaptionText",              COLOR_CAPTIONTEXT,
56      "DisabledText",             COLOR_GRAYTEXT,      "DisabledText",             COLOR_GRAYTEXT,
57      "GrayText",                 COLOR_GRAYTEXT,      "GrayText",                 COLOR_GRAYTEXT,
58      "Highlight",                COLOR_HIGHLIGHT,      "Highlight",                COLOR_HIGHLIGHT,
59      "HighlightText",            COLOR_HIGHLIGHTTEXT,      "HighlightText",            COLOR_HIGHLIGHTTEXT,
60      "InactiveBorder",           COLOR_INACTIVEBORDER,      "InactiveBorder",           COLOR_INACTIVEBORDER,
61      "InactiveCaption",          COLOR_INACTIVECAPTION,      "InactiveCaption",          COLOR_INACTIVECAPTION,
62      "InactiveCaptionText",      COLOR_INACTIVECAPTIONTEXT,      "InactiveCaptionText",      COLOR_INACTIVECAPTIONTEXT,
63      "InfoBackground",           COLOR_INFOBK,      "InfoBackground",           COLOR_INFOBK,
64      "InfoText",                 COLOR_INFOTEXT,      "InfoText",                 COLOR_INFOTEXT,
65      "Menu",                     COLOR_MENU,      "Menu",                     COLOR_MENU,
66      "MenuText",                 COLOR_MENUTEXT,      "MenuText",                 COLOR_MENUTEXT,
67      "Scrollbar",                COLOR_SCROLLBAR,      "Scrollbar",                COLOR_SCROLLBAR,
68      "Window",                   COLOR_WINDOW,      "Window",                   COLOR_WINDOW,
69      "WindowFrame",              COLOR_WINDOWFRAME,      "WindowFrame",              COLOR_WINDOWFRAME,
70      "WindowText",               COLOR_WINDOWTEXT,      "WindowText",               COLOR_WINDOWTEXT,
71      NULL,                       0      NULL,                       0
72  };  };
73    
74  typedef struct ThreadSpecificData {  typedef struct ThreadSpecificData {
75      int ncolors;      int ncolors;
76  } ThreadSpecificData;  } ThreadSpecificData;
77  static Tcl_ThreadDataKey dataKey;  static Tcl_ThreadDataKey dataKey;
78    
79  /*  /*
80   * Forward declarations for functions defined later in this file.   * Forward declarations for functions defined later in this file.
81   */   */
82    
83  static int      FindSystemColor _ANSI_ARGS_((const char *name,  static int      FindSystemColor _ANSI_ARGS_((const char *name,
84                      XColor *colorPtr, int *indexPtr));                      XColor *colorPtr, int *indexPtr));
85  static int      GetColorByName _ANSI_ARGS_((char *name, XColor *color));  static int      GetColorByName _ANSI_ARGS_((char *name, XColor *color));
86  static int      GetColorByValue _ANSI_ARGS_((char *value, XColor *color));  static int      GetColorByValue _ANSI_ARGS_((char *value, XColor *color));
87    
88  /*  /*
89   *----------------------------------------------------------------------   *----------------------------------------------------------------------
90   *   *
91   * FindSystemColor --   * FindSystemColor --
92   *   *
93   *      This routine finds the color entry that corresponds to the   *      This routine finds the color entry that corresponds to the
94   *      specified color.   *      specified color.
95   *   *
96   * Results:   * Results:
97   *      Returns non-zero on success.  The RGB values of the XColor   *      Returns non-zero on success.  The RGB values of the XColor
98   *      will be initialized to the proper values on success.   *      will be initialized to the proper values on success.
99   *   *
100   * Side effects:   * Side effects:
101   *      None.   *      None.
102   *   *
103   *----------------------------------------------------------------------   *----------------------------------------------------------------------
104   */   */
105    
106  static int  static int
107  FindSystemColor(name, colorPtr, indexPtr)  FindSystemColor(name, colorPtr, indexPtr)
108      const char *name;           /* Color name. */      const char *name;           /* Color name. */
109      XColor *colorPtr;           /* Where to store results. */      XColor *colorPtr;           /* Where to store results. */
110      int *indexPtr;              /* Out parameter to store color index. */      int *indexPtr;              /* Out parameter to store color index. */
111  {  {
112      int l, u, r, i;      int l, u, r, i;
113      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)      ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
114              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));              Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
115    
116      /*      /*
117       * Count the number of elements in the color array if we haven't       * Count the number of elements in the color array if we haven't
118       * done so yet.       * done so yet.
119       */       */
120    
121      if (tsdPtr->ncolors == 0) {      if (tsdPtr->ncolors == 0) {
122          SystemColorEntry *ePtr;          SystemColorEntry *ePtr;
123          int version;          int version;
124    
125          version = LOBYTE(LOWORD(GetVersion()));          version = LOBYTE(LOWORD(GetVersion()));
126          for (ePtr = sysColors; ePtr->name != NULL; ePtr++) {          for (ePtr = sysColors; ePtr->name != NULL; ePtr++) {
127              if (version < 4) {              if (version < 4) {
128                  if (ePtr->index == COLOR_3DDKSHADOW) {                  if (ePtr->index == COLOR_3DDKSHADOW) {
129                      ePtr->index = COLOR_BTNSHADOW;                      ePtr->index = COLOR_BTNSHADOW;
130                  } else if (ePtr->index == COLOR_3DLIGHT) {                  } else if (ePtr->index == COLOR_3DLIGHT) {
131                      ePtr->index = COLOR_BTNHIGHLIGHT;                      ePtr->index = COLOR_BTNHIGHLIGHT;
132                  }                  }
133              }              }
134              tsdPtr->ncolors++;              tsdPtr->ncolors++;
135          }          }
136      }      }
137    
138      /*      /*
139       * Perform a binary search on the sorted array of colors.       * Perform a binary search on the sorted array of colors.
140       */       */
141    
142      l = 0;      l = 0;
143      u = tsdPtr->ncolors - 1;      u = tsdPtr->ncolors - 1;
144      while (l <= u) {      while (l <= u) {
145          i = (l + u) / 2;          i = (l + u) / 2;
146          r = strcasecmp(name, sysColors[i].name);          r = strcasecmp(name, sysColors[i].name);
147          if (r == 0) {          if (r == 0) {
148              break;              break;
149          } else if (r < 0) {          } else if (r < 0) {
150              u = i-1;              u = i-1;
151          } else {          } else {
152              l = i+1;              l = i+1;
153          }          }
154      }      }
155      if (l > u) {      if (l > u) {
156          return 0;          return 0;
157      }      }
158    
159      *indexPtr = sysColors[i].index;      *indexPtr = sysColors[i].index;
160      colorPtr->pixel = GetSysColor(sysColors[i].index);      colorPtr->pixel = GetSysColor(sysColors[i].index);
161      /*      /*
162       * x257 is (value<<8 + value) to get the properly bit shifted       * x257 is (value<<8 + value) to get the properly bit shifted
163       * and padded value.  [Bug: 4919]       * and padded value.  [Bug: 4919]
164       */       */
165      colorPtr->red = GetRValue(colorPtr->pixel) * 257;      colorPtr->red = GetRValue(colorPtr->pixel) * 257;
166      colorPtr->green = GetGValue(colorPtr->pixel) * 257;      colorPtr->green = GetGValue(colorPtr->pixel) * 257;
167      colorPtr->blue = GetBValue(colorPtr->pixel) * 257;      colorPtr->blue = GetBValue(colorPtr->pixel) * 257;
168      colorPtr->flags = DoRed|DoGreen|DoBlue;      colorPtr->flags = DoRed|DoGreen|DoBlue;
169      colorPtr->pad = 0;      colorPtr->pad = 0;
170      return 1;      return 1;
171  }  }
172    
173  /*  /*
174   *----------------------------------------------------------------------   *----------------------------------------------------------------------
175   *   *
176   * TkpGetColor --   * TkpGetColor --
177   *   *
178   *      Allocate a new TkColor for the color with the given name.   *      Allocate a new TkColor for the color with the given name.
179   *   *
180   * Results:   * Results:
181   *      Returns a newly allocated TkColor, or NULL on failure.   *      Returns a newly allocated TkColor, or NULL on failure.
182   *   *
183   * Side effects:   * Side effects:
184   *      May invalidate the colormap cache associated with tkwin upon   *      May invalidate the colormap cache associated with tkwin upon
185   *      allocating a new colormap entry.  Allocates a new TkColor   *      allocating a new colormap entry.  Allocates a new TkColor
186   *      structure.   *      structure.
187   *   *
188   *----------------------------------------------------------------------   *----------------------------------------------------------------------
189   */   */
190    
191  TkColor *  TkColor *
192  TkpGetColor(tkwin, name)  TkpGetColor(tkwin, name)
193      Tk_Window tkwin;            /* Window in which color will be used. */      Tk_Window tkwin;            /* Window in which color will be used. */
194      Tk_Uid name;                /* Name of color to allocated (in form      Tk_Uid name;                /* Name of color to allocated (in form
195                                   * suitable for passing to XParseColor). */                                   * suitable for passing to XParseColor). */
196  {  {
197      WinColor *winColPtr;      WinColor *winColPtr;
198      XColor color;      XColor color;
199      int index = -1;             /* -1 indicates that this is not an indirect      int index = -1;             /* -1 indicates that this is not an indirect
200                                   * sytem color. */                                   * sytem color. */
201    
202      /*      /*
203       * Check to see if it is a system color or an X color string.  If the       * Check to see if it is a system color or an X color string.  If the
204       * color is found, allocate a new WinColor and store the XColor and the       * color is found, allocate a new WinColor and store the XColor and the
205       * system color index.       * system color index.
206       */       */
207    
208      if (((strncasecmp(name, "system", 6) == 0)      if (((strncasecmp(name, "system", 6) == 0)
209              && FindSystemColor(name+6, &color, &index))              && FindSystemColor(name+6, &color, &index))
210              || XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,              || XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
211                      &color)) {                      &color)) {
212          winColPtr = (WinColor *) ckalloc(sizeof(WinColor));          winColPtr = (WinColor *) ckalloc(sizeof(WinColor));
213          winColPtr->info.color = color;          winColPtr->info.color = color;
214          winColPtr->index = index;          winColPtr->index = index;
215    
216          XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin),          XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
217                  &winColPtr->info.color);                  &winColPtr->info.color);
218          return (TkColor *) winColPtr;          return (TkColor *) winColPtr;
219      }      }
220      return (TkColor *) NULL;      return (TkColor *) NULL;
221  }  }
222    
223  /*  /*
224   *----------------------------------------------------------------------   *----------------------------------------------------------------------
225   *   *
226   * TkpGetColorByValue --   * TkpGetColorByValue --
227   *   *
228   *      Given a desired set of red-green-blue intensities for a color,   *      Given a desired set of red-green-blue intensities for a color,
229   *      locate a pixel value to use to draw that color in a given   *      locate a pixel value to use to draw that color in a given
230   *      window.   *      window.
231   *   *
232   * Results:   * Results:
233   *      The return value is a pointer to an TkColor structure that   *      The return value is a pointer to an TkColor structure that
234   *      indicates the closest red, blue, and green intensities available   *      indicates the closest red, blue, and green intensities available
235   *      to those specified in colorPtr, and also specifies a pixel   *      to those specified in colorPtr, and also specifies a pixel
236   *      value to use to draw in that color.   *      value to use to draw in that color.
237   *   *
238   * Side effects:   * Side effects:
239   *      May invalidate the colormap cache for the specified window.   *      May invalidate the colormap cache for the specified window.
240   *      Allocates a new TkColor structure.   *      Allocates a new TkColor structure.
241   *   *
242   *----------------------------------------------------------------------   *----------------------------------------------------------------------
243   */   */
244    
245  TkColor *  TkColor *
246  TkpGetColorByValue(tkwin, colorPtr)  TkpGetColorByValue(tkwin, colorPtr)
247      Tk_Window tkwin;            /* Window in which color will be used. */      Tk_Window tkwin;            /* Window in which color will be used. */
248      XColor *colorPtr;           /* Red, green, and blue fields indicate      XColor *colorPtr;           /* Red, green, and blue fields indicate
249                                   * desired color. */                                   * desired color. */
250  {  {
251      WinColor *tkColPtr = (WinColor *) ckalloc(sizeof(WinColor));      WinColor *tkColPtr = (WinColor *) ckalloc(sizeof(WinColor));
252    
253      tkColPtr->info.color.red = colorPtr->red;      tkColPtr->info.color.red = colorPtr->red;
254      tkColPtr->info.color.green = colorPtr->green;      tkColPtr->info.color.green = colorPtr->green;
255      tkColPtr->info.color.blue = colorPtr->blue;      tkColPtr->info.color.blue = colorPtr->blue;
256      tkColPtr->info.color.pixel = 0;      tkColPtr->info.color.pixel = 0;
257      tkColPtr->index = -1;      tkColPtr->index = -1;
258      XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), &tkColPtr->info.color);      XAllocColor(Tk_Display(tkwin), Tk_Colormap(tkwin), &tkColPtr->info.color);
259      return (TkColor *) tkColPtr;      return (TkColor *) tkColPtr;
260  }  }
261    
262  /*  /*
263   *----------------------------------------------------------------------   *----------------------------------------------------------------------
264   *   *
265   * TkpFreeColor --   * TkpFreeColor --
266   *   *
267   *      Release the specified color back to the system.   *      Release the specified color back to the system.
268   *   *
269   * Results:   * Results:
270   *      None   *      None
271   *   *
272   * Side effects:   * Side effects:
273   *      Invalidates the colormap cache for the colormap associated with   *      Invalidates the colormap cache for the colormap associated with
274   *      the given color.   *      the given color.
275   *   *
276   *----------------------------------------------------------------------   *----------------------------------------------------------------------
277   */   */
278    
279  void  void
280  TkpFreeColor(tkColPtr)  TkpFreeColor(tkColPtr)
281      TkColor *tkColPtr;          /* Color to be released.  Must have been      TkColor *tkColPtr;          /* Color to be released.  Must have been
282                                   * allocated by TkpGetColor or                                   * allocated by TkpGetColor or
283                                   * TkpGetColorByValue. */                                   * TkpGetColorByValue. */
284  {  {
285      Screen *screen = tkColPtr->screen;      Screen *screen = tkColPtr->screen;
286    
287      XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,      XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap,
288              &tkColPtr->color.pixel, 1, 0L);              &tkColPtr->color.pixel, 1, 0L);
289  }  }
290    
291  /*  /*
292   *----------------------------------------------------------------------   *----------------------------------------------------------------------
293   *   *
294   * TkWinIndexOfColor --   * TkWinIndexOfColor --
295   *   *
296   *      Given a color, return the system color index that was used   *      Given a color, return the system color index that was used
297   *      to create the color.   *      to create the color.
298   *   *
299   * Results:   * Results:
300   *      If the color was allocated using a system indirect color name,   *      If the color was allocated using a system indirect color name,
301   *      then the corresponding GetSysColor() index is returned.   *      then the corresponding GetSysColor() index is returned.
302   *      Otherwise, -1 is returned.   *      Otherwise, -1 is returned.
303   *   *
304   * Side effects:   * Side effects:
305   *      None.   *      None.
306   *   *
307   *----------------------------------------------------------------------   *----------------------------------------------------------------------
308   */   */
309    
310  int  int
311  TkWinIndexOfColor(colorPtr)  TkWinIndexOfColor(colorPtr)
312      XColor *colorPtr;      XColor *colorPtr;
313  {  {
314      register WinColor *winColPtr = (WinColor *) colorPtr;      register WinColor *winColPtr = (WinColor *) colorPtr;
315      if (winColPtr->info.magic == COLOR_MAGIC) {      if (winColPtr->info.magic == COLOR_MAGIC) {
316          return winColPtr->index;          return winColPtr->index;
317      }          }    
318      return -1;      return -1;
319  }  }
320    
321  /*  /*
322   *----------------------------------------------------------------------   *----------------------------------------------------------------------
323   *   *
324   * XAllocColor --   * XAllocColor --
325   *   *
326   *      Find the closest available color to the specified XColor.   *      Find the closest available color to the specified XColor.
327   *   *
328   * Results:   * Results:
329   *      Updates the color argument and returns 1 on success.  Otherwise   *      Updates the color argument and returns 1 on success.  Otherwise
330   *      returns 0.   *      returns 0.
331   *   *
332   * Side effects:   * Side effects:
333   *      Allocates a new color in the palette.   *      Allocates a new color in the palette.
334   *   *
335   *----------------------------------------------------------------------   *----------------------------------------------------------------------
336   */   */
337    
338  int  int
339  XAllocColor(display, colormap, color)  XAllocColor(display, colormap, color)
340      Display* display;      Display* display;
341      Colormap colormap;      Colormap colormap;
342      XColor* color;      XColor* color;
343  {  {
344      TkWinColormap *cmap = (TkWinColormap *) colormap;      TkWinColormap *cmap = (TkWinColormap *) colormap;
345      PALETTEENTRY entry, closeEntry;      PALETTEENTRY entry, closeEntry;
346      HDC dc = GetDC(NULL);      HDC dc = GetDC(NULL);
347    
348      entry.peRed = (color->red) >> 8;      entry.peRed = (color->red) >> 8;
349      entry.peGreen = (color->green) >> 8;      entry.peGreen = (color->green) >> 8;
350      entry.peBlue = (color->blue) >> 8;      entry.peBlue = (color->blue) >> 8;
351      entry.peFlags = 0;      entry.peFlags = 0;
352    
353      if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {      if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
354          unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE);          unsigned long sizePalette = GetDeviceCaps(dc, SIZEPALETTE);
355          UINT newPixel, closePixel;          UINT newPixel, closePixel;
356          int new, refCount;          int new, refCount;
357          Tcl_HashEntry *entryPtr;          Tcl_HashEntry *entryPtr;
358          UINT index;          UINT index;
359    
360          /*          /*
361           * Find the nearest existing palette entry.           * Find the nearest existing palette entry.
362           */           */
363                    
364          newPixel = RGB(entry.peRed, entry.peGreen, entry.peBlue);          newPixel = RGB(entry.peRed, entry.peGreen, entry.peBlue);
365          index = GetNearestPaletteIndex(cmap->palette, newPixel);          index = GetNearestPaletteIndex(cmap->palette, newPixel);
366          GetPaletteEntries(cmap->palette, index, 1, &closeEntry);          GetPaletteEntries(cmap->palette, index, 1, &closeEntry);
367          closePixel = RGB(closeEntry.peRed, closeEntry.peGreen,          closePixel = RGB(closeEntry.peRed, closeEntry.peGreen,
368                  closeEntry.peBlue);                  closeEntry.peBlue);
369    
370          /*          /*
371           * If this is not a duplicate, allocate a new entry.  Note that           * If this is not a duplicate, allocate a new entry.  Note that
372           * we may get values for index that are above the current size           * we may get values for index that are above the current size
373           * of the palette.  This happens because we don't shrink the size of           * of the palette.  This happens because we don't shrink the size of
374           * the palette object when we deallocate colors so there may be           * the palette object when we deallocate colors so there may be
375           * stale values that match in the upper slots.  We should ignore           * stale values that match in the upper slots.  We should ignore
376           * those values and just put the new color in as if the colors           * those values and just put the new color in as if the colors
377           * had not matched.           * had not matched.
378           */           */
379                    
380          if ((index >= cmap->size) || (newPixel != closePixel)) {          if ((index >= cmap->size) || (newPixel != closePixel)) {
381              if (cmap->size == sizePalette) {              if (cmap->size == sizePalette) {
382                  color->red   = closeEntry.peRed * 257;                  color->red   = closeEntry.peRed * 257;
383                  color->green = closeEntry.peGreen * 257;                  color->green = closeEntry.peGreen * 257;
384                  color->blue  = closeEntry.peBlue * 257;                  color->blue  = closeEntry.peBlue * 257;
385                  entry = closeEntry;                  entry = closeEntry;
386                  if (index >= cmap->size) {                  if (index >= cmap->size) {
387                      OutputDebugString("XAllocColor: Colormap is bigger than we thought");                      OutputDebugString("XAllocColor: Colormap is bigger than we thought");
388                  }                  }
389              } else {              } else {
390                  cmap->size++;                  cmap->size++;
391                  ResizePalette(cmap->palette, cmap->size);                  ResizePalette(cmap->palette, cmap->size);
392                  SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);                  SetPaletteEntries(cmap->palette, cmap->size - 1, 1, &entry);
393              }              }
394          }          }
395    
396          color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);          color->pixel = PALETTERGB(entry.peRed, entry.peGreen, entry.peBlue);
397          entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,          entryPtr = Tcl_CreateHashEntry(&cmap->refCounts,
398                  (char *) color->pixel, &new);                  (char *) color->pixel, &new);
399          if (new) {          if (new) {
400              refCount = 1;              refCount = 1;
401          } else {          } else {
402              refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1;              refCount = ((int) Tcl_GetHashValue(entryPtr)) + 1;
403          }          }
404          Tcl_SetHashValue(entryPtr, (ClientData)refCount);          Tcl_SetHashValue(entryPtr, (ClientData)refCount);
405      } else {      } else {
406                    
407          /*          /*
408           * Determine what color will actually be used on non-colormap systems.           * Determine what color will actually be used on non-colormap systems.
409           */           */
410                    
411          color->pixel = GetNearestColor(dc,          color->pixel = GetNearestColor(dc,
412                  RGB(entry.peRed, entry.peGreen, entry.peBlue));                  RGB(entry.peRed, entry.peGreen, entry.peBlue));
413          color->red    = GetRValue(color->pixel) * 257;          color->red    = GetRValue(color->pixel) * 257;
414          color->green  = GetGValue(color->pixel) * 257;          color->green  = GetGValue(color->pixel) * 257;
415          color->blue   = GetBValue(color->pixel) * 257;          color->blue   = GetBValue(color->pixel) * 257;
416      }      }
417    
418      ReleaseDC(NULL, dc);      ReleaseDC(NULL, dc);
419      return 1;      return 1;
420  }  }
421    
422  /*  /*
423   *----------------------------------------------------------------------   *----------------------------------------------------------------------
424   *   *
425   * XFreeColors --   * XFreeColors --
426   *   *
427   *      Deallocate a block of colors.   *      Deallocate a block of colors.
428   *   *
429   * Results:   * Results:
430   *      None.   *      None.
431   *   *
432   * Side effects:   * Side effects:
433   *      Removes entries for the current palette and compacts the   *      Removes entries for the current palette and compacts the
434   *      remaining set.   *      remaining set.
435   *   *
436   *----------------------------------------------------------------------   *----------------------------------------------------------------------
437   */   */
438    
439  void  void
440  XFreeColors(display, colormap, pixels, npixels, planes)  XFreeColors(display, colormap, pixels, npixels, planes)
441      Display* display;      Display* display;
442      Colormap colormap;      Colormap colormap;
443      unsigned long* pixels;      unsigned long* pixels;
444      int npixels;      int npixels;
445      unsigned long planes;      unsigned long planes;
446  {  {
447      TkWinColormap *cmap = (TkWinColormap *) colormap;      TkWinColormap *cmap = (TkWinColormap *) colormap;
448      COLORREF cref;      COLORREF cref;
449      UINT count, index, refCount;      UINT count, index, refCount;
450      int i;      int i;
451      PALETTEENTRY entry, *entries;      PALETTEENTRY entry, *entries;
452      Tcl_HashEntry *entryPtr;      Tcl_HashEntry *entryPtr;
453      HDC dc = GetDC(NULL);      HDC dc = GetDC(NULL);
454    
455      /*      /*
456       * We don't have to do anything for non-palette devices.       * We don't have to do anything for non-palette devices.
457       */       */
458            
459      if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {      if (GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE) {
460    
461          /*          /*
462           * This is really slow for large values of npixels.           * This is really slow for large values of npixels.
463           */           */
464    
465          for (i = 0; i < npixels; i++) {          for (i = 0; i < npixels; i++) {
466              entryPtr = Tcl_FindHashEntry(&cmap->refCounts,              entryPtr = Tcl_FindHashEntry(&cmap->refCounts,
467                      (char *) pixels[i]);                      (char *) pixels[i]);
468              if (!entryPtr) {              if (!entryPtr) {
469                  panic("Tried to free a color that isn't allocated.");                  panic("Tried to free a color that isn't allocated.");
470              }              }
471              refCount = (int) Tcl_GetHashValue(entryPtr) - 1;              refCount = (int) Tcl_GetHashValue(entryPtr) - 1;
472              if (refCount == 0) {              if (refCount == 0) {
473                  cref = pixels[i] & 0x00ffffff;                  cref = pixels[i] & 0x00ffffff;
474                  index = GetNearestPaletteIndex(cmap->palette, cref);                  index = GetNearestPaletteIndex(cmap->palette, cref);
475                  GetPaletteEntries(cmap->palette, index, 1, &entry);                  GetPaletteEntries(cmap->palette, index, 1, &entry);
476                  if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) {                  if (cref == RGB(entry.peRed, entry.peGreen, entry.peBlue)) {
477                      count = cmap->size - index;                      count = cmap->size - index;
478                      entries = (PALETTEENTRY *) ckalloc(sizeof(PALETTEENTRY)                      entries = (PALETTEENTRY *) ckalloc(sizeof(PALETTEENTRY)
479                              * count);                              * count);
480                      GetPaletteEntries(cmap->palette, index+1, count, entries);                      GetPaletteEntries(cmap->palette, index+1, count, entries);
481                      SetPaletteEntries(cmap->palette, index, count, entries);                      SetPaletteEntries(cmap->palette, index, count, entries);
482                      ckfree((char *) entries);                      ckfree((char *) entries);
483                      cmap->size--;                      cmap->size--;
484                  } else {                  } else {
485                      panic("Tried to free a color that isn't allocated.");                      panic("Tried to free a color that isn't allocated.");
486                  }                  }
487                  Tcl_DeleteHashEntry(entryPtr);                  Tcl_DeleteHashEntry(entryPtr);
488              } else {              } else {
489                  Tcl_SetHashValue(entryPtr, (ClientData)refCount);                  Tcl_SetHashValue(entryPtr, (ClientData)refCount);
490              }              }
491          }          }
492      }      }
493      ReleaseDC(NULL, dc);      ReleaseDC(NULL, dc);
494  }  }
495    
496  /*  /*
497   *----------------------------------------------------------------------   *----------------------------------------------------------------------
498   *   *
499   * XCreateColormap --   * XCreateColormap --
500   *   *
501   *      Allocate a new colormap.   *      Allocate a new colormap.
502   *   *
503   * Results:   * Results:
504   *      Returns a newly allocated colormap.   *      Returns a newly allocated colormap.
505   *   *
506   * Side effects:   * Side effects:
507   *      Allocates an empty palette and color list.   *      Allocates an empty palette and color list.
508   *   *
509   *----------------------------------------------------------------------   *----------------------------------------------------------------------
510   */   */
511    
512  Colormap  Colormap
513  XCreateColormap(display, w, visual, alloc)  XCreateColormap(display, w, visual, alloc)
514      Display* display;      Display* display;
515      Window w;      Window w;
516      Visual* visual;      Visual* visual;
517      int alloc;      int alloc;
518  {  {
519      char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];      char logPalBuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
520      LOGPALETTE *logPalettePtr;      LOGPALETTE *logPalettePtr;
521      PALETTEENTRY *entryPtr;      PALETTEENTRY *entryPtr;
522      TkWinColormap *cmap;      TkWinColormap *cmap;
523      Tcl_HashEntry *hashPtr;      Tcl_HashEntry *hashPtr;
524      int new;      int new;
525      UINT i;      UINT i;
526      HPALETTE sysPal;      HPALETTE sysPal;
527    
528      /*      /*
529       * Allocate a starting palette with all of the reserved colors.       * Allocate a starting palette with all of the reserved colors.
530       */       */
531    
532      logPalettePtr = (LOGPALETTE *) logPalBuf;      logPalettePtr = (LOGPALETTE *) logPalBuf;
533      logPalettePtr->palVersion = 0x300;      logPalettePtr->palVersion = 0x300;
534      sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);      sysPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
535      logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256,      logPalettePtr->palNumEntries = GetPaletteEntries(sysPal, 0, 256,
536              logPalettePtr->palPalEntry);              logPalettePtr->palPalEntry);
537    
538      cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap));      cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap));
539      cmap->size = logPalettePtr->palNumEntries;      cmap->size = logPalettePtr->palNumEntries;
540      cmap->stale = 0;      cmap->stale = 0;
541      cmap->palette = CreatePalette(logPalettePtr);      cmap->palette = CreatePalette(logPalettePtr);
542    
543      /*      /*
544       * Add hash entries for each of the static colors.       * Add hash entries for each of the static colors.
545       */       */
546    
547      Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);      Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS);
548      for (i = 0; i < logPalettePtr->palNumEntries; i++) {      for (i = 0; i < logPalettePtr->palNumEntries; i++) {
549          entryPtr = logPalettePtr->palPalEntry + i;          entryPtr = logPalettePtr->palPalEntry + i;
550          hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char*) PALETTERGB(          hashPtr = Tcl_CreateHashEntry(&cmap->refCounts, (char*) PALETTERGB(
551              entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue), &new);              entryPtr->peRed, entryPtr->peGreen, entryPtr->peBlue), &new);
552          Tcl_SetHashValue(hashPtr, (ClientData)1);          Tcl_SetHashValue(hashPtr, (ClientData)1);
553      }      }
554    
555      return (Colormap)cmap;      return (Colormap)cmap;
556  }  }
557    
558  /*  /*
559   *----------------------------------------------------------------------   *----------------------------------------------------------------------
560   *   *
561   * XFreeColormap --   * XFreeColormap --
562   *   *
563   *      Frees the resources associated with the given colormap.   *      Frees the resources associated with the given colormap.
564   *   *
565   * Results:   * Results:
566   *      None.   *      None.
567   *   *
568   * Side effects:   * Side effects:
569   *      Deletes the palette associated with the colormap.  Note that   *      Deletes the palette associated with the colormap.  Note that
570   *      the palette must not be selected into a device context when   *      the palette must not be selected into a device context when
571   *      this occurs.   *      this occurs.
572   *   *
573   *----------------------------------------------------------------------   *----------------------------------------------------------------------
574   */   */
575    
576  void  void
577  XFreeColormap(display, colormap)  XFreeColormap(display, colormap)
578      Display* display;      Display* display;
579      Colormap colormap;      Colormap colormap;
580  {  {
581      TkWinColormap *cmap = (TkWinColormap *) colormap;      TkWinColormap *cmap = (TkWinColormap *) colormap;
582      if (!DeleteObject(cmap->palette)) {      if (!DeleteObject(cmap->palette)) {
583          panic("Unable to free colormap, palette is still selected.");          panic("Unable to free colormap, palette is still selected.");
584      }      }
585      Tcl_DeleteHashTable(&cmap->refCounts);      Tcl_DeleteHashTable(&cmap->refCounts);
586      ckfree((char *) cmap);      ckfree((char *) cmap);
587  }  }
588    
589  /*  /*
590   *----------------------------------------------------------------------   *----------------------------------------------------------------------
591   *   *
592   * TkWinSelectPalette --   * TkWinSelectPalette --
593   *   *
594   *      This function sets up the specified device context with a   *      This function sets up the specified device context with a
595   *      given palette.  If the palette is stale, it realizes it in   *      given palette.  If the palette is stale, it realizes it in
596   *      the background unless the palette is the current global   *      the background unless the palette is the current global
597   *      palette.   *      palette.
598   *   *
599   * Results:   * Results:
600   *      Returns the previous palette selected into the device context.   *      Returns the previous palette selected into the device context.
601   *   *
602   * Side effects:   * Side effects:
603   *      May change the system palette.   *      May change the system palette.
604   *   *
605   *----------------------------------------------------------------------   *----------------------------------------------------------------------
606   */   */
607    
608  HPALETTE  HPALETTE
609  TkWinSelectPalette(dc, colormap)  TkWinSelectPalette(dc, colormap)
610      HDC dc;      HDC dc;
611      Colormap colormap;      Colormap colormap;
612  {  {
613      TkWinColormap *cmap = (TkWinColormap *) colormap;      TkWinColormap *cmap = (TkWinColormap *) colormap;
614      HPALETTE oldPalette;      HPALETTE oldPalette;
615    
616      oldPalette = SelectPalette(dc, cmap->palette,      oldPalette = SelectPalette(dc, cmap->palette,
617              (cmap->palette == TkWinGetSystemPalette()) ? FALSE : TRUE);              (cmap->palette == TkWinGetSystemPalette()) ? FALSE : TRUE);
618      RealizePalette(dc);      RealizePalette(dc);
619      return oldPalette;      return oldPalette;
620  }  }
621    
622  /* End of tkwincolor.c */  /* End of tkwincolor.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25