1 /*
2  * TkMacOSXColor.c --
3  *
4  *	This file maintains a database of color values for the Tk
5  *	toolkit, in order to avoid round-trips to the server to
6  *	map color names to pixel values.
7  *
8  * Copyright © 1990-1994 The Regents of the University of California.
9  * Copyright © 1994-1996 Sun Microsystems, Inc.
10  * Copyright © 2001-2009 Apple Inc.
11  * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
12  * Copyright © 2020 Marc Culler
13  *
14  * See the file "license.terms" for information on usage and redistribution
15  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16  */
17 
18 #include "tkMacOSXPrivate.h"
19 #include "tkColor.h"
20 #include "tkMacOSXColor.h"
21 
22 static Tcl_HashTable systemColors;
23 static int numSystemColors;
24 static int rgbColorIndex;
25 static int controlAccentIndex;
26 static int selectedTabTextIndex;
27 static Bool useFakeAccentColor = NO;
28 static SystemColorDatum **systemColorIndex;
29 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
30 static NSAppearance *lightAqua = nil;
31 static NSAppearance *darkAqua = nil;
32 #endif
33 static NSColorSpace* sRGB = NULL;
34 static const CGFloat WINDOWBACKGROUND[4] =
35     {236.0 / 255, 236.0 / 255, 236.0 / 255, 1.0};
36 
initColorTable()37 void initColorTable()
38 {
39     NSAutoreleasePool *pool = [NSAutoreleasePool new];
40     Tcl_InitHashTable(&systemColors, TCL_STRING_KEYS);
41     SystemColorDatum *entry, *oldEntry;
42     Tcl_HashSearch search;
43     Tcl_HashEntry *hPtr;
44     int newPtr, index = 0;
45     NSColorList *systemColorList = [NSColorList colorListNamed:@"System"];
46     NSString *key;
47 
48 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
49     if (@available(macOS 10.14, *)) {
50 	darkAqua = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
51         lightAqua = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
52     }
53 #endif
54 
55     /*
56      * Build a hash table for looking up a color by its name.
57      * First add all of the static entries from tkMacOSXColor.h
58      */
59 
60     for (entry = systemColorData; entry->name != NULL; entry++) {
61 	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
62 	if (entry->type == semantic) {
63 	    NSString *colorName = [[NSString alloc]
64 				   initWithCString:entry->macName
65 					  encoding:NSUTF8StringEncoding];
66 	    SEL colorSelector = NSSelectorFromString(colorName);
67 	    if (![NSColor respondsToSelector:colorSelector]) {
68 		if ([colorName isEqualToString:@"controlAccentColor"]) {
69 		    useFakeAccentColor = YES;
70 		} else if (![colorName isEqualToString:@"selectedTabTextColor"]) {
71 		    /* Uncomment to print all unsupported colors:              */
72 		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
73 		    continue;
74 		}
75 	    }
76 	    entry->selector = [colorName retain];
77 	}
78 	if (newPtr == 0) {
79 	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
80 	    entry->index = oldEntry->index;
81 	    [oldEntry->selector release];
82 	} else {
83 	    entry->index = index++;
84 	}
85 	Tcl_SetHashValue(hPtr, entry);
86     }
87 
88     /*
89      * Add all of the colors in the System ColorList.
90      */
91 
92     for (key in [systemColorList allKeys]) {
93 	int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
94 	char *name;
95 	entry = (SystemColorDatum *)ckalloc(sizeof(SystemColorDatum));
96 	bzero(entry, sizeof(SystemColorDatum));
97 	name = (char *)ckalloc(length + 1);
98 	strcpy(name, key.UTF8String);
99 	name[0] = toupper(name[0]);
100         if (!strcmp(name, "WindowBackgroundColor")) {
101 
102 	    /*
103 	     * Avoid black windows on old systems.
104 	     */
105 
106 	    continue;
107 	}
108 	entry->type=semantic;
109 	entry->name = name;
110 	entry->selector = [key retain];
111 	hPtr = Tcl_CreateHashEntry(&systemColors, entry->name, &newPtr);
112 	if (newPtr == 0) {
113 	    oldEntry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
114 	    entry->index = oldEntry->index;
115 	    [oldEntry->selector release];
116 	} else {
117 	    entry->index = index++;
118 	}
119 	Tcl_SetHashValue(hPtr, entry);
120     }
121 
122     /*
123      * Build an array for looking up a color by its index.
124      */
125 
126     numSystemColors = index;
127     systemColorIndex = (SystemColorDatum **)ckalloc(numSystemColors * sizeof(SystemColorDatum *));
128     for (hPtr = Tcl_FirstHashEntry(&systemColors, &search); hPtr != NULL;
129 	 hPtr = Tcl_NextHashEntry(&search)) {
130 	entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
131 	if (entry == NULL) {
132 	    Tcl_Panic("Unsupported semantic color with no supported backup!");
133 	}
134 	systemColorIndex[entry->index] = entry;
135     }
136 
137     /*
138      * Remember the indexes of some special entries.
139      */
140 
141     hPtr = Tcl_FindHashEntry(&systemColors, "Pixel");
142     entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
143     rgbColorIndex = entry->index;
144     hPtr = Tcl_FindHashEntry(&systemColors, "ControlAccentColor");
145     entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
146     controlAccentIndex = entry->index;
147     hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
148     entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
149     selectedTabTextIndex = entry->index;
150     [pool drain];
151 }
152 
153 /*
154  *----------------------------------------------------------------------
155  *
156  * TkMacOSXRGBPixel --
157  *
158  *	Return an unsigned long value suitable for use in the pixel
159  *	field of an XColor with the specified red, green and blue
160  *	intensities.  The inputs are cast as unsigned longs but are
161  *      expected to have values representable by an unsigned char.
162  *
163  *      This is called in the TkpGetPixel macro, used in xcolor.c,
164  *      and in ImageGetPixel.
165  *
166  * Results:
167  *	An unsigned long that can be used as the pixel field of an XColor.
168  *
169  * Side effects:
170  *	None.
171  *----------------------------------------------------------------------
172  */
173 MODULE_SCOPE
174 unsigned long
TkMacOSXRGBPixel(unsigned long red,unsigned long green,unsigned long blue)175 TkMacOSXRGBPixel(
176     unsigned long red,
177     unsigned long green,
178     unsigned long blue)
179 {
180     MacPixel p = {0};
181     p.pixel.colortype = rgbColor;
182     p.pixel.value = ((red & 0xff) << 16)  |
183 	            ((green & 0xff) << 8) |
184 	            (blue & 0xff);
185     return p.ulong;
186 }
187 
188 /*
189  *----------------------------------------------------------------------
190  *
191  * TkMacOSXClearPixel --
192  *
193  *	Return the unsigned long value that appears in the pixel
194  *	field of the XColor for systemTransparentColor.
195  *
196  *      This is used in tkMacOSXImage.c.
197  *
198  * Results:
199  *	The unsigned long that appears in the pixel field of the XColor
200  *      for systemTransparentPixel.
201  *
202  * Side effects:
203  *	None.
204  *----------------------------------------------------------------------
205  */
206 MODULE_SCOPE
TkMacOSXClearPixel(void)207 unsigned long TkMacOSXClearPixel(
208     void)
209 {
210     MacPixel p = {0};
211     p.pixel.value = 0;
212     p.pixel.colortype = clearColor;
213     return p.ulong;
214 }
215 
216 
217 /*
218  *----------------------------------------------------------------------
219  *
220  * GetEntryFromPixel --
221  *
222  *	Look up a SystemColorDatum which describes the XColor with
223  *      the specified value as its pixel field.
224  *
225  * Results:
226  *	A pointer to a SystemColorDatum, or NULL if the pixel value is
227  *	invalid.
228  *
229  * Side effects:
230  *	None
231  *
232  *----------------------------------------------------------------------
233  */
234 
235 SystemColorDatum*
GetEntryFromPixel(unsigned long pixel)236 GetEntryFromPixel(
237     unsigned long pixel)
238 {
239     MacPixel p = {0};
240     int index = rgbColorIndex;
241 
242     p.ulong = pixel;
243     if (p.pixel.colortype != rgbColor) {
244 	index = p.pixel.value;
245     }
246     if (index < numSystemColors) {
247 	return systemColorIndex[index];
248     } else {
249 	return NULL;
250     }
251 }
252 
253 
254 /*
255  *----------------------------------------------------------------------
256  *
257  * GetRGBA --
258  *
259  *	Given a SystemColorDatum and a pointer to an array of 4 CGFloats, store
260  *      the associated RGBA color values in the array.  In the case of the
261  *      RGBColor datum, the unsigned long pixel value containing the RGB values
262  *      must also be provided as the pixel parameter.  Otherwise the pixel
263  *      parameter is ignored.
264  *
265  * Results:
266  *	None
267  *
268  * Side effects:
269  *	The array rgba is filled in.
270  *
271  *----------------------------------------------------------------------
272  */
273 
274 static void
GetRGBA(SystemColorDatum * entry,unsigned long pixel,CGFloat * rgba)275 GetRGBA(
276     SystemColorDatum *entry,
277     unsigned long pixel,
278     CGFloat *rgba)
279 {
280     NSColor *bgColor, *color = nil;
281 
282     if (!sRGB) {
283 	sRGB = [NSColorSpace sRGBColorSpace];
284     }
285 
286     switch (entry->type) {
287     case rgbColor:
288 	rgba[0] = ((pixel >> 16) & 0xff) / 255.0;
289 	rgba[1] = ((pixel >>  8) & 0xff) / 255.0;
290 	rgba[2] = ((pixel      ) & 0xff) / 255.0;
291 	break;
292     case ttkBackground:
293 
294 	/*
295 	 * Prior to OSX 10.14, getComponents returns black when applied to
296 	 * windowBackGroundColor.
297 	 */
298 
299 	if ([NSApp macOSVersion] < 101400) {
300 	    for (int i = 0; i < 3; i++) {
301 		rgba[i] = WINDOWBACKGROUND[i];
302 	    }
303 	} else {
304 	    bgColor = [[NSColor windowBackgroundColor] colorUsingColorSpace:sRGB];
305 	    [bgColor getComponents: rgba];
306 	}
307 	if (rgba[0] + rgba[1] + rgba[2] < 1.5) {
308 	    for (int i=0; i<3; i++) {
309 		rgba[i] += entry->value*8.0 / 255.0;
310 	    }
311 	} else {
312 	    for (int i=0; i<3; i++) {
313 		rgba[i] -= entry->value*8.0 / 255.0;
314 	    }
315 	}
316 	break;
317     case clearColor:
318 	rgba[0] = rgba[1] = rgba[2] = 1.0;
319 	rgba[3] = 0;
320 	break;
321     case semantic:
322 	if (entry->index == controlAccentIndex && useFakeAccentColor) {
323 #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
324 	    color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
325 			      colorUsingColorSpace:sRGB];
326 #endif
327 	} else if (entry->index == selectedTabTextIndex) {
328 	    int OSVersion = [NSApp macOSVersion];
329 	    if (OSVersion > 100600 && OSVersion < 101600) {
330 		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
331 	    } else {
332 		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
333 	    }
334 	} else {
335 	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
336 	}
337 	[color getComponents: rgba];
338 	break;
339     default:
340 	break;
341     }
342 }
343 
344 /*
345  *----------------------------------------------------------------------
346  *
347  * SetCGColorComponents --
348  *
349  *	Set the components of a CGColorRef from an XColor pixel value and a
350  *      SystemColorDatum.  The pixel value is only used in the case where
351  *      the color is of type rgbColor.  In that case the normalized XColor RGB
352  *      values are copied into the CGColorRef.  Otherwise the components are
353  *      computed from the SystemColorDatum.
354  *
355  * Results:
356  *	True if the function succeeds, false otherwise.
357  *
358  * Side effects:
359  *	None.
360  *
361  *----------------------------------------------------------------------
362  */
363 
364 static Bool
SetCGColorComponents(SystemColorDatum * entry,unsigned long pixel,CGColorRef * c)365 SetCGColorComponents(
366     SystemColorDatum *entry,
367     unsigned long pixel,
368     CGColorRef *c)
369 {
370     CGFloat rgba[4] = {0, 0, 0, 1};
371 
372     /*
373      * This function is called before our autorelease pool is set up,
374      * so it needs its own pool.
375      */
376 
377     NSAutoreleasePool *pool = [NSAutoreleasePool new];
378 
379     if (entry->type == HIBrush) {
380      	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);
381      	return err == noErr;
382     }
383     GetRGBA(entry, pixel, rgba);
384     *c = CGColorCreate(sRGB.CGColorSpace, rgba);
385     [pool drain];
386     return true;
387 }
388 
389 /*
390  *----------------------------------------------------------------------
391  *
392  * TkMacOSXInDarkMode --
393  *
394  *      Tests whether the given window's NSView has a DarkAqua Appearance.
395  *
396  * Results:
397  *      Returns true if the NSView is in DarkMode, false if not.
398  *
399  * Side effects:
400  *      None.
401  *
402  *----------------------------------------------------------------------
403  */
404 
405 MODULE_SCOPE Bool
TkMacOSXInDarkMode(Tk_Window tkwin)406 TkMacOSXInDarkMode(Tk_Window tkwin)
407 {
408 
409 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
410     if (@available(macOS 10.14, *)) {
411         TkWindow *winPtr = (TkWindow*) tkwin;
412 	NSAppearanceName name;
413 	NSView *view = nil;
414 	if (winPtr && winPtr->privatePtr) {
415 	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
416 	}
417 	if (view) {
418 	    name = [[view effectiveAppearance] name];
419 	} else {
420 	    name = [[NSAppearance currentAppearance] name];
421 	}
422 	return (name == NSAppearanceNameDarkAqua);
423     }
424 #else
425     (void) tkwin;
426 #endif
427     return false;
428 }
429 
430 /*
431  *----------------------------------------------------------------------
432  *
433  * TkSetMacColor --
434  *
435  *	Sets the components of a CGColorRef from an XColor pixel value.  The
436  *      pixel value is used to look up the color in the system color table, and
437  *      then SetCGColorComponents is called with the table entry and the pixel
438  *      value.  The parameter macColor should be a pointer to a CGColorRef.
439  *
440  * Results:
441  *      Returns false if the color is not found, true otherwise.
442  *
443  * Side effects:
444  *	The CGColorRef referenced by the variable macColor may be modified.
445  *
446  *----------------------------------------------------------------------
447  */
448 
449 int
TkSetMacColor(unsigned long pixel,void * macColor)450 TkSetMacColor(
451     unsigned long pixel,	/* Pixel value to convert. */
452     void *macColor)		/* CGColorRef to modify. */
453 {
454     CGColorRef *color = (CGColorRef*)macColor;
455     SystemColorDatum *entry = GetEntryFromPixel(pixel);
456 
457     if (entry) {
458 	return SetCGColorComponents(entry, pixel, color);
459     } else {
460 	return false;
461     }
462 }
463 
464 /*
465  *----------------------------------------------------------------------
466  *
467  * TkMacOSXGetNSColor --
468  *
469  *	Creates an autoreleased NSColor from a X style pixel value.
470  *      The return value is nil if the pixel value is invalid.
471  *
472  * Results:
473  *	A possibly nil pointer to an NSColor.
474  *
475  * Side effects:
476  *	None
477  *
478  *----------------------------------------------------------------------
479  */
480 
481 NSColor*
TkMacOSXGetNSColor(TCL_UNUSED (GC),unsigned long pixel)482 TkMacOSXGetNSColor(
483     TCL_UNUSED(GC),
484     unsigned long pixel)		/* Pixel value to convert. */
485 {
486     CGColorRef cgColor;
487     NSColor *nsColor = nil;
488 
489     TkSetMacColor(pixel, &cgColor);
490     nsColor = [NSColor colorWithColorSpace:sRGB
491 		   components:CGColorGetComponents(cgColor)
492 		   count:CGColorGetNumberOfComponents(cgColor)];
493     return nsColor;
494 }
495 
496 /*
497  *----------------------------------------------------------------------
498  *
499  * TkMacOSXSetColorInContext --
500  *
501  *	Sets the fill and stroke colors in the given CGContext to the CGColor
502  *	which corresponds to the XColor having the specified value for its pixel
503  *	field.
504  *
505  * Results:
506  *	None.
507  *
508  * Side effects:
509  *	None.
510  *
511  *----------------------------------------------------------------------
512  */
513 
514 void
TkMacOSXSetColorInContext(TCL_UNUSED (GC),unsigned long pixel,CGContextRef context)515 TkMacOSXSetColorInContext(
516     TCL_UNUSED(GC),
517     unsigned long pixel,
518     CGContextRef context)
519 {
520     OSStatus err = noErr;
521     CGColorRef cgColor = nil;
522     SystemColorDatum *entry = GetEntryFromPixel(pixel);
523 
524     if (entry) {
525 	switch (entry->type) {
526 	case HIBrush:
527 	    err = ChkErr(HIThemeSetFill, entry->value, NULL, context,
528 		    kHIThemeOrientationNormal);
529 	    if (err == noErr) {
530 		err = ChkErr(HIThemeSetStroke, entry->value, NULL, context,
531 			kHIThemeOrientationNormal);
532 	    }
533 	    break;
534 	default:
535 	    SetCGColorComponents(entry, pixel, &cgColor);
536 	    break;
537 	}
538     }
539     if (cgColor) {
540 	CGContextSetFillColorWithColor(context, cgColor);
541 	CGContextSetStrokeColorWithColor(context, cgColor);
542 	CGColorRelease(cgColor);
543     }
544     if (err != noErr) {
545 	TkMacOSXDbgMsg("Ignored unknown pixel value 0x%lx", pixel);
546     }
547 }
548 
549 /*
550  *----------------------------------------------------------------------
551  *
552  * TkpGetColor --
553  *
554  *	Create a new TkColor for the color with the given name, for use in the
555  *      specified window. The colormap field is set to lightColormap if the
556  *      window has a LightAqua appearance, or darkColormap if the window has a
557  *      DarkAqua appearance.  TkColors with different colormaps are managed
558  *      separately in the per-display table of TkColors maintained by Tk.
559  *
560  *      This function is called by Tk_GetColor.
561  *
562  * Results:
563  *	Returns a newly allocated TkColor, or NULL on failure.
564  *
565  * Side effects:
566  *
567  *	Allocates memory for the TkColor structure.
568  *
569  *----------------------------------------------------------------------
570  */
571 
572 TkColor *
TkpGetColor(Tk_Window tkwin,Tk_Uid name)573 TkpGetColor(
574     Tk_Window tkwin,		/* Window in which color will be used. */
575     Tk_Uid name)		/* Name of color to be allocated (in form
576 				 * suitable for passing to XParseColor). */
577 {
578     Display *display = NULL;
579     TkColor *tkColPtr;
580     XColor color;
581     Colormap colormap = tkwin ? Tk_Colormap(tkwin) : noColormap;
582     NSView *view = nil;
583     static Bool initialized = NO;
584     static NSColorSpace* sRGB = nil;
585 
586     if (!initialized) {
587 	initialized = YES;
588 	sRGB = [NSColorSpace sRGBColorSpace];
589 	initColorTable();
590     }
591     if (tkwin) {
592 	display = Tk_Display(tkwin);
593 	Drawable d = Tk_WindowId(tkwin);
594 	view = TkMacOSXGetNSViewForDrawable(d);
595     }
596 
597     /*
598      * Check to see if this is a system color. If not, just call XParseColor.
599      */
600 
601     if (strncasecmp(name, "system", 6) == 0) {
602 	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&systemColors, name + 6);
603 	MacPixel p = {0};
604 
605 	if (hPtr != NULL) {
606 	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);
607 	    CGColorRef c;
608 
609 	    p.pixel.colortype = entry->type;
610 	    p.pixel.value = entry->index;
611 	    color.pixel = p.ulong;
612 	    if (entry->type == semantic) {
613 		CGFloat rgba[4];
614 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
615 		if (@available(macOS 10.14, *)) {
616 		    NSAppearance *savedAppearance = [NSAppearance currentAppearance];
617 		    NSAppearance *windowAppearance = savedAppearance;
618 		    if (view) {
619 			windowAppearance = [view effectiveAppearance];
620 		    }
621 		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
622 			colormap = darkColormap;
623 		    } else {
624 			colormap = lightColormap;
625 		    }
626 		    [NSAppearance setCurrentAppearance:windowAppearance];
627 		    GetRGBA(entry, p.ulong, rgba);
628 		    [NSAppearance setCurrentAppearance:savedAppearance];
629 		} else {
630 		    GetRGBA(entry, p.ulong, rgba);
631 		}
632 #else
633 		GetRGBA(entry, p.ulong, rgba);
634 #endif
635 		color.red   = rgba[0] * 65535.0;
636 		color.green = rgba[1] * 65535.0;
637 		color.blue  = rgba[2] * 65535.0;
638 		goto validXColor;
639 	    } else if (SetCGColorComponents(entry, 0, &c)) {
640 		const size_t n = CGColorGetNumberOfComponents(c);
641 		const CGFloat *rgba = CGColorGetComponents(c);
642 
643 		switch (n) {
644 		case 4:
645 		    color.red   = rgba[0] * 65535.0;
646 		    color.green = rgba[1] * 65535.0;
647 		    color.blue  = rgba[2] * 65535.0;
648 		    break;
649 		case 2:
650 		    color.red = color.green = color.blue = rgba[0] * 65535.0;
651 		    break;
652 		default:
653 		    Tcl_Panic("CGColor with %d components", (int) n);
654 		}
655 		CGColorRelease(c);
656 		goto validXColor;
657 	    }
658 	}
659     }
660     if (TkParseColor(display, colormap, name, &color) == 0) {
661 	return NULL;
662     }
663 
664 validXColor:
665     tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
666     tkColPtr->colormap = colormap;
667     tkColPtr->color = color;
668     return tkColPtr;
669 }
670 
671 /*
672  *----------------------------------------------------------------------
673  *
674  * TkpGetColorByValue --
675  *
676  *	Given an pointer to an XColor, construct a TkColor whose red, green and
677  *	blue intensities match those of the XColor as closely as possible.  For
678  *	the Macintosh, this means that the colortype bitfield of the pixel
679  *	value will be RGBColor and that the color intensities stored in its
680  *	24-bit value bitfield are computed from the 16-bit red green and blue
681  *	values in the XColor by dividing by 256.
682  *
683  * Results:
684  *	A pointer to a newly allocated TkColor structure.
685  *
686  * Side effects:
687  *	May invalidate the colormap cache for the specified window.
688  *	Allocates memory for a TkColor structure.
689  *
690  *----------------------------------------------------------------------
691  */
692 
693 TkColor *
TkpGetColorByValue(TCL_UNUSED (Tk_Window),XColor * colorPtr)694 TkpGetColorByValue(
695     TCL_UNUSED(Tk_Window),		/* Window in which color will be used. */
696     XColor *colorPtr)		/* Red, green, and blue fields indicate
697 				 * desired color. */
698 {
699     TkColor *tkColPtr = (TkColor *)ckalloc(sizeof(TkColor));
700 
701     tkColPtr->color.red = colorPtr->red;
702     tkColPtr->color.green = colorPtr->green;
703     tkColPtr->color.blue = colorPtr->blue;
704     tkColPtr->color.pixel = TkpGetPixel(colorPtr);
705     return tkColPtr;
706 }
707 
708 /*
709  *----------------------------------------------------------------------
710  *
711  * Stub functions --
712  *
713  *	These functions are just stubs for functions that either
714  *	don't make sense on the Mac or have yet to be implemented.
715  *
716  * Results:
717  *	None.
718  *
719  * Side effects:
720  *	These calls do nothing - which may not be expected.
721  *
722  *----------------------------------------------------------------------
723  */
724 
725 Status
XAllocColor(Display * display,TCL_UNUSED (Colormap),XColor * colorPtr)726 XAllocColor(
727     Display *display,		/* Display. */
728     TCL_UNUSED(Colormap),		/* Not used. */
729     XColor *colorPtr)		/* XColor struct to modify. */
730 {
731     display->request++;
732     colorPtr->pixel = TkpGetPixel(colorPtr);
733     return 1;
734 }
735 
736 Colormap
XCreateColormap(TCL_UNUSED (Display *),TCL_UNUSED (Window),TCL_UNUSED (Visual *),TCL_UNUSED (int))737 XCreateColormap(
738     TCL_UNUSED(Display *),		/* Display. */
739     TCL_UNUSED(Window),		/* X window. */
740     TCL_UNUSED(Visual *),		/* Not used. */
741     TCL_UNUSED(int))			/* Not used. */
742 {
743     static Colormap index = 16;
744 
745     /*
746      * Just return a new value each time, large enough that it will not
747      * conflict with any value of the macColormap enum.
748      */
749     return index++;
750 }
751 
752 int
XFreeColormap(TCL_UNUSED (Display *),TCL_UNUSED (Colormap))753 XFreeColormap(
754     TCL_UNUSED(Display *),		/* Display. */
755     TCL_UNUSED(Colormap))		/* Colormap. */
756 {
757     return Success;
758 }
759 
760 int
XFreeColors(TCL_UNUSED (Display *),TCL_UNUSED (Colormap),TCL_UNUSED (unsigned long *),TCL_UNUSED (int),TCL_UNUSED (unsigned long))761 XFreeColors(
762     TCL_UNUSED(Display *),		/* Display. */
763     TCL_UNUSED(Colormap),		/* Colormap. */
764     TCL_UNUSED(unsigned long *),	/* Array of pixels. */
765     TCL_UNUSED(int),		/* Number of pixels. */
766     TCL_UNUSED(unsigned long))	/* Number of pixel planes. */
767 {
768     /*
769      * Nothing needs to be done to release colors as there really is no
770      * colormap in the Tk sense.
771      */
772     return Success;
773 }
774 
775 /*
776  * Local Variables:
777  * mode: objc
778  * c-basic-offset: 4
779  * fill-column: 79
780  * coding: utf-8
781  * End:
782  */
783