Tk Source Code

Check-in [d222d486]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add 8 colors to the supported color list (aqua, crimson, fuchsia, indigo, lime, olive, silver and teal), part of TIP #403
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-4-branch
Files: files | file ages | folders
SHA1: d222d486b422b5c19437251a936f6fc5c124ee3b
User & Date: jan.nijtmans 2012-09-28 09:41:22
Context
2012-10-23
13:26
sync nmakehlp.c with Tcl version check-in: d6caa983 user: jan.nijtmans tags: core-8-4-branch
2012-09-28
10:42
Add 8 colors to the supported color list (aqua, crimson, fuchsia, indigo, lime, olive, silver and teal), part of TIP #403 check-in: 357653d8 user: jan.nijtmans tags: core-8-5-branch
09:41
Add 8 colors to the supported color list (aqua, crimson, fuchsia, indigo, lime, olive, silver and teal), part of TIP #403 check-in: d222d486 user: jan.nijtmans tags: core-8-4-branch
2012-09-26
13:04
Compile win32 binaries with -DTCL_NO_DEPRECATED check-in: 93d8c72f user: jan.nijtmans tags: core-8-4-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.









1
2
3
4
5
6
7








2012-09-26  Jan Nijtmans  <[email protected]>

	* win/Makefile.in:    Compile win32 binaries with -DTCL_NO_DEPRECATED

2012-08-28  Jan Nijtmans  <[email protected]>

	* generic/tkMenuDraw.c: [Bug 3562426]: Context menu goes out of edge of
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2012-09-27  Jan Nijtmans  <[email protected]>

	* generic/tkInt.h:     Add 8 colors to the supported color list
	* generic/tkColor.c:   (aqua, crimson, fuchsia, indigo, lime,
	* unix/tkUnixColor.c:  olive, silver and teal), part of TIP #403
	* xlib/rgb.txt
	* xlib/xcolors.c

2012-09-26  Jan Nijtmans  <[email protected]>

	* win/Makefile.in:    Compile win32 binaries with -DTCL_NO_DEPRECATED

2012-08-28  Jan Nijtmans  <[email protected]>

	* generic/tkMenuDraw.c: [Bug 3562426]: Context menu goes out of edge of

Changes to generic/tkColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* 
 * tkColor.c --
 *
 *	This file maintains a database of color values for the Tk
 *	toolkit, in order to avoid round-trips to the server to
 *	map color names to pixel values.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */


#include "tkColor.h"

/*
 * Structures of the following following type are used as keys for 
 * colorValueTable (in TkDisplay).
 */

typedef struct {
    int red, green, blue;	/* Values for desired color. */
    Colormap colormap;		/* Colormap from which color will be
				 * allocated. */
    Display *display;		/* Display for colormap. */
} ValueKey;


/*
 * The structure below is used to allocate thread-local data. 
 */

typedef struct ThreadSpecificData {
    char rgbString[20];            /* */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for procedures defined in this file:
 */

static void		ColorInit _ANSI_ARGS_((TkDisplay *dispPtr));
static void		DupColorObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr));
static void		FreeColorObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		InitColorObj _ANSI_ARGS_((Tcl_Obj *objPtr));

/*
 * The following structure defines the implementation of the "color" Tcl
 * object, which maps a string color name to a TkColor object.  The
 * ptr1 field of the Tcl_Obj points to a TkColor object.
 */

Tcl_ObjType tkColorObjType = {
    "color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocColorFromObj --
 *
 *	Given a Tcl_Obj *, map the value to a corresponding
 *	XColor structure based on the tkwin given.
 *
 * Results:
 *	The return value is a pointer to an XColor structure that
 *	indicates the red, blue, and green intensities for the color
 *	given by the string in objPtr, and also specifies a pixel value 
 *	to use to draw in that color.  If an error occurs, NULL is 
 *	returned and an error message will be left in interp's result
 *	(unless interp is NULL).
 *
 * Side effects:
 *	The color is added to an internal database with a reference count.
 *	For each call to this procedure, there should eventually be a call
 *	to Tk_FreeColorFromObj so that the database is cleaned up when colors
 *	aren't in use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_AllocColorFromObj(interp, tkwin, objPtr)
|


|
|
|




|
|


>



|










<

|



|




|










|
|















|
|


|
|
|
<
|
|


|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * tkColor.c --
 *
 *	This file maintains a database of color values for the Tk toolkit, in
 *	order to avoid round-trips to the server to map color names to pixel
 *	values.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkColor.h"

/*
 * Structures of the following following type are used as keys for
 * colorValueTable (in TkDisplay).
 */

typedef struct {
    int red, green, blue;	/* Values for desired color. */
    Colormap colormap;		/* Colormap from which color will be
				 * allocated. */
    Display *display;		/* Display for colormap. */
} ValueKey;


/*
 * The structure below is used to allocate thread-local data.
 */

typedef struct ThreadSpecificData {
    char rgbString[20];		/* */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Forward declarations for functions defined in this file:
 */

static void		ColorInit _ANSI_ARGS_((TkDisplay *dispPtr));
static void		DupColorObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr,
			    Tcl_Obj *dupObjPtr));
static void		FreeColorObjProc _ANSI_ARGS_((Tcl_Obj *objPtr));
static void		InitColorObj _ANSI_ARGS_((Tcl_Obj *objPtr));

/*
 * The following structure defines the implementation of the "color" Tcl
 * object, which maps a string color name to a TkColor object. The ptr1 field
 * of the Tcl_Obj points to a TkColor object.
 */

Tcl_ObjType tkColorObjType = {
    "color",			/* name */
    FreeColorObjProc,		/* freeIntRepProc */
    DupColorObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_AllocColorFromObj --
 *
 *	Given a Tcl_Obj *, map the value to a corresponding XColor structure
 *	based on the tkwin given.
 *
 * Results:
 *	The return value is a pointer to an XColor structure that indicates
 *	the red, blue, and green intensities for the color given by the string
 *	in objPtr, and also specifies a pixel value to use to draw in that

 *	color. If an error occurs, NULL is returned and an error message will
 *	be left in interp's result (unless interp is NULL).
 *
 * Side effects:
 *	The color is added to an internal database with a reference count. For
 *	each call to this function, there should eventually be a call to
 *	Tk_FreeColorFromObj so that the database is cleaned up when colors
 *	aren't in use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_AllocColorFromObj(interp, tkwin, objPtr)
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }
    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkColor, see if it's the
     * one we want.  If so, increment its reference count and return.
     */

    if (tkColPtr != NULL) {
	if (tkColPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkColor that's
	     * no longer in use.  Clear the reference.
	     */

	    FreeColorObjProc(objPtr);
	    tkColPtr = NULL;
	} else if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    tkColPtr->resourceRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

    /*
     * The object didn't point to the TkColor that we wanted.  Search
     * the list of TkColors with the same name to see if one of the
     * other TkColors is the right one.
     */

    if (tkColPtr != NULL) {
	TkColor *firstColorPtr = 
		(TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
	FreeColorObjProc(objPtr);
	for (tkColPtr = firstColorPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == tkColPtr->screen)
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		tkColPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
		return (XColor *) tkColPtr;
	    }
	}
    }

    /*
     * Still no luck.  Call Tk_GetColor to allocate a new TkColor object.
     */

    tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
    return (XColor *) tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColor --
 *
 *	Given a string name for a color, map the name to a corresponding
 *	XColor structure.
 *
 * Results:
 *	The return value is a pointer to an XColor structure that
 *	indicates the red, blue, and green intensities for the color
 *	given by "name", and also specifies a pixel value to use to
 *	draw in that color.  If an error occurs, NULL is returned and
 *	an error message will be left in the interp's result.
 *
 * Side effects:
 *	The color is added to an internal database with a reference count.
 *	For each call to this procedure, there should eventually be a call
 *	to Tk_FreeColor so that the database is cleaned up when colors
 *	aren't in use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColor(interp, tkwin, name)
    Tcl_Interp *interp;		/* Place to leave error message if
				 * color can't be found. */
    Tk_Window tkwin;		/* Window in which color will be used. */
    Tk_Uid name;		/* Name of color to be allocated (in form
				 * suitable for passing to XParseColor). */
{
    Tcl_HashEntry *nameHashPtr;
    int new;
    TkColor *tkColPtr;
    TkColor *existingColPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->colorInit) {
	ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color
     * name.
     */

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &new);
    if (!new) {
	existingColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr);
	for (tkColPtr = existingColPtr;  tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((tkColPtr->screen == Tk_Screen(tkwin))
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		return &tkColPtr->color;
	    }
	}
    } else {
	existingColPtr = NULL;
    }

    /*
     * The name isn't currently known.  Map from the name to a pixel
     * value.
     */

    tkColPtr = TkpGetColor(tkwin, name);
    if (tkColPtr == NULL) {
	if (interp != NULL) {
	    if (*name == '#') {
		Tcl_AppendResult(interp, "invalid color name \"", name,
			"\"", (char *) NULL);
	    } else {
		Tcl_AppendResult(interp, "unknown color name \"", name,
			"\"", (char *) NULL);
	    }
	}
	if (new) {
	    Tcl_DeleteHashEntry(nameHashPtr);
	}
	return (XColor *) NULL;
    }

    /*
     * Now create a new TkColor structure and add it to colorNameTable
     * (in TkDisplay).
     */

    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = Tk_Colormap(tkwin);
    tkColPtr->visual  = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_NAME;
    tkColPtr->hashPtr = nameHashPtr;
    tkColPtr->nextPtr = existingColPtr;
    Tcl_SetHashValue(nameHashPtr, tkColPtr);

    return &tkColPtr->color;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColorByValue --
 *
 *	Given a desired set of red-green-blue intensities for a color,
 *	locate a pixel value to use to draw that color in a given
 *	window.
 *
 * Results:
 *	The return value is a pointer to an XColor structure that
 *	indicates the closest red, blue, and green intensities available
 *	to those specified in colorPtr, and also specifies a pixel
 *	value to use to draw in that color.
 *
 * Side effects:
 *	The color is added to an internal database with a reference count.
 *	For each call to this procedure, there should eventually be a call
 *	to Tk_FreeColor, so that the database is cleaned up when colors
 *	aren't in use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColorByValue(tkwin, colorPtr)
    Tk_Window tkwin;		/* Window where color will be used. */
    XColor *colorPtr;		/* Red, green, and blue fields indicate
				 * desired color. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr;
    int new;
    TkColor *tkColPtr;
    Display *display = Tk_Display(tkwin);
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->colorInit) {
	ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color

     * name.
     */


    valueKey.red = colorPtr->red;
    valueKey.green = colorPtr->green;
    valueKey.blue = colorPtr->blue;
    valueKey.colormap = Tk_Colormap(tkwin);
    valueKey.display = display;
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable, 
            (char *) &valueKey, &new);
    if (!new) {
	tkColPtr = (TkColor *) Tcl_GetHashValue(valueHashPtr);
	tkColPtr->resourceRefCount++;
	return &tkColPtr->color;
    }

    /*
     * The name isn't currently known.  Find a pixel value for this
     * color and add a new structure to colorValueTable (in TkDisplay).
     */

    tkColPtr = TkpGetColorByValue(tkwin, colorPtr);
    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = valueKey.colormap;
    tkColPtr->visual  = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_VALUE;
    tkColPtr->hashPtr = valueHashPtr;
    tkColPtr->nextPtr = NULL;
    Tcl_SetHashValue(valueHashPtr, tkColPtr);
    return &tkColPtr->color;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfColor --
 *
 *	Given a color, return a textual string identifying
 *	the color.
 *
 * Results:
 *	If colorPtr was created by Tk_GetColor, then the return
 *	value is the "string" that was used to create it.
 *	Otherwise the return value is a string that could have
 *	been passed to Tk_GetColor to allocate that color.  The
 *	storage for the returned string is only guaranteed to
 *	persist up until the next call to this procedure.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfColor(colorPtr)
    XColor *colorPtr;		/* Color whose name is desired. */
{
    register TkColor *tkColPtr = (TkColor *) colorPtr;
    
    if ((tkColPtr->magic == COLOR_MAGIC) &&
	    (tkColPtr->type == TK_COLOR_BY_NAME)) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *) 
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red, 
		colorPtr->green, colorPtr->blue);
	return tsdPtr->rgbString;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GCForColor --
 *
 *	Given a color allocated from this module, this procedure
 *	returns a GC that can be used for simple drawing with that
 *	color.
 *
 * Results:
 *	The return value is a GC with color set as its foreground
 *	color and all other fields defaulted.  This GC is only valid
 *	as long as the color exists;  it is freed automatically when
 *	the last reference to the color is freed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

GC
Tk_GCForColor(colorPtr, drawable)
    XColor *colorPtr;		/* Color for which a GC is desired. Must
				 * have been allocated by Tk_GetColor. */
    Drawable drawable;		/* Drawable in which the color will be
				 * used (must have same screen and depth
				 * as the one for which the color was
				 * allocated). */
{
    TkColor *tkColPtr = (TkColor *) colorPtr;
    XGCValues gcValues;

    /*
     * Do a quick sanity check to make sure this color was really
     * allocated by Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	panic("Tk_GCForColor called with bogus color");
    }

    if (tkColPtr->gc == None) {
	gcValues.foreground = tkColPtr->color.pixel;
	tkColPtr->gc = XCreateGC(DisplayOfScreen(tkColPtr->screen),
		drawable, GCForeground, &gcValues);
    }
    return tkColPtr->gc;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColor --
 *
 *	This procedure is called to release a color allocated by
 *	Tk_GetColor.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with colorPtr is deleted, and
 *	the color is released to X if there are no remaining uses
 *	for it.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeColor(colorPtr)
    XColor *colorPtr;		/* Color to be released.  Must have been
				 * allocated by Tk_GetColor or
				 * Tk_GetColorByValue. */
{
    TkColor *tkColPtr = (TkColor *) colorPtr;
    Screen *screen = tkColPtr->screen;
    TkColor *prevPtr;

    /*
     * Do a quick sanity check to make sure this color was really
     * allocated by Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	panic("Tk_FreeColor called with bogus color");
    }

    tkColPtr->resourceRefCount--;
    if (tkColPtr->resourceRefCount > 0) {
	return;
    }

    /*
     * This color is no longer being actively used, so free the color
     * resources associated with it and remove it from the hash table.
     * no longer any objects referencing it.
     */

    if (tkColPtr->gc != None) {
	XFreeGC(DisplayOfScreen(screen), tkColPtr->gc);
	tkColPtr->gc = None;
    }
    TkpFreeColor(tkColPtr);

    prevPtr = (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
    if (prevPtr == tkColPtr) {
	if (tkColPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(tkColPtr->hashPtr);
	} else  {
	    Tcl_SetHashValue(tkColPtr->hashPtr, tkColPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != tkColPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = tkColPtr->nextPtr;
    }

    /*
     * Free the TkColor structure if there are no objects referencing
     * it.  However, if there are objects referencing it then keep the
     * structure around; it will get freed when the last reference is
     * cleared
     */

    if (tkColPtr->objRefCount == 0) {
	ckfree((char *) tkColPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColorFromObj --
 *
 *	This procedure is called to release a color allocated by
 *	Tk_AllocColorFromObj. It does not throw away the Tcl_Obj *;
 *	it only gets rid of the hash table entry for this color
 *	and clears the cached value that is normally stored in the object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with the color represented by
 *	objPtr is decremented, and the color is released to X if there are 
 *	no remaining uses for it.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeColorFromObj(tkwin, objPtr)
    Tk_Window tkwin;		/* The window this color lives in. Needed
				 * for the screen and colormap values. */
    Tcl_Obj *objPtr;		/* The Tcl_Obj * to be freed. */
{
    Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr));
    FreeColorObjProc(objPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeColorObjProc -- 
 *
 *	This proc is called to release an object reference to a color.
 *	Called when the object's internal rep is released or when
 *	the cached tkColPtr needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it
 *	and the hash ref count go to zero, the color's resources
 *	are released.
 *
 *---------------------------------------------------------------------------
 */

static void
FreeColorObjProc(objPtr)
    Tcl_Obj *objPtr;		/* The object we are releasing. */
{
    TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount--;
	if ((tkColPtr->objRefCount == 0) 
		&& (tkColPtr->resourceRefCount == 0)) {
	    ckfree((char *) tkColPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * DupColorObjProc -- 
 *
 *	When a cached color object is duplicated, this is called to
 *	update the internal reps.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The color's objRefCount is incremented and the internal rep
 *	of the copy is set to point to it.
 *
 *---------------------------------------------------------------------------
 */

static void
DupColorObjProc(srcObjPtr, dupObjPtr)
    Tcl_Obj *srcObjPtr;		/* The object we are copying from. */
    Tcl_Obj *dupObjPtr;		/* The object we are copying to. */
{
    TkColor *tkColPtr = (TkColor *) srcObjPtr->internalRep.twoPtrValue.ptr1;
    
    dupObjPtr->typePtr = srcObjPtr->typePtr;
    dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColorFromObj --
 *
 *	Returns the color referred to by a Tcl object.  The color must
 *	already have been allocated via a call to Tk_AllocColorFromObj
 *	or Tk_GetColor.
 *
 * Results:
 *	Returns the XColor * that matches the tkwin and the string rep
 *	of objPtr.
 *
 * Side effects:
 *	If the object is not already a color, the conversion will free
 *	any old internal representation. 
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColorFromObj(tkwin, objPtr)
    Tk_Window tkwin;		/* The window in which the color will be
				 * used. */
    Tcl_Obj *objPtr;		/* String value contains the name of the
				 * desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }
  
    /*
     * First check to see if the internal representation of the object
     * is defined and is a color that is valid for the current screen
     * and color map.  If it is, we are done.
     */

    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
    if ((tkColPtr != NULL)
	    && (tkColPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == tkColPtr->screen)
	    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	/*
	 * The object already points to the right TkColor structure.
	 * Just return it.
	 */

	return (XColor *) tkColPtr;
    }

    /*
     * If we reach this point, it means that the TkColor structure
     * that we have cached in the internal representation is not valid
     * for the current screen and colormap.  But there is a list of
     * other TkColor structures attached to the TkDisplay.  Walk this
     * list looking for the right TkColor structure.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, 
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);
	    (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    FreeColorObjProc(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
	    tkColPtr->objRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

    error:
    panic(" Tk_GetColorFromObj called with non-existent color!");
    /*
     * The following code isn't reached; it's just there to please compilers.
     */
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * InitColorObj --
 *
 *	Bookeeping procedure to change an objPtr to a color type.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The old internal rep of the object is freed. The object's
 *	type is set to color with a NULL TkColor pointer (the pointer
 *	will be set later by either Tk_AllocColorFromObj or
 *	Tk_GetColorFromObj).
 *
 *----------------------------------------------------------------------
 */

static void
InitColorObj(objPtr)
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one. 
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }







|
|





|
|












|
|
|



















|



















|
|
|
|
|


|
|
|
|






|
|





|









|
<


|
|

|












|
<







|


|


|






|
|






|















|
|
<


|
|
|
|


|
|
|
|












|









|
>
|


>





|
|
|






|
|







|














|
<


|
|
<
|
|
|












|




|
|
>
|










|
|
<


|
|
|
|









|
|
|
|
|
<





|
|



|




|
|









|
<





|
|
<















|
|



|









|
|












|










|
|
|
<












|
|
|
|





|
|
|

















|

|
|
|





|
|
<












|










|

|
|





|
|










|













|
|
<


|
|


|
|


















|

|
|
|

>






|
|






|
|
|
|
|


|















|
|











|





|
|
|
<











|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }
    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    /*
     * If the object currently points to a TkColor, see if it's the one we
     * want. If so, increment its reference count and return.
     */

    if (tkColPtr != NULL) {
	if (tkColPtr->resourceRefCount == 0) {
	    /*
	     * This is a stale reference: it refers to a TkColor that's no
	     * longer in use. Clear the reference.
	     */

	    FreeColorObjProc(objPtr);
	    tkColPtr = NULL;
	} else if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    tkColPtr->resourceRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

    /*
     * The object didn't point to the TkColor that we wanted. Search the list
     * of TkColors with the same name to see if one of the other TkColors is
     * the right one.
     */

    if (tkColPtr != NULL) {
	TkColor *firstColorPtr = 
		(TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
	FreeColorObjProc(objPtr);
	for (tkColPtr = firstColorPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((Tk_Screen(tkwin) == tkColPtr->screen)
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		tkColPtr->objRefCount++;
		objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
		return (XColor *) tkColPtr;
	    }
	}
    }

    /*
     * Still no luck. Call Tk_GetColor to allocate a new TkColor object.
     */

    tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
    return (XColor *) tkColPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColor --
 *
 *	Given a string name for a color, map the name to a corresponding
 *	XColor structure.
 *
 * Results:
 *	The return value is a pointer to an XColor structure that indicates
 *	the red, blue, and green intensities for the color given by "name",
 *	and also specifies a pixel value to use to draw in that color. If an
 *	error occurs, NULL is returned and an error message will be left in
 *	the interp's result.
 *
 * Side effects:
 *	The color is added to an internal database with a reference count. For
 *	each call to this function, there should eventually be a call to
 *	Tk_FreeColor so that the database is cleaned up when colors aren't in
 *	use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColor(interp, tkwin, name)
    Tcl_Interp *interp;		/* Place to leave error message if color can't
				 * be found. */
    Tk_Window tkwin;		/* Window in which color will be used. */
    Tk_Uid name;		/* Name of color to be allocated (in form
				 * suitable for passing to XParseColor). */
{
    Tcl_HashEntry *nameHashPtr;
    int isNew;
    TkColor *tkColPtr;
    TkColor *existingColPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (!dispPtr->colorInit) {
	ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color name.

     */

    nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew);
    if (!isNew) {
	existingColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr);
	for (tkColPtr = existingColPtr; tkColPtr != NULL;
		tkColPtr = tkColPtr->nextPtr) {
	    if ((tkColPtr->screen == Tk_Screen(tkwin))
		    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
		tkColPtr->resourceRefCount++;
		return &tkColPtr->color;
	    }
	}
    } else {
	existingColPtr = NULL;
    }

    /*
     * The name isn't currently known. Map from the name to a pixel value.

     */

    tkColPtr = TkpGetColor(tkwin, name);
    if (tkColPtr == NULL) {
	if (interp != NULL) {
	    if (*name == '#') {
		Tcl_AppendResult(interp, "invalid color name \"", name,
			"\"", NULL);
	    } else {
		Tcl_AppendResult(interp, "unknown color name \"", name,
			"\"", NULL);
	    }
	}
	if (isNew) {
	    Tcl_DeleteHashEntry(nameHashPtr);
	}
	return (XColor *) NULL;
    }

    /*
     * Now create a new TkColor structure and add it to colorNameTable (in
     * TkDisplay).
     */

    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = Tk_Colormap(tkwin);
    tkColPtr->visual = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_NAME;
    tkColPtr->hashPtr = nameHashPtr;
    tkColPtr->nextPtr = existingColPtr;
    Tcl_SetHashValue(nameHashPtr, tkColPtr);

    return &tkColPtr->color;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColorByValue --
 *
 *	Given a desired set of red-green-blue intensities for a color, locate
 *	a pixel value to use to draw that color in a given window.

 *
 * Results:
 *	The return value is a pointer to an XColor structure that indicates
 *	the closest red, blue, and green intensities available to those
 *	specified in colorPtr, and also specifies a pixel value to use to draw
 *	in that color.
 *
 * Side effects:
 *	The color is added to an internal database with a reference count. For
 *	each call to this function, there should eventually be a call to
 *	Tk_FreeColor, so that the database is cleaned up when colors aren't in
 *	use anymore.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColorByValue(tkwin, colorPtr)
    Tk_Window tkwin;		/* Window where color will be used. */
    XColor *colorPtr;		/* Red, green, and blue fields indicate
				 * desired color. */
{
    ValueKey valueKey;
    Tcl_HashEntry *valueHashPtr;
    int isNew;
    TkColor *tkColPtr;
    Display *display = Tk_Display(tkwin);
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->colorInit) {
	ColorInit(dispPtr);
    }

    /*
     * First, check to see if there's already a mapping for this color name.
     * Must clear the structure first; it's not tightly packed on 64-bit
     * systems. [Bug 2911570]
     */

    memset(&valueKey, 0, sizeof(ValueKey));
    valueKey.red = colorPtr->red;
    valueKey.green = colorPtr->green;
    valueKey.blue = colorPtr->blue;
    valueKey.colormap = Tk_Colormap(tkwin);
    valueKey.display = display;
    valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable,
	    (char *) &valueKey, &isNew);
    if (!isNew) {
	tkColPtr = (TkColor *) Tcl_GetHashValue(valueHashPtr);
	tkColPtr->resourceRefCount++;
	return &tkColPtr->color;
    }

    /*
     * The name isn't currently known. Find a pixel value for this color and
     * add a new structure to colorValueTable (in TkDisplay).
     */

    tkColPtr = TkpGetColorByValue(tkwin, colorPtr);
    tkColPtr->magic = COLOR_MAGIC;
    tkColPtr->gc = None;
    tkColPtr->screen = Tk_Screen(tkwin);
    tkColPtr->colormap = valueKey.colormap;
    tkColPtr->visual = Tk_Visual(tkwin);
    tkColPtr->resourceRefCount = 1;
    tkColPtr->objRefCount = 0;
    tkColPtr->type = TK_COLOR_BY_VALUE;
    tkColPtr->hashPtr = valueHashPtr;
    tkColPtr->nextPtr = NULL;
    Tcl_SetHashValue(valueHashPtr, tkColPtr);
    return &tkColPtr->color;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfColor --
 *
 *	Given a color, return a textual string identifying the color.

 *
 * Results:
 *	If colorPtr was created by Tk_GetColor, then the return value is the
 *	"string" that was used to create it. Otherwise the return value is a

 *	string that could have been passed to Tk_GetColor to allocate that
 *	color. The storage for the returned string is only guaranteed to
 *	persist up until the next call to this function.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

CONST char *
Tk_NameOfColor(colorPtr)
    XColor *colorPtr;		/* Color whose name is desired. */
{
    register TkColor *tkColPtr = (TkColor *) colorPtr;

    if ((tkColPtr->magic == COLOR_MAGIC) &&
	    (tkColPtr->type == TK_COLOR_BY_NAME)) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);
	return tsdPtr->rgbString;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GCForColor --
 *
 *	Given a color allocated from this module, this function returns a GC
 *	that can be used for simple drawing with that color.

 *
 * Results:
 *	The return value is a GC with color set as its foreground color and
 *	all other fields defaulted. This GC is only valid as long as the color
 *	exists; it is freed automatically when the last reference to the color
 *	is freed.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

GC
Tk_GCForColor(colorPtr, drawable)
    XColor *colorPtr;		/* Color for which a GC is desired. Must have
				 * been allocated by Tk_GetColor. */
    Drawable drawable;		/* Drawable in which the color will be used
				 * (must have same screen and depth as the one
				 * for which the color was allocated). */

{
    TkColor *tkColPtr = (TkColor *) colorPtr;
    XGCValues gcValues;

    /*
     * Do a quick sanity check to make sure this color was really allocated by
     * Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	Tcl_Panic("Tk_GCForColor called with bogus color");
    }

    if (tkColPtr->gc == None) {
	gcValues.foreground = tkColPtr->color.pixel;
	tkColPtr->gc = XCreateGC(DisplayOfScreen(tkColPtr->screen), drawable,
		GCForeground, &gcValues);
    }
    return tkColPtr->gc;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColor --
 *
 *	This function is called to release a color allocated by Tk_GetColor.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with colorPtr is deleted, and the color
 *	is released to X if there are no remaining uses for it.

 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeColor(colorPtr)
    XColor *colorPtr;		/* Color to be released.  Must have been
				 * allocated by Tk_GetColor or
				 * Tk_GetColorByValue. */
{
    TkColor *tkColPtr = (TkColor *) colorPtr;
    Screen *screen = tkColPtr->screen;
    TkColor *prevPtr;

    /*
     * Do a quick sanity check to make sure this color was really allocated by
     * Tk_GetColor.
     */

    if (tkColPtr->magic != COLOR_MAGIC) {
	Tcl_Panic("Tk_FreeColor called with bogus color");
    }

    tkColPtr->resourceRefCount--;
    if (tkColPtr->resourceRefCount > 0) {
	return;
    }

    /*
     * This color is no longer being actively used, so free the color
     * resources associated with it and remove it from the hash table. No
     * longer any objects referencing it.
     */

    if (tkColPtr->gc != None) {
	XFreeGC(DisplayOfScreen(screen), tkColPtr->gc);
	tkColPtr->gc = None;
    }
    TkpFreeColor(tkColPtr);

    prevPtr = (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr);
    if (prevPtr == tkColPtr) {
	if (tkColPtr->nextPtr == NULL) {
	    Tcl_DeleteHashEntry(tkColPtr->hashPtr);
	} else {
	    Tcl_SetHashValue(tkColPtr->hashPtr, tkColPtr->nextPtr);
	}
    } else {
	while (prevPtr->nextPtr != tkColPtr) {
	    prevPtr = prevPtr->nextPtr;
	}
	prevPtr->nextPtr = tkColPtr->nextPtr;
    }

    /*
     * Free the TkColor structure if there are no objects referencing it.
     * However, if there are objects referencing it then keep the structure
     * around; it will get freed when the last reference is cleared

     */

    if (tkColPtr->objRefCount == 0) {
	ckfree((char *) tkColPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FreeColorFromObj --
 *
 *	This function is called to release a color allocated by
 *	Tk_AllocColorFromObj. It does not throw away the Tcl_Obj *; it only
 *	gets rid of the hash table entry for this color and clears the cached
 *	value that is normally stored in the object.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The reference count associated with the color represented by objPtr is
 *	decremented, and the color is released to X if there are no remaining
 *	uses for it.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeColorFromObj(tkwin, objPtr)
    Tk_Window tkwin;		/* The window this color lives in. Needed
				 * for the screen and colormap values. */
    Tcl_Obj *objPtr;		/* The Tcl_Obj * to be freed. */
{
    Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr));
    FreeColorObjProc(objPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * FreeColorObjProc --
 *
 *	This proc is called to release an object reference to a color. Called
 *	when the object's internal rep is released or when the cached tkColPtr
 *	needs to be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The object reference count is decremented. When both it and the hash
 *	ref count go to zero, the color's resources are released.

 *
 *---------------------------------------------------------------------------
 */

static void
FreeColorObjProc(objPtr)
    Tcl_Obj *objPtr;		/* The object we are releasing. */
{
    TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount--;
	if ((tkColPtr->objRefCount == 0)
		&& (tkColPtr->resourceRefCount == 0)) {
	    ckfree((char *) tkColPtr);
	}
	objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * DupColorObjProc --
 *
 *	When a cached color object is duplicated, this is called to update the
 *	internal reps.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The color's objRefCount is incremented and the internal rep of the
 *	copy is set to point to it.
 *
 *---------------------------------------------------------------------------
 */

static void
DupColorObjProc(srcObjPtr, dupObjPtr)
    Tcl_Obj *srcObjPtr;		/* The object we are copying from. */
    Tcl_Obj *dupObjPtr;		/* The object we are copying to. */
{
    TkColor *tkColPtr = (TkColor *) srcObjPtr->internalRep.twoPtrValue.ptr1;

    dupObjPtr->typePtr = srcObjPtr->typePtr;
    dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;

    if (tkColPtr != NULL) {
	tkColPtr->objRefCount++;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetColorFromObj --
 *
 *	Returns the color referred to by a Tcl object. The color must already
 *	have been allocated via a call to Tk_AllocColorFromObj or Tk_GetColor.

 *
 * Results:
 *	Returns the XColor * that matches the tkwin and the string rep of
 *	objPtr.
 *
 * Side effects:
 *	If the object is not already a color, the conversion will free any old
 *	internal representation.
 *
 *----------------------------------------------------------------------
 */

XColor *
Tk_GetColorFromObj(tkwin, objPtr)
    Tk_Window tkwin;		/* The window in which the color will be
				 * used. */
    Tcl_Obj *objPtr;		/* String value contains the name of the
				 * desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (objPtr->typePtr != &tkColorObjType) {
	InitColorObj(objPtr);
    }

    /*
     * First check to see if the internal representation of the object is
     * defined and is a color that is valid for the current screen and color
     * map. If it is, we are done.
     */

    tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
    if ((tkColPtr != NULL)
	    && (tkColPtr->resourceRefCount > 0)
	    && (Tk_Screen(tkwin) == tkColPtr->screen)
	    && (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	/*
	 * The object already points to the right TkColor structure. Just
	 * return it.
	 */

	return (XColor *) tkColPtr;
    }

    /*
     * If we reach this point, it means that the TkColor structure that we
     * have cached in the internal representation is not valid for the current
     * screen and colormap. But there is a list of other TkColor structures
     * attached to the TkDisplay. Walk this list looking for the right TkColor
     * structure.
     */

    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable,
	    Tcl_GetString(objPtr));
    if (hashPtr == NULL) {
	goto error;
    }
    for (tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);
	    (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	if ((Tk_Screen(tkwin) == tkColPtr->screen)
		&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
	    FreeColorObjProc(objPtr);
	    objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr;
	    tkColPtr->objRefCount++;
	    return (XColor *) tkColPtr;
	}
    }

  error:
    Tcl_Panic("Tk_GetColorFromObj called with non-existent color!");
    /*
     * The following code isn't reached; it's just there to please compilers.
     */
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * InitColorObj --
 *
 *	Bookeeping function to change an objPtr to a color type.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The old internal rep of the object is freed. The object's type is set
 *	to color with a NULL TkColor pointer (the pointer will be set later by
 *	either Tk_AllocColorFromObj or Tk_GetColorFromObj).

 *
 *----------------------------------------------------------------------
 */

static void
InitColorObj(objPtr)
    Tcl_Obj *objPtr;		/* The object to convert. */
{
    Tcl_ObjType *typePtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	(*typePtr->freeIntRepProc)(objPtr);
    }
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797

798
799
800
801
802

803
804
805
806
807
808
809
810
811
812
813

814
815


























816
817
818
819
820
821
822
 */

static void
ColorInit(dispPtr)
    TkDisplay *dispPtr;
{
    if (!dispPtr->colorInit) {
        dispPtr->colorInit = 1;
	Tcl_InitHashTable(&dispPtr->colorNameTable, TCL_STRING_KEYS);
	Tcl_InitHashTable(&dispPtr->colorValueTable, 
                sizeof(ValueKey)/sizeof(int));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugColor --
 *
 *	This procedure returns debugging information about a color.
 *
 * Results:
 *	The return value is a list with one sublist for each TkColor
 *	corresponding to "name".  Each sublist has two elements that
 *	contain the resourceRefCount and objRefCount fields from the
 *	TkColor structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugColor(tkwin, name)
    Tk_Window tkwin;		/* The window in which the color will be
				 * used (not currently used). */
    char *name;			/* Name of the desired color. */
{
    TkColor *tkColPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name);
    if (hashPtr != NULL) {
	tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);

	if (tkColPtr == NULL) {
	    panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->objRefCount)); 
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef __WIN32__

/* This function is not necessary for Win32,
 * since XParseColor already does the right thing */


























Status
TkParseColor(display, map, name, color)
    Display * display;		/* The display */
    Colormap map;			/* Color map */
    CONST char* name;     /* String to be parsed */
    XColor * color;
{







|

|
|








|



|
|
|









|
|


<

|





|
>

|


|
>



|







>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
 */

static void
ColorInit(dispPtr)
    TkDisplay *dispPtr;
{
    if (!dispPtr->colorInit) {
	dispPtr->colorInit = 1;
	Tcl_InitHashTable(&dispPtr->colorNameTable, TCL_STRING_KEYS);
	Tcl_InitHashTable(&dispPtr->colorValueTable,
		sizeof(ValueKey)/sizeof(int));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugColor --
 *
 *	This function returns debugging information about a color.
 *
 * Results:
 *	The return value is a list with one sublist for each TkColor
 *	corresponding to "name". Each sublist has two elements that contain
 *	the resourceRefCount and objRefCount fields from the TkColor
 *	structure.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugColor(tkwin, name)
    Tk_Window tkwin;		/* The window in which the color will be used
				 * (not currently used). */
    char *name;			/* Name of the desired color. */
{

    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name);
    if (hashPtr != NULL) {
	TkColor *tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr);

	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef __WIN32__

/* This function is not necessary for Win32,
 * since XParseColor already does the right thing */

#undef XParseColor

CONST char *CONST tkWebColors[20] = {
    /* 'a' */ "qua\0#0000ffffffff",
    /* 'b' */ NULL,
    /* 'c' */ "rimson\0#dcdc14143c3c",
    /* 'd' */ NULL,
    /* 'e' */ NULL,
    /* 'f' */ "uchsia\0#ffff0000ffff",
    /* 'g' */ NULL,
    /* 'h' */ NULL,
    /* 'i' */ "ndigo\0#4b4b00008282",
    /* 'j' */ NULL,
    /* 'k' */ NULL,
    /* 'l' */ "ime\0#0000ffff0000",
    /* 'm' */ NULL,
    /* 'n' */ NULL,
    /* 'o' */ "live\0#808080800000",
    /* 'p' */ NULL,
    /* 'q' */ NULL,
    /* 'r' */ NULL,
    /* 's' */ "ilver\0#c0c0c0c0c0c0",
    /* 't' */ "eal\0#000080808080"
};

Status
TkParseColor(display, map, name, color)
    Display * display;		/* The display */
    Colormap map;			/* Color map */
    CONST char* name;     /* String to be parsed */
    XColor * color;
{
861
862
863
864
865
866
867







868





869
870
871
872
873

874
875
876







	    name = buf;
	} else if (!*(++name) || !*(++name) || *(++name)) {
	    /* Not exactly 12 hex digits, so invalid */
	    return 0;
	} else {
	    name -= 13;
	}







    } else {





	if (strlen(name) > 99) {
	    /* Don't bother to parse this. [Bug 2809525]*/
	    return 0;
	}
    }

    return XParseColor(display, map, name, color);
}
#endif /* __WIN32__ */














>
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
|
<
>



>
>
>
>
>
>
>
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

903
904
905
906
907
908
909
910
911
912
913
	    name = buf;
	} else if (!*(++name) || !*(++name) || *(++name)) {
	    /* Not exactly 12 hex digits, so invalid */
	    return 0;
	} else {
	    name -= 13;
	}
	goto done;
    } else if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {
	const char *p = tkWebColors[((*name - 'A') & 0x1f)];
	if (p) {
	    const char *q = name;
	    while (!((*p - *(++q)) & 0xdf)) {
		if (!*p++) {
		    name = p;
		    goto done;
		}
	    }
	}
    }
    if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return 0;
    }

done:
    return XParseColor(display, map, name, color);
}
#endif /* __WIN32__ */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to generic/tkInt.h.

965
966
967
968
969
970
971


972
973
974
975
976
977
978
extern void			(*tkHandleEventProc) _ANSI_ARGS_((
    				    XEvent* eventPtr));
extern Tk_PhotoImageFormat	tkImgFmtPPM;
extern TkMainInfo		*tkMainWindowList;
extern Tk_ImageType		tkPhotoImageType;
extern Tcl_HashTable		tkPredefBitmapTable;
extern int			tkSendSerial;



#include "tkIntDecls.h"

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif







>
>







965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
extern void			(*tkHandleEventProc) _ANSI_ARGS_((
    				    XEvent* eventPtr));
extern Tk_PhotoImageFormat	tkImgFmtPPM;
extern TkMainInfo		*tkMainWindowList;
extern Tk_ImageType		tkPhotoImageType;
extern Tcl_HashTable		tkPredefBitmapTable;
extern int			tkSendSerial;

extern CONST char *const tkWebColors[20];

#include "tkIntDecls.h"

#ifdef BUILD_tk
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLEXPORT
#endif

Changes to unix/tkUnixColor.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/* 
 * tkUnixColor.c --
 *
 *	This file contains the platform specific color routines
 *	needed for X support.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tkColor.h>

/*
 * If a colormap fills up, attempts to allocate new colors from that
 * colormap will fail.  When that happens, we'll just choose the
 * closest color from those that are available in the colormap.
 * One of the following structures will be created for each "stressed"
 * colormap to keep track of the colors that are available in the
 * colormap (otherwise we would have to re-query from the server on
 * each allocation, which would be very slow).  These entries are
 * flushed after a few seconds, since other clients may release or
 * reallocate colors over time.
 */

struct TkStressedCmap {
    Colormap colormap;			/* X's token for the colormap. */
    int numColors;			/* Number of entries currently active
					 * at *colorPtr. */
    XColor *colorPtr;			/* Pointer to malloc'ed array of all
					 * colors that seem to be available in
					 * the colormap.  Some may not actually
					 * be available, e.g. because they are
					 * read-write for another client;  when
					 * we find this out, we remove them
					 * from the array. */
    struct TkStressedCmap *nextPtr;	/* Next in list of all stressed

					 * colormaps for the display. */
};

/*
 * Forward declarations for procedures defined in this file:
 */

static void		DeleteStressedCmap _ANSI_ARGS_((Display *display,
			    Colormap colormap));
static void		FindClosestColor _ANSI_ARGS_((Tk_Window tkwin,
			    XColor *desiredColorPtr, XColor *actualColorPtr));

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeColor --
 *
 *	Release the specified color back to the system.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Invalidates the colormap cache for the colormap associated with
 *	the given color.
 *
 *----------------------------------------------------------------------
 */

void
TkpFreeColor(tkColPtr)
    TkColor *tkColPtr;		/* Color to be released.  Must have been
				 * allocated by TkpGetColor or
				 * TkpGetColorByValue. */
{
    Visual *visual;
    Screen *screen = tkColPtr->screen;

    /*
     * Careful!  Don't free black or white, since this will
     * make some servers very unhappy.  Also, there is a bug in
     * some servers (such Sun's X11/NeWS server) where reference
     * counting is performed incorrectly, so that if a color is
     * allocated twice in different places and then freed twice,
     * the second free generates an error (this bug existed as of
     * 10/1/92).  To get around this problem, ignore errors that
     * occur during the free operation.
     */

    visual = tkColPtr->visual;
    if ((visual->class != StaticGray) && (visual->class != StaticColor)
	    && (tkColPtr->color.pixel != BlackPixelOfScreen(screen))
	    && (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) {
	Tk_ErrorHandler handler;
|


|
|



|
|





|
|
|
|
<
|
|
|




|
|
|
|
|
|
<
|
|
|
|
>
|



|


















|
|














|
<
|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * tkUnixColor.c --
 *
 *	This file contains the platform specific color routines needed for X
 *	support.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <tkColor.h>

/*
 * If a colormap fills up, attempts to allocate new colors from that colormap
 * will fail. When that happens, we'll just choose the closest color from
 * those that are available in the colormap. One of the following structures
 * will be created for each "stressed" colormap to keep track of the colors

 * that are available in the colormap (otherwise we would have to re-query
 * from the server on each allocation, which would be very slow). These
 * entries are flushed after a few seconds, since other clients may release or
 * reallocate colors over time.
 */

struct TkStressedCmap {
    Colormap colormap;		/* X's token for the colormap. */
    int numColors;		/* Number of entries currently active at
				 * *colorPtr. */
    XColor *colorPtr;		/* Pointer to malloc'ed array of all colors
				 * that seem to be available in the colormap.
				 * Some may not actually be available, e.g.

				 * because they are read-write for another
				 * client; when we find this out, we remove
				 * them from the array. */
    struct TkStressedCmap *nextPtr;
				/* Next in list of all stressed colormaps for
				 * the display. */
};

/*
 * Forward declarations for functions defined in this file:
 */

static void		DeleteStressedCmap _ANSI_ARGS_((Display *display,
			    Colormap colormap));
static void		FindClosestColor _ANSI_ARGS_((Tk_Window tkwin,
			    XColor *desiredColorPtr, XColor *actualColorPtr));

/*
 *----------------------------------------------------------------------
 *
 * TkpFreeColor --
 *
 *	Release the specified color back to the system.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Invalidates the colormap cache for the colormap associated with the
 *	given color.
 *
 *----------------------------------------------------------------------
 */

void
TkpFreeColor(tkColPtr)
    TkColor *tkColPtr;		/* Color to be released.  Must have been
				 * allocated by TkpGetColor or
				 * TkpGetColorByValue. */
{
    Visual *visual;
    Screen *screen = tkColPtr->screen;

    /*
     * Careful! Don't free black or white, since this will make some servers

     * very unhappy. Also, there is a bug in some servers (such Sun's X11/NeWS
     * server) where reference counting is performed incorrectly, so that if a
     * color is allocated twice in different places and then freed twice, the
     * second free generates an error (this bug existed as of 10/1/92). To get
     * around this problem, ignore errors that occur during the free
     * operation.
     */

    visual = tkColPtr->visual;
    if ((visual->class != StaticGray) && (visual->class != StaticColor)
	    && (tkColPtr->color.pixel != BlackPixelOfScreen(screen))
	    && (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) {
	Tk_ErrorHandler handler;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140












141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
 *	Allocate a new TkColor for the color with the given name.
 *
 * Results:
 *	Returns a newly allocated TkColor, or NULL on failure.
 *
 * Side effects:
 *	May invalidate the colormap cache associated with tkwin upon
 *	allocating a new colormap entry.  Allocates a new TkColor
 *	structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColor(tkwin, name)
    Tk_Window tkwin;		/* Window in which color will be used. */
    Tk_Uid name;		/* Name of color to allocated (in form
				 * suitable for passing to XParseColor). */
{
    Display *display = Tk_Display(tkwin);
    Colormap colormap = Tk_Colormap(tkwin);
    XColor color;
    TkColor *tkColPtr;

    /*
     * Map from the name to a pixel value.  Call XAllocNamedColor rather than
     * XParseColor for non-# names: this saves a server round-trip for those
     * names.
     */

    if (*name != '#') {
	XColor screen;













	if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return (TkColor *) NULL;
    } else if (XAllocNamedColor(display, colormap, name, &screen, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    /*
	     * Couldn't allocate the color.  Try translating the name to
	     * a color value, to see whether the problem is a bad color
	     * name or a full colormap.  If the colormap is full, then
	     * pick an approximation to the desired color.
	     */

	    if (XLookupColor(display, colormap, name, &color, &screen) == 0) {
		return (TkColor *) NULL;
	    }
	    FindClosestColor(tkwin, &screen, &color);
	}
    } else {

	if (TkParseColor(display, colormap, name, &color) == 0) {
	    return (TkColor *) NULL;
	}
	if (XAllocColor(display, colormap, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    FindClosestColor(tkwin, &color, &color);







|
<
















|







>
>
>
>
>
>
>
>
>
>
>
>







|
|
|
|








>







106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 *	Allocate a new TkColor for the color with the given name.
 *
 * Results:
 *	Returns a newly allocated TkColor, or NULL on failure.
 *
 * Side effects:
 *	May invalidate the colormap cache associated with tkwin upon
 *	allocating a new colormap entry. Allocates a new TkColor structure.

 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColor(tkwin, name)
    Tk_Window tkwin;		/* Window in which color will be used. */
    Tk_Uid name;		/* Name of color to allocated (in form
				 * suitable for passing to XParseColor). */
{
    Display *display = Tk_Display(tkwin);
    Colormap colormap = Tk_Colormap(tkwin);
    XColor color;
    TkColor *tkColPtr;

    /*
     * Map from the name to a pixel value. Call XAllocNamedColor rather than
     * XParseColor for non-# names: this saves a server round-trip for those
     * names.
     */

    if (*name != '#') {
	XColor screen;

	if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) {
	    const char *p = tkWebColors[((*name - 'A') & 0x1f)];
	    if (p) {
		const char *q = name;
		while (!((*p - *(++q)) & 0xdf)) {
		    if (!*p++) {
			name = p;
			goto gotWebColor;
		    }
		}
	    }
	}
	if (strlen(name) > 99) {
	/* Don't bother to parse this. [Bug 2809525]*/
	return (TkColor *) NULL;
    } else if (XAllocNamedColor(display, colormap, name, &screen, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    /*
	     * Couldn't allocate the color. Try translating the name to a
	     * color value, to see whether the problem is a bad color name or
	     * a full colormap. If the colormap is full, then pick an
	     * approximation to the desired color.
	     */

	    if (XLookupColor(display, colormap, name, &color, &screen) == 0) {
		return (TkColor *) NULL;
	    }
	    FindClosestColor(tkwin, &screen, &color);
	}
    } else {
    gotWebColor:
	if (TkParseColor(display, colormap, name, &color) == 0) {
	    return (TkColor *) NULL;
	}
	if (XAllocColor(display, colormap, &color) != 0) {
	    DeleteStressedCmap(display, colormap);
	} else {
	    FindClosestColor(tkwin, &color, &color);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColorByValue --
 *
 *	Given a desired set of red-green-blue intensities for a color,
 *	locate a pixel value to use to draw that color in a given
 *	window.
 *
 * Results:
 *	The return value is a pointer to an TkColor structure that
 *	indicates the closest red, blue, and green intensities available
 *	to those specified in colorPtr, and also specifies a pixel
 *	value to use to draw in that color.
 *
 * Side effects:
 *	May invalidate the colormap cache for the specified window.
 *	Allocates a new TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColorByValue(tkwin, colorPtr)
    Tk_Window tkwin;		/* Window in which color will be used. */







|
|
<


|
|
|
|


|
|







184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetColorByValue --
 *
 *	Given a desired set of red-green-blue intensities for a color, locate
 *	a pixel value to use to draw that color in a given window.

 *
 * Results:
 *	The return value is a pointer to an TkColor structure that indicates
 *	the closest red, blue, and green intensities available to those
 *	specified in colorPtr, and also specifies a pixel value to use to draw
 *	in that color.
 *
 * Side effects:
 *	May invalidate the colormap cache for the specified window. Allocates
 *	a new TkColor structure.
 *
 *----------------------------------------------------------------------
 */

TkColor *
TkpGetColorByValue(tkwin, colorPtr)
    Tk_Window tkwin;		/* Window in which color will be used. */
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
}

/*
 *----------------------------------------------------------------------
 *
 * FindClosestColor --
 *
 *	When Tk can't allocate a color because a colormap has filled
 *	up, this procedure is called to find and allocate the closest
 *	available color in the colormap.
 *
 * Results:
 *	There is no return value, but *actualColorPtr is filled in
 *	with information about the closest available color in tkwin's
 *	colormap.  This color has been allocated via X, so it must
 *	be released by the caller when the caller is done with it.
 *
 * Side effects:
 *	A color is allocated.
 *
 *----------------------------------------------------------------------
 */








|
|
|


|
|
|
|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
}

/*
 *----------------------------------------------------------------------
 *
 * FindClosestColor --
 *
 *	When Tk can't allocate a color because a colormap has filled up, this
 *	function is called to find and allocate the closest available color in
 *	the colormap.
 *
 * Results:
 *	There is no return value, but *actualColorPtr is filled in with
 *	information about the closest available color in tkwin's colormap.
 *	This color has been allocated via X, so it must be released by the
 *	caller when the caller is done with it.
 *
 * Side effects:
 *	A color is allocated.
 *
 *----------------------------------------------------------------------
 */

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272

273
274
275
276
277
278
279

280
281

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    int i, closest, numFound;
    XColor *colorPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Colormap colormap = Tk_Colormap(tkwin);
    XVisualInfo template, *visInfoPtr;

    /*
     * Find the TkStressedCmap structure for this colormap, or create
     * a new one if needed.
     */

    for (stressPtr = dispPtr->stressPtr; ; stressPtr = stressPtr->nextPtr) {
	if (stressPtr == NULL) {
	    stressPtr = (TkStressedCmap *) ckalloc(sizeof(TkStressedCmap));
	    stressPtr->colormap = colormap;
	    template.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));

	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &template, &numFound);
	    if (numFound < 1) {
		panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *) ckalloc((unsigned)
		    (stressPtr->numColors * sizeof(XColor)));
	    for (i = 0; i  < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);

	    stressPtr->nextPtr = dispPtr->stressPtr;
	    dispPtr->stressPtr = stressPtr;
	    break;
	}
	if (stressPtr->colormap == colormap) {
	    break;
	}
    }

    /*
     * Find the color that best approximates the desired one, then
     * try to allocate that color.  If that fails, it must mean that
     * the color was read-write (so we can't use it, since it's owner
     * might change it) or else it was already freed.  Try again,
     * over and over again, until something succeeds.
     */

    while (1)  {
	if (stressPtr->numColors == 0) {
	    panic("FindClosestColor ran out of colors");
	}
	closestDistance = 1e30;
	closest = 0;
	for (colorPtr = stressPtr->colorPtr, i = 0; i < stressPtr->numColors;
		colorPtr++, i++) {
	    /*
	     * Use Euclidean distance in RGB space, weighted by Y (of YIQ)
	     * as the objective function;  this accounts for differences
	     * in the color sensitivity of the eye.
	     */
    
	    tmp = .30*(((int) desiredColorPtr->red) - (int) colorPtr->red);
	    distance = tmp*tmp;
	    tmp = .61*(((int) desiredColorPtr->green) - (int) colorPtr->green);
	    distance += tmp*tmp;
	    tmp = .11*(((int) desiredColorPtr->blue) - (int) colorPtr->blue);
	    distance += tmp*tmp;
	    if (distance < closestDistance) {
		closest = i;
		closestDistance = distance;
	    }
	}
	if (XAllocColor(dispPtr->display, colormap,
		&stressPtr->colorPtr[closest]) != 0) {
	    *actualColorPtr = stressPtr->colorPtr[closest];
	    return;
	}

	/*
	 * Couldn't allocate the color.  Remove it from the table and
	 * go back to look for the next best color.
	 */

	stressPtr->colorPtr[closest] =
		stressPtr->colorPtr[stressPtr->numColors-1];
	stressPtr->numColors -= 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteStressedCmap --
 *
 *	This procedure releases the information cached for "colormap"
 *	so that it will be refetched from the X server the next time
 *	it is needed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The TkStressedCmap structure for colormap is deleted;  the
 *	colormap is no longer considered to be "stressed".
 *
 * Note:
 *	This procedure is invoked whenever a color in a colormap is
 *	freed, and whenever a color allocation in a colormap succeeds.
 *	This guarantees that TkStressedCmap structures are always
 *	deleted before the corresponding Colormap is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteStressedCmap(display, colormap)
    Display *display;		/* Xlib's handle for the display
				 * containing the colormap. */
    Colormap colormap;		/* Colormap to flush. */
{
    TkStressedCmap *prevPtr, *stressPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    for (prevPtr = NULL, stressPtr = dispPtr->stressPtr; stressPtr != NULL;
	    prevPtr = stressPtr, stressPtr = stressPtr->nextPtr) {







|
|







>



|

>




|


>


>










|
|
|
|
|


|

|






|
|
|

|


















|
|













|
|
<





|
|


|
|
|
|






|
|







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    int i, closest, numFound;
    XColor *colorPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    Colormap colormap = Tk_Colormap(tkwin);
    XVisualInfo template, *visInfoPtr;

    /*
     * Find the TkStressedCmap structure for this colormap, or create a new
     * one if needed.
     */

    for (stressPtr = dispPtr->stressPtr; ; stressPtr = stressPtr->nextPtr) {
	if (stressPtr == NULL) {
	    stressPtr = (TkStressedCmap *) ckalloc(sizeof(TkStressedCmap));
	    stressPtr->colormap = colormap;
	    template.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));

	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &template, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *) ckalloc((unsigned)
		    (stressPtr->numColors * sizeof(XColor)));
	    for (i = 0; i < stressPtr->numColors; i++) {
		stressPtr->colorPtr[i].pixel = (unsigned long) i;
	    }

	    XQueryColors(dispPtr->display, colormap, stressPtr->colorPtr,
		    stressPtr->numColors);

	    stressPtr->nextPtr = dispPtr->stressPtr;
	    dispPtr->stressPtr = stressPtr;
	    break;
	}
	if (stressPtr->colormap == colormap) {
	    break;
	}
    }

    /*
     * Find the color that best approximates the desired one, then try to
     * allocate that color. If that fails, it must mean that the color was
     * read-write (so we can't use it, since it's owner might change it) or
     * else it was already freed. Try again, over and over again, until
     * something succeeds.
     */

    while (1) {
	if (stressPtr->numColors == 0) {
	    Tcl_Panic("FindClosestColor ran out of colors");
	}
	closestDistance = 1e30;
	closest = 0;
	for (colorPtr = stressPtr->colorPtr, i = 0; i < stressPtr->numColors;
		colorPtr++, i++) {
	    /*
	     * Use Euclidean distance in RGB space, weighted by Y (of YIQ) as
	     * the objective function; this accounts for differences in the
	     * color sensitivity of the eye.
	     */

	    tmp = .30*(((int) desiredColorPtr->red) - (int) colorPtr->red);
	    distance = tmp*tmp;
	    tmp = .61*(((int) desiredColorPtr->green) - (int) colorPtr->green);
	    distance += tmp*tmp;
	    tmp = .11*(((int) desiredColorPtr->blue) - (int) colorPtr->blue);
	    distance += tmp*tmp;
	    if (distance < closestDistance) {
		closest = i;
		closestDistance = distance;
	    }
	}
	if (XAllocColor(dispPtr->display, colormap,
		&stressPtr->colorPtr[closest]) != 0) {
	    *actualColorPtr = stressPtr->colorPtr[closest];
	    return;
	}

	/*
	 * Couldn't allocate the color. Remove it from the table and go back
	 * to look for the next best color.
	 */

	stressPtr->colorPtr[closest] =
		stressPtr->colorPtr[stressPtr->numColors-1];
	stressPtr->numColors -= 1;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteStressedCmap --
 *
 *	This function releases the information cached for "colormap" so that
 *	it will be refetched from the X server the next time it is needed.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The TkStressedCmap structure for colormap is deleted; the colormap is
 *	no longer considered to be "stressed".
 *
 * Note:
 *	This function is invoked whenever a color in a colormap is freed, and
 *	whenever a color allocation in a colormap succeeds. This guarantees
 *	that TkStressedCmap structures are always deleted before the
 *	corresponding Colormap is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteStressedCmap(display, colormap)
    Display *display;		/* Xlib's handle for the display containing
				 * the colormap. */
    Colormap colormap;		/* Colormap to flush. */
{
    TkStressedCmap *prevPtr, *stressPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    for (prevPtr = NULL, stressPtr = dispPtr->stressPtr; stressPtr != NULL;
	    prevPtr = stressPtr, stressPtr = stressPtr->nextPtr) {
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCmapStressed --
 *
 *	Check to see whether a given colormap is known to be out
 *	of entries.
 *
 * Results:
 *	1 is returned if "colormap" is stressed (i.e. it has run out
 *	of entries recently), 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */








|
<


|
|







400
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCmapStressed --
 *
 *	Check to see whether a given colormap is known to be out of entries.

 *
 * Results:
 *	1 is returned if "colormap" is stressed (i.e. it has run out of
 *	entries recently), 0 otherwise.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

417
418
419
420
421
422
423








	    stressPtr != NULL; stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    return 1;
	}
    }
    return 0;
}















>
>
>
>
>
>
>
>
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	    stressPtr != NULL; stressPtr = stressPtr->nextPtr) {
	if (stressPtr->colormap == colormap) {
	    return 1;
	}
    }
    return 0;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */

Changes to xlib/rgb.txt.











1
2
3
4
5
6
7

8
9
10
11
12
13
14










!
240 248 255		aliceBlue
250 235 215		antiqueWhite
255 239 219		antiqueWhite1
238 223 204		antiqueWhite2
205 192 176		antiqueWhite3
139 131 120		antiqueWhite4

127 255 212		aquamarine
127 255 212		aquamarine1
118 238 198		aquamarine2
102 205 170		aquamarine3
 69 139 116		aquamarine4
240 255 255		azure
240 255 255		azure1
>
>
>
>
>
>
>
>
>
>







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
!      Changes compared to Xorg:rgb.txt
!      name       old value       new value
!      aqua           -            0 255 255
!      crimson        -          220  20  60
!      fuchsia        -          255   0 255
!      indigo         -           75   0 130
!      lime           -            0 255   0
!      olive          -          128 128   0
!      silver         -          192 192 192
!      teal           -            0 128 128
!
240 248 255		aliceBlue
250 235 215		antiqueWhite
255 239 219		antiqueWhite1
238 223 204		antiqueWhite2
205 192 176		antiqueWhite3
139 131 120		antiqueWhite4
  0 255 255		aqua
127 255 212		aquamarine
127 255 212		aquamarine1
118 238 198		aquamarine2
102 205 170		aquamarine3
 69 139 116		aquamarine4
240 255 255		azure
240 255 255		azure1
61
62
63
64
65
66
67

68
69
70
71
72
73
74
139  62  47		coral4
100 149 237		cornflowerBlue
255 248 220		cornsilk
255 248 220		cornsilk1
238 232 205		cornsilk2
205 200 177		cornsilk3
139 136 120		cornsilk4

  0 255 255		cyan
  0 255 255		cyan1
  0 238 238		cyan2
  0 205 205		cyan3
  0 139 139		cyan4
  0   0 139		darkBlue
  0 139 139		darkCyan







>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
139  62  47		coral4
100 149 237		cornflowerBlue
255 248 220		cornsilk
255 248 220		cornsilk1
238 232 205		cornsilk2
205 200 177		cornsilk3
139 136 120		cornsilk4
220  20  60		crimson
  0 255 255		cyan
  0 255 255		cyan1
  0 238 238		cyan2
  0 205 205		cyan3
  0 139 139		cyan4
  0   0 139		darkBlue
  0 139 139		darkCyan
133
134
135
136
137
138
139

140
141
142
143
144
145
146
178  34  34		firebrick
255  48  48		firebrick1
238  44  44		firebrick2
205  38  38		firebrick3
139  26  26		firebrick4
255 250 240		floralWhite
 34 139  34		forestGreen

220 220 220		gainsboro
248 248 255		ghostWhite
255 215   0		gold
255 215   0		gold1
238 201   0		gold2
205 173   0		gold3
139 117   0		gold4







>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
178  34  34		firebrick
255  48  48		firebrick1
238  44  44		firebrick2
205  38  38		firebrick3
139  26  26		firebrick4
255 250 240		floralWhite
 34 139  34		forestGreen
255   0 255		fuchsia
220 220 220		gainsboro
248 248 255		ghostWhite
255 215   0		gold
255 215   0		gold1
238 201   0		gold2
205 173   0		gold3
139 117   0		gold4
370
371
372
373
374
375
376

377
378
379
380
381
382
383
205  96 144		hotPink3
139  58  98		hotPink4
205  92  92		indianRed
255 106 106		indianRed1
238  99  99		indianRed2
205  85  85		indianRed3
139  58  58		indianRed4

255 255 240		ivory
255 255 240		ivory1
238 238 224		ivory2
205 205 193		ivory3
139 139 131		ivory4
240 230 140		khaki
255 246 143		khaki1







>







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
205  96 144		hotPink3
139  58  98		hotPink4
205  92  92		indianRed
255 106 106		indianRed1
238  99  99		indianRed2
205  85  85		indianRed3
139  58  58		indianRed4
 75   0 130		indigo
255 255 240		ivory
255 255 240		ivory1
238 238 224		ivory2
205 205 193		ivory3
139 139 131		ivory4
240 230 140		khaki
255 246 143		khaki1
441
442
443
444
445
446
447

448
449
450
451
452
453
454
162 181 205		lightSteelBlue3
110 123 139		lightSteelBlue4
255 255 224		lightYellow
255 255 224		lightYellow1
238 238 209		lightYellow2
205 205 180		lightYellow3
139 139 122		lightYellow4

 50 205  50		limeGreen
250 240 230		linen
255   0 255		magenta
255   0 255		magenta1
238   0 238		magenta2
205   0 205		magenta3
139   0 139		magenta4







>







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
162 181 205		lightSteelBlue3
110 123 139		lightSteelBlue4
255 255 224		lightYellow
255 255 224		lightYellow1
238 238 209		lightYellow2
205 205 180		lightYellow3
139 139 122		lightYellow4
  0 255   0		lime
 50 205  50		limeGreen
250 240 230		linen
255   0 255		magenta
255   0 255		magenta1
238   0 238		magenta2
205   0 205		magenta3
139   0 139		magenta4
486
487
488
489
490
491
492

493
494
495
496
497
498
499
255 222 173		navajoWhite1
238 207 161		navajoWhite2
205 179 139		navajoWhite3
139 121  94		navajoWhite4
  0   0 128		navy
  0   0 128		navyBlue
253 245 230		oldLace

107 142  35		oliveDrab
192 255  62		oliveDrab1
179 238  58		oliveDrab2
154 205  50		oliveDrab3
105 139  34		oliveDrab4
255 165   0		orange
255 165   0		orange1







>







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
255 222 173		navajoWhite1
238 207 161		navajoWhite2
205 179 139		navajoWhite3
139 121  94		navajoWhite4
  0   0 128		navy
  0   0 128		navyBlue
253 245 230		oldLace
128 128   0		olive
107 142  35		oliveDrab
192 255  62		oliveDrab1
179 238  58		oliveDrab2
154 205  50		oliveDrab3
105 139  34		oliveDrab4
255 165   0		orange
255 165   0		orange1
582
583
584
585
586
587
588

589
590
591
592
593
594
595
205 197 191		seashell3
139 134 130		seashell4
160  82  45		sienna
255 130  71		sienna1
238 121  66		sienna2
205 104  57		sienna3
139  71  38		sienna4

135 206 235		skyBlue
135 206 255		skyBlue1
126 192 238		skyBlue2
108 166 205		skyBlue3
 74 112 139		skyBlue4
106  90 205		slateBlue
131 111 255		slateBlue1







>







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
205 197 191		seashell3
139 134 130		seashell4
160  82  45		sienna
255 130  71		sienna1
238 121  66		sienna2
205 104  57		sienna3
139  71  38		sienna4
192 192 192		silver
135 206 235		skyBlue
135 206 255		skyBlue1
126 192 238		skyBlue2
108 166 205		skyBlue3
 74 112 139		skyBlue4
106  90 205		slateBlue
131 111 255		slateBlue1
618
619
620
621
622
623
624

625
626
627
628
629
630
631
 79 148 205		steelBlue3
 54 100 139		steelBlue4
210 180 140		tan
255 165  79		tan1
238 154  73		tan2
205 133  63		tan3
139  90  43		tan4

216 191 216		thistle
255 225 255		thistle1
238 210 238		thistle2
205 181 205		thistle3
139 123 139		thistle4
255  99  71		tomato
255  99  71		tomato1







>







635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
 79 148 205		steelBlue3
 54 100 139		steelBlue4
210 180 140		tan
255 165  79		tan1
238 154  73		tan2
205 133  63		tan3
139  90  43		tan4
  0 128 128		teal
216 191 216		thistle
255 225 255		thistle1
238 210 238		thistle2
205 181 205		thistle3
139 123 139		thistle4
255  99  71		tomato
255  99  71		tomato1

Changes to xlib/xcolors.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include "tkInt.h"

/*
 * Index array. For each of the characters 'a'-'y', this table gives the first color
 * starting with that character in the xColors table.
 */
static const unsigned char az[] = {0, 4, 12, 19, 43, 44, 47, 57, 59, 61,
	62, 63, 86, 101, 104, 109, 120, 121, 124, 137, 141, 142, 144, 147, 148, 150};

/*
 * Define an array that defines the mapping from color names to RGB values.
 * Note that this array must be kept sorted alphabetically so that the
 * binary search used in XParseColor will succeed.
 *
 * Each color definition consists of exactly 32 characters, and starts with







|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include "tkInt.h"

/*
 * Index array. For each of the characters 'a'-'y', this table gives the first color
 * starting with that character in the xColors table.
 */
static const unsigned char az[] = {0, 5, 13, 21, 45, 46, 50, 60, 62, 65, 66,
	67, 91, 106, 109, 115, 126, 127, 130, 144, 149, 150, 152, 155, 156, 158};

/*
 * Define an array that defines the mapping from color names to RGB values.
 * Note that this array must be kept sorted alphabetically so that the
 * binary search used in XParseColor will succeed.
 *
 * Each color definition consists of exactly 32 characters, and starts with
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70

typedef char elem[32];

static const elem xColors[] = {
    /* Colors starting with 'a' */
    "liceBlue\0                   \360\370\377",
    "ntiqueWhite\0    \213\203\170\315\300\260\356\337\314\377\357\333\372\353\327\4",

    "quamarine\0      \105\213\164\146\315\252\166\356\306\177\377\324\177\377\324\4",
    "zure\0           \203\213\213\301\315\315\340\356\356\360\377\377\360\377\377\4",
    /* Colors starting with 'b' */
    "eige\0                       \365\365\334",
    "isque\0          \213\175\153\315\267\236\356\325\267\377\344\304\377\344\304\4",
    "lack\0                       \000\000\000",
    "lanchedAlmond\0              \377\353\315",
    "lue\0            \000\000\213\000\000\315\000\000\356\000\000\377\000\000\377\4",
    "lueViolet\0                  \212\053\342",
    "rown\0           \213\043\043\315\063\063\356\073\073\377\100\100\245\052\052\4",
    "urlywood\0       \213\163\125\315\252\175\356\305\221\377\323\233\336\270\207\4",
    /* Colors starting with 'c' */
    "adetBlue\0       \123\206\213\172\305\315\216\345\356\230\365\377\137\236\240\4",
    "hartreuse\0      \105\213\000\146\315\000\166\356\000\177\377\000\177\377\000\4",
    "hocolate\0       \213\105\023\315\146\035\356\166\041\377\177\044\322\151\036\4",
    "oral\0           \213\076\057\315\133\105\356\152\120\377\162\126\377\177\120\4",
    "ornflowerBlue\0              \144\225\355",
    "ornsilk\0        \213\210\170\315\310\261\356\350\315\377\370\334\377\370\334\4",

    "yan\0            \000\213\213\000\315\315\000\356\356\000\377\377\000\377\377\4",
    /* Colors starting with 'd' */
    "arkBlue\0                    \000\000\213",
    "arkCyan\0                    \000\213\213",
    "arkGoldenrod\0   \213\145\010\315\225\014\356\255\016\377\271\017\270\206\013\4",
    "arkGray\0                    \251\251\251",
    "arkGreen\0                   \000\144\000",







>


















>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

typedef char elem[32];

static const elem xColors[] = {
    /* Colors starting with 'a' */
    "liceBlue\0                   \360\370\377",
    "ntiqueWhite\0    \213\203\170\315\300\260\356\337\314\377\357\333\372\353\327\4",
    "qua\0                        \000\377\377",
    "quamarine\0      \105\213\164\146\315\252\166\356\306\177\377\324\177\377\324\4",
    "zure\0           \203\213\213\301\315\315\340\356\356\360\377\377\360\377\377\4",
    /* Colors starting with 'b' */
    "eige\0                       \365\365\334",
    "isque\0          \213\175\153\315\267\236\356\325\267\377\344\304\377\344\304\4",
    "lack\0                       \000\000\000",
    "lanchedAlmond\0              \377\353\315",
    "lue\0            \000\000\213\000\000\315\000\000\356\000\000\377\000\000\377\4",
    "lueViolet\0                  \212\053\342",
    "rown\0           \213\043\043\315\063\063\356\073\073\377\100\100\245\052\052\4",
    "urlywood\0       \213\163\125\315\252\175\356\305\221\377\323\233\336\270\207\4",
    /* Colors starting with 'c' */
    "adetBlue\0       \123\206\213\172\305\315\216\345\356\230\365\377\137\236\240\4",
    "hartreuse\0      \105\213\000\146\315\000\166\356\000\177\377\000\177\377\000\4",
    "hocolate\0       \213\105\023\315\146\035\356\166\041\377\177\044\322\151\036\4",
    "oral\0           \213\076\057\315\133\105\356\152\120\377\162\126\377\177\120\4",
    "ornflowerBlue\0              \144\225\355",
    "ornsilk\0        \213\210\170\315\310\261\356\350\315\377\370\334\377\370\334\4",
    "rimson\0                     \334\024\074",
    "yan\0            \000\213\213\000\315\315\000\356\356\000\377\377\000\377\377\4",
    /* Colors starting with 'd' */
    "arkBlue\0                    \000\000\213",
    "arkCyan\0                    \000\213\213",
    "arkGoldenrod\0   \213\145\010\315\225\014\356\255\016\377\271\017\270\206\013\4",
    "arkGray\0                    \251\251\251",
    "arkGreen\0                   \000\144\000",
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
    "odgerBlue\0      \020\116\213\030\164\315\034\206\356\036\220\377\036\220\377\4",
    /* Colors starting with 'e' */
    "\377" /* placeholder */,
    /* Colors starting with 'f' */
    "irebrick\0       \213\032\032\315\046\046\356\054\054\377\060\060\262\042\042\4",
    "loralWhite\0                 \377\372\360",
    "orestGreen\0                 \042\213\042",

    /* Colors starting with 'g' */
    "ainsboro\0                   \334\334\334",
    "hostWhite\0                  \370\370\377",
    "old\0            \213\165\000\315\255\000\356\311\000\377\327\000\377\327\000\4",
    "oldenrod\0       \213\151\024\315\233\035\356\264\042\377\301\045\332\245\040\4",
    "ray\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "ray0\0                       \000\000\000",
    "reen\0           \000\213\000\000\315\000\000\356\000\000\377\000\000\377\000\4",
    "reenYellow\0                 \255\377\057",
    "rey\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "rey0\0                       \000\000\000",
    /* Colors starting with 'h' */
    "oneydew\0        \203\213\203\301\315\301\340\356\340\360\377\360\360\377\360\4",
    "otPink\0         \213\072\142\315\140\220\356\152\247\377\156\264\377\151\264\4",
    /* Colors starting with 'i' */
    "ndianRed\0       \213\072\072\315\125\125\356\143\143\377\152\152\315\134\134\4",

    "vory\0           \213\213\203\315\315\301\356\356\340\377\377\360\377\377\360\4",
    /* Colors starting with 'j' */
    "\377" /* placeholder */,
    /* Colors starting with 'k' */
    "haki\0           \213\206\116\315\306\163\356\346\205\377\366\217\360\346\214\4",
    /* Colors starting with 'l' */
    "avender\0                    \346\346\372",







>


















>







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    "odgerBlue\0      \020\116\213\030\164\315\034\206\356\036\220\377\036\220\377\4",
    /* Colors starting with 'e' */
    "\377" /* placeholder */,
    /* Colors starting with 'f' */
    "irebrick\0       \213\032\032\315\046\046\356\054\054\377\060\060\262\042\042\4",
    "loralWhite\0                 \377\372\360",
    "orestGreen\0                 \042\213\042",
    "uchsia\0                     \377\000\377",
    /* Colors starting with 'g' */
    "ainsboro\0                   \334\334\334",
    "hostWhite\0                  \370\370\377",
    "old\0            \213\165\000\315\255\000\356\311\000\377\327\000\377\327\000\4",
    "oldenrod\0       \213\151\024\315\233\035\356\264\042\377\301\045\332\245\040\4",
    "ray\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "ray0\0                       \000\000\000",
    "reen\0           \000\213\000\000\315\000\000\356\000\000\377\000\000\377\000\4",
    "reenYellow\0                 \255\377\057",
    "rey\0\024\024\024\022\022\022\017\017\017\015\015\015\012\012\012"
	    "\010\010\010\005\005\005\003\003\003\276\276\276\10",
    "rey0\0                       \000\000\000",
    /* Colors starting with 'h' */
    "oneydew\0        \203\213\203\301\315\301\340\356\340\360\377\360\360\377\360\4",
    "otPink\0         \213\072\142\315\140\220\356\152\247\377\156\264\377\151\264\4",
    /* Colors starting with 'i' */
    "ndianRed\0       \213\072\072\315\125\125\356\143\143\377\152\152\315\134\134\4",
    "ndigo\0                      \113\000\202",
    "vory\0           \213\213\203\315\315\301\356\356\340\377\377\360\377\377\360\4",
    /* Colors starting with 'j' */
    "\377" /* placeholder */,
    /* Colors starting with 'k' */
    "haki\0           \213\206\116\315\306\163\356\346\205\377\366\217\360\346\214\4",
    /* Colors starting with 'l' */
    "avender\0                    \346\346\372",
134
135
136
137
138
139
140

141
142
143
144
145
146
147
    "ightSeaGreen\0               \040\262\252",
    "ightSkyBlue\0    \140\173\213\215\266\315\244\323\356\260\342\377\207\316\372\4",
    "ightSlateBlue\0              \204\160\377",
    "ightSlateGray\0              \167\210\231",
    "ightSlateGrey\0              \167\210\231",
    "ightSteelBlue\0  \156\173\213\242\265\315\274\322\356\312\341\377\260\304\336\4",
    "ightYellow\0     \213\213\172\315\315\264\356\356\321\377\377\340\377\377\340\4",

    "imeGreen\0                   \062\315\062",
    "inen\0                       \372\360\346",
    /* Colors starting with 'm' */
    "agenta\0         \213\000\213\315\000\315\356\000\356\377\000\377\377\000\377\4",
    "aroon\0          \213\034\142\315\051\220\356\060\247\377\064\263\260\060\140\4",
    "ediumAquamarine\0            \146\315\252",
    "ediumBlue\0                  \000\000\315",







>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    "ightSeaGreen\0               \040\262\252",
    "ightSkyBlue\0    \140\173\213\215\266\315\244\323\356\260\342\377\207\316\372\4",
    "ightSlateBlue\0              \204\160\377",
    "ightSlateGray\0              \167\210\231",
    "ightSlateGrey\0              \167\210\231",
    "ightSteelBlue\0  \156\173\213\242\265\315\274\322\356\312\341\377\260\304\336\4",
    "ightYellow\0     \213\213\172\315\315\264\356\356\321\377\377\340\377\377\340\4",
    "ime\0                        \000\377\000",
    "imeGreen\0                   \062\315\062",
    "inen\0                       \372\360\346",
    /* Colors starting with 'm' */
    "agenta\0         \213\000\213\315\000\315\356\000\356\377\000\377\377\000\377\4",
    "aroon\0          \213\034\142\315\051\220\356\060\247\377\064\263\260\060\140\4",
    "ediumAquamarine\0            \146\315\252",
    "ediumBlue\0                  \000\000\315",
158
159
160
161
162
163
164

165
166
167
168
169
170
171
    "occasin\0                    \377\344\265",
    /* Colors starting with 'n' */
    "avajoWhite\0     \213\171\136\315\263\213\356\317\241\377\336\255\377\336\255\4",
    "avy\0                        \000\000\200",
    "avyBlue\0                    \000\000\200",
    /* Colors starting with 'o' */
    "ldLace\0                     \375\365\346",

    "liveDrab\0       \151\213\042\232\315\062\263\356\072\300\377\076\153\216\043\4",
    "range\0          \213\132\000\315\205\000\356\232\000\377\245\000\377\245\000\4",
    "rangeRed\0       \213\045\000\315\067\000\356\100\000\377\105\000\377\105\000\4",
    "rchid\0          \213\107\211\315\151\311\356\172\351\377\203\372\332\160\326\4",
    /* Colors starting with 'p' */
    "aleGoldenrod\0               \356\350\252",
    "aleGreen\0       \124\213\124\174\315\174\220\356\220\232\377\232\230\373\230\4",







>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    "occasin\0                    \377\344\265",
    /* Colors starting with 'n' */
    "avajoWhite\0     \213\171\136\315\263\213\356\317\241\377\336\255\377\336\255\4",
    "avy\0                        \000\000\200",
    "avyBlue\0                    \000\000\200",
    /* Colors starting with 'o' */
    "ldLace\0                     \375\365\346",
    "live\0                       \200\200\000",
    "liveDrab\0       \151\213\042\232\315\062\263\356\072\300\377\076\153\216\043\4",
    "range\0          \213\132\000\315\205\000\356\232\000\377\245\000\377\245\000\4",
    "rangeRed\0       \213\045\000\315\067\000\356\100\000\377\105\000\377\105\000\4",
    "rchid\0          \213\107\211\315\151\311\356\172\351\377\203\372\332\160\326\4",
    /* Colors starting with 'p' */
    "aleGoldenrod\0               \356\350\252",
    "aleGreen\0       \124\213\124\174\315\174\220\356\220\232\377\232\230\373\230\4",
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
    /* Colors starting with 's' */
    "addleBrown\0                 \213\105\023",
    "almon\0          \213\114\071\315\160\124\356\202\142\377\214\151\372\200\162\4",
    "andyBrown\0                  \364\244\140",
    "eaGreen\0        \056\213\127\103\315\200\116\356\224\124\377\237\056\213\127\4",
    "eashell\0        \213\206\202\315\305\277\356\345\336\377\365\356\377\365\356\4",
    "ienna\0          \213\107\046\315\150\071\356\171\102\377\202\107\240\122\055\4",

    "kyBlue\0         \112\160\213\154\246\315\176\300\356\207\316\377\207\316\353\4",
    "lateBlue\0       \107\074\213\151\131\315\172\147\356\203\157\377\152\132\315\4",
    "lateGray\0       \154\173\213\237\266\315\271\323\356\306\342\377\160\200\220\4",
    "lateGrey\0                   \160\200\220",
    "now\0            \213\211\211\315\311\311\356\351\351\377\372\372\377\372\372\4",
    "pringGreen\0     \000\213\105\000\315\146\000\356\166\000\377\177\000\377\177\4",
    "teelBlue\0       \066\144\213\117\224\315\134\254\356\143\270\377\106\202\264\4",
    /* Colors starting with 't' */
    "an\0             \213\132\053\315\205\077\356\232\111\377\245\117\322\264\214\4",

    "histle\0         \213\173\213\315\265\315\356\322\356\377\341\377\330\277\330\4",
    "omato\0          \213\066\046\315\117\071\356\134\102\377\143\107\377\143\107\4",
    "urquoise\0       \000\206\213\000\305\315\000\345\356\000\365\377\100\340\320\4",
    /* Colors starting with 'u' */
    "\377" /* placeholder */,
    /* Colors starting with 'v' */
    "iolet\0                      \356\202\356",







>









>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    /* Colors starting with 's' */
    "addleBrown\0                 \213\105\023",
    "almon\0          \213\114\071\315\160\124\356\202\142\377\214\151\372\200\162\4",
    "andyBrown\0                  \364\244\140",
    "eaGreen\0        \056\213\127\103\315\200\116\356\224\124\377\237\056\213\127\4",
    "eashell\0        \213\206\202\315\305\277\356\345\336\377\365\356\377\365\356\4",
    "ienna\0          \213\107\046\315\150\071\356\171\102\377\202\107\240\122\055\4",
    "ilver\0                      \300\300\300",
    "kyBlue\0         \112\160\213\154\246\315\176\300\356\207\316\377\207\316\353\4",
    "lateBlue\0       \107\074\213\151\131\315\172\147\356\203\157\377\152\132\315\4",
    "lateGray\0       \154\173\213\237\266\315\271\323\356\306\342\377\160\200\220\4",
    "lateGrey\0                   \160\200\220",
    "now\0            \213\211\211\315\311\311\356\351\351\377\372\372\377\372\372\4",
    "pringGreen\0     \000\213\105\000\315\146\000\356\166\000\377\177\000\377\177\4",
    "teelBlue\0       \066\144\213\117\224\315\134\254\356\143\270\377\106\202\264\4",
    /* Colors starting with 't' */
    "an\0             \213\132\053\315\205\077\356\232\111\377\245\117\322\264\214\4",
    "eal\0                        \000\200\200",
    "histle\0         \213\173\213\315\265\315\356\322\356\377\341\377\330\277\330\4",
    "omato\0          \213\066\046\315\117\071\356\134\102\377\143\107\377\143\107\4",
    "urquoise\0       \000\206\213\000\305\315\000\345\356\000\365\377\100\340\320\4",
    /* Colors starting with 'u' */
    "\377" /* placeholder */,
    /* Colors starting with 'v' */
    "iolet\0                      \356\202\356",