summaryrefslogtreecommitdiffstats
path: root/generic/tkColor.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkColor.c')
-rw-r--r--generic/tkColor.c110
1 files changed, 73 insertions, 37 deletions
diff --git a/generic/tkColor.c b/generic/tkColor.c
index 76d0baa..9abb448 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -42,6 +42,7 @@ static Tcl_ThreadDataKey dataKey;
static void ColorInit(TkDisplay *dispPtr);
static void DupColorObjProc(Tcl_Obj *srcObjPtr,Tcl_Obj *dupObjPtr);
+static void FreeColorObj(Tcl_Obj *objPtr);
static void FreeColorObjProc(Tcl_Obj *objPtr);
static void InitColorObj(Tcl_Obj *objPtr);
@@ -51,7 +52,7 @@ static void InitColorObj(Tcl_Obj *objPtr);
* of the Tcl_Obj points to a TkColor object.
*/
-Tcl_ObjType tkColorObjType = {
+const Tcl_ObjType tkColorObjType = {
"color", /* name */
FreeColorObjProc, /* freeIntRepProc */
DupColorObjProc, /* dupIntRepProc */
@@ -111,7 +112,7 @@ Tk_AllocColorFromObj(
* longer in use. Clear the reference.
*/
- FreeColorObjProc(objPtr);
+ FreeColorObj(objPtr);
tkColPtr = NULL;
} else if ((Tk_Screen(tkwin) == tkColPtr->screen)
&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
@@ -129,14 +130,14 @@ Tk_AllocColorFromObj(
if (tkColPtr != NULL) {
TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr);
- FreeColorObjProc(objPtr);
+ FreeColorObj(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;
+ objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
return (XColor *) tkColPtr;
}
}
@@ -147,7 +148,7 @@ Tk_AllocColorFromObj(
*/
tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr));
- objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
if (tkColPtr != NULL) {
tkColPtr->objRefCount++;
}
@@ -223,11 +224,13 @@ Tk_GetColor(
if (tkColPtr == NULL) {
if (interp != NULL) {
if (*name == '#') {
- Tcl_AppendResult(interp, "invalid color name \"", name,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid color name \"%s\"", name));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL);
} else {
- Tcl_AppendResult(interp, "unknown color name \"", name,
- "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown color name \"%s\"", name));
+ Tcl_SetErrorCode(interp, "TK", "LOOKUP", "COLOR", name, NULL);
}
}
if (isNew) {
@@ -356,7 +359,7 @@ Tk_GetColorByValue(
*--------------------------------------------------------------
*/
-CONST char *
+const char *
Tk_NameOfColor(
XColor *colorPtr) /* Color whose name is desired. */
{
@@ -365,11 +368,30 @@ Tk_NameOfColor(
if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
return tkColPtr->hashPtr->key.string;
} else {
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red,
colorPtr->green, colorPtr->blue);
+
+ /*
+ * If the string has the form #RSRSTUTUVWVW (where equal letters
+ * denote equal hexdigits) then this is equivalent to #RSTUVW. Then
+ * output the shorter form.
+ */
+
+ if ((tsdPtr->rgbString[1] == tsdPtr->rgbString[3])
+ && (tsdPtr->rgbString[2] == tsdPtr->rgbString[4])
+ && (tsdPtr->rgbString[5] == tsdPtr->rgbString[7])
+ && (tsdPtr->rgbString[6] == tsdPtr->rgbString[8])
+ && (tsdPtr->rgbString[9] == tsdPtr->rgbString[11])
+ && (tsdPtr->rgbString[10] == tsdPtr->rgbString[12])) {
+ tsdPtr->rgbString[3] = tsdPtr->rgbString[5];
+ tsdPtr->rgbString[4] = tsdPtr->rgbString[6];
+ tsdPtr->rgbString[5] = tsdPtr->rgbString[9];
+ tsdPtr->rgbString[6] = tsdPtr->rgbString[10];
+ tsdPtr->rgbString[7] = '\0';
+ }
return tsdPtr->rgbString;
}
}
@@ -496,7 +518,7 @@ Tk_FreeColor(
*/
if (tkColPtr->objRefCount == 0) {
- ckfree((char *) tkColPtr);
+ ckfree(tkColPtr);
}
}
@@ -528,13 +550,13 @@ Tk_FreeColorFromObj(
Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */
{
Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr));
- FreeColorObjProc(objPtr);
+ FreeColorObj(objPtr);
}
/*
*---------------------------------------------------------------------------
*
- * FreeColorObjProc --
+ * FreeColorObjProc, FreeColorObj --
*
* 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
@@ -554,13 +576,21 @@ static void
FreeColorObjProc(
Tcl_Obj *objPtr) /* The object we are releasing. */
{
- TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
+ FreeColorObj(objPtr);
+ objPtr->typePtr = NULL;
+}
+
+static void
+FreeColorObj(
+ Tcl_Obj *objPtr) /* The object we are releasing. */
+{
+ TkColor *tkColPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (tkColPtr != NULL) {
tkColPtr->objRefCount--;
if ((tkColPtr->objRefCount == 0)
&& (tkColPtr->resourceRefCount == 0)) {
- ckfree((char *) tkColPtr);
+ ckfree(tkColPtr);
}
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
@@ -589,10 +619,10 @@ DupColorObjProc(
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;
+ TkColor *tkColPtr = srcObjPtr->internalRep.twoPtrValue.ptr1;
dupObjPtr->typePtr = srcObjPtr->typePtr;
- dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
if (tkColPtr != NULL) {
tkColPtr->objRefCount++;
@@ -639,7 +669,7 @@ Tk_GetColorFromObj(
* map. If it is, we are done.
*/
- tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1;
+ tkColPtr = objPtr->internalRep.twoPtrValue.ptr1;
if ((tkColPtr != NULL)
&& (tkColPtr->resourceRefCount > 0)
&& (Tk_Screen(tkwin) == tkColPtr->screen)
@@ -669,8 +699,8 @@ Tk_GetColorFromObj(
(tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
if ((Tk_Screen(tkwin) == tkColPtr->screen)
&& (Tk_Colormap(tkwin) == tkColPtr->colormap)) {
- FreeColorObjProc(objPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr;
+ FreeColorObj(objPtr);
+ objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr;
tkColPtr->objRefCount++;
return (XColor *) tkColPtr;
}
@@ -715,7 +745,7 @@ InitColorObj(
Tcl_GetString(objPtr);
typePtr = objPtr->typePtr;
if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
- (*typePtr->freeIntRepProc)(objPtr);
+ typePtr->freeIntRepProc(objPtr);
}
objPtr->typePtr = &tkColorObjType;
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
@@ -772,7 +802,7 @@ Tcl_Obj *
TkDebugColor(
Tk_Window tkwin, /* The window in which the color will be used
* (not currently used). */
- char *name) /* Name of the desired color. */
+ const char *name) /* Name of the desired color. */
{
Tcl_HashEntry *hashPtr;
Tcl_Obj *resultPtr;
@@ -799,30 +829,30 @@ TkDebugColor(
return resultPtr;
}
-#ifndef __WIN32__
+#ifndef _WIN32
/* This function is not necessary for Win32,
* since XParseColor already does the right thing */
#undef XParseColor
-CONST char *CONST tkWebColors[20] = {
+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,
+ /* 'g' */ "reen\0#000080800000",
/* 'h' */ NULL,
/* 'i' */ "ndigo\0#4b4b00008282",
/* 'j' */ NULL,
/* 'k' */ NULL,
/* 'l' */ "ime\0#0000ffff0000",
- /* 'm' */ NULL,
+ /* 'm' */ "aroon\0#808000000000",
/* 'n' */ NULL,
/* 'o' */ "live\0#808080800000",
- /* 'p' */ NULL,
+ /* 'p' */ "urple\0#808000008080",
/* 'q' */ NULL,
/* 'r' */ NULL,
/* 's' */ "ilver\0#c0c0c0c0c0c0",
@@ -883,25 +913,31 @@ TkParseColor(
}
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 (!((name[0] - 'G') & 0xdf) && !((name[1] - 'R') & 0xdf)
+ && !((name[2] - 'A') & 0xdb) && !((name[3] - 'Y') & 0xdf)
+ && !name[4]) {
+ name = "#808080808080";
+ goto done;
+ } else {
+ 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__ */
+#endif /* _WIN32 */
/*
* Local Variables:
* mode: c