summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--doc/GetColor.35
-rw-r--r--doc/canvas.n8
-rw-r--r--generic/tkColor.c56
-rw-r--r--generic/tkCursor.c4
-rw-r--r--generic/tkImgBmap.c4
-rw-r--r--generic/tkImgPhoto.c2
-rw-r--r--generic/tkInt.h7
-rw-r--r--generic/tkStubInit.c6
-rw-r--r--macosx/tkMacOSXColor.c2
-rw-r--r--unix/tkUnixColor.c2
-rw-r--r--unix/tkUnixCursor.c10
-rwxr-xr-xwin/configure67
-rw-r--r--win/configure.in12
-rw-r--r--win/tkWinColor.c2
-rw-r--r--win/tkWinDialog.c13
-rw-r--r--xlib/xcolors.c96
17 files changed, 262 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 994ba62..5360007 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,35 @@
-2012-02-?? Francois Vogel <fvogelnew1@free.fr>
+2012-02-28 Francois Vogel <fvogelnew1@free.fr>
- * generic/tkText.c: [Bug-3487407]: Weird text indices.
- * generic/tkTextDisp.c
- * generic/tkTextMark.c
+ * generic/tkText.c: [Bug-1630262], [Bug-1615425]: segfault
+ * generic/tkTextBTree.c when deleting lines or tagging outside of
+ * generic/tkTextDisp.c the -startline/-endline range with peer
+ * generic/tkTextMark.c text widgets.
+ * tests/text.test [Bug-3487407]: Weird text indices.
* tests/textMark.test
-2012-02-?? Francois Vogel <fvogelnew1@free.fr>
+2012-02-28 Donal K. Fellows <dkf@users.sf.net>
- * generic/tkText.c: [Bug-1630262] and [Bug-1615425]: segfault
- * generic/tkTextBTree.c when deleting lines or tagging outside of
- * generic/tkTextDisp.c the -startline/-endline range with peer
- * tests/text.test text widgets.
+ * doc/canvas.n: [Bug 3495198]: Corrected types of bitmap options.
+
+2012-02-26 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * xlib/xcolors.c: Provide fallback for _strtoi64
+ * win/configure.in: Detect whether _strtoi64 is available
+ * win/configure: (regenerated)
+
+2012-02-15 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * xlib/xcolors.c: [Bug 3486474]: Inconsistent color scaling
+ * generic/tkColor.c: new internal function TkParseColor
+ * generic/tkInt.h:
+ * generic/tk*.c: Change XParseColor() to TkParseColor() everywhere.
+
+2012-02-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * win/tkWinDialog.c (GetFileNameW): Ensure that we do not convert a
+ result list to a string inadvertently, as this causes problems with
+ Tkinter's handling of multiple filename results. Issue was reported
+ via StackOverflow: http://stackoverflow.com/q/9227859/301832
2012-01-29 Jan Nijtmans <nijtmans@users.sf.net>
diff --git a/doc/GetColor.3 b/doc/GetColor.3
index b5416af..25fe16e 100644
--- a/doc/GetColor.3
+++ b/doc/GetColor.3
@@ -87,8 +87,9 @@ to use to display the color. Each \fIR\fR, \fIG\fR, or \fIB\fR
represents a single hexadecimal digit. The four forms permit
colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values.
When fewer than 16 bits are provided for each color, they represent
-the most significant bits of the color. For example, #3a7 is the
-same as #3000a0007000.
+the most significant bits of the color, while the lower unfilled
+bits will be repeatedly replicated from the available higher bits.
+For example, #3a7 is the same as #3333aaaa7777.
.PP
\fBTk_AllocColorFromObj\fR returns a pointer to
an XColor structure; the structure indicates the exact intensities of
diff --git a/doc/canvas.n b/doc/canvas.n
index bdf1e62..9338b8d 100644
--- a/doc/canvas.n
+++ b/doc/canvas.n
@@ -1287,9 +1287,9 @@ This option defaults to \fBcenter\fR.
.TP
\fB\-background \fIcolor\fR
.TP
-\fB\-activebackground \fIbitmap\fR
+\fB\-activebackground \fIcolor\fR
.TP
-\fB\-disabledbackground \fIbitmap\fR
+\fB\-disabledbackground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 0
valued pixels in its normal, active and disabled states.
@@ -1309,9 +1309,9 @@ disabled states.
.TP
\fB\-foreground \fIcolor\fR
.TP
-\fB\-activeforeground \fIbitmap\fR
+\fB\-activeforeground \fIcolor\fR
.TP
-\fB\-disabledforeground \fIbitmap\fR
+\fB\-disabledforeground \fIcolor\fR
Specifies the color to use for each of the bitmap's
.QW 1
valued pixels in its normal, active and disabled states.
diff --git a/generic/tkColor.c b/generic/tkColor.c
index 6836c52..3705103 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -798,7 +798,61 @@ TkDebugColor(
}
return resultPtr;
}
-
+
+#ifndef __WIN32__
+/* This function is not necessary for Win32,
+ * since XParseColor already does the right thing */
+Status
+TkParseColor(
+ Display * display, /* The display */
+ Colormap map, /* Color map */
+ const char* spec, /* String to be parsed */
+ XColor * colorPtr)
+{
+ if (*spec == '#') {
+ char buf[14];
+ buf[0] = '#'; buf[13] = '\0';
+ if (!*(++spec) || !*(++spec) || !*(++spec)) {
+ /* Not at least 3 hex digits, so invalid */
+ return 0;
+ } else if (!*(++spec)) {
+ /* Exactly 3 hex digits */
+ buf[9] = buf[10] = buf[11] = buf[12] = *(--spec);
+ buf[5] = buf[6] = buf[7] = buf[8] = *(--spec);
+ buf[1] = buf[2] = buf[3] = buf[4] = *(--spec);
+ spec = buf;
+ } else if (!*(++spec) || !*(++spec)) {
+ /* Not at least 6 hex digits, so invalid */
+ return 0;
+ } else if (!*(++spec)) {
+ /* Exactly 6 hex digits */
+ buf[10] = buf[12] = *(--spec);
+ buf[9] = buf[11] = *(--spec);
+ buf[6] = buf[8] = *(--spec);
+ buf[5] = buf[7] = *(--spec);
+ buf[2] = buf[4] = *(--spec);
+ buf[1] = buf[3] = *(--spec);
+ spec = buf;
+ } else if (!*(++spec) || !*(++spec)) {
+ /* Not at least 9 hex digits, so invalid */
+ return 0;
+ } else if (!*(++spec)) {
+ /* Exactly 9 hex digits */
+ buf[11] = *(--spec);
+ buf[10] = *(--spec);
+ buf[9] = buf[12] = *(--spec);
+ buf[7] = *(--spec);
+ buf[6] = *(--spec);
+ buf[5] = buf[8] = *(--spec);
+ buf[3] = *(--spec);
+ buf[2] = *(--spec);
+ buf[1] = buf[4] = *(--spec);
+ spec = buf;
+ }
+ }
+ return XParseColor(display, map, spec, colorPtr);
+}
+#endif /* __WIN32__ */
/*
* Local Variables:
* mode: c
diff --git a/generic/tkCursor.c b/generic/tkCursor.c
index 606a349..410aea9 100644
--- a/generic/tkCursor.c
+++ b/generic/tkCursor.c
@@ -349,11 +349,11 @@ Tk_GetCursorFromData(
* add it to the database.
*/
- if (XParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
+ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", fg, "\"", NULL);
goto error;
}
- if (XParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
+ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", bg, "\"", NULL);
goto error;
}
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index 88c96d5..8598e88 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -1247,7 +1247,7 @@ ImgBmapPostscript(
if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) {
XColor color;
- XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
+ TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
return TCL_ERROR;
@@ -1269,7 +1269,7 @@ ImgBmapPostscript(
if ((masterPtr->fgUid != NULL) && (masterPtr->data != NULL)) {
XColor color;
- XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
+ TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid,
&color);
if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) {
return TCL_ERROR;
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 6075da8..ffff4fc 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -1160,7 +1160,7 @@ ImgPhotoCmd(
}
}
- if (!XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
+ if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
colorString, &color)) {
Tcl_AppendResult(interp, "can't parse color \"",
colorString, "\"", NULL);
diff --git a/generic/tkInt.h b/generic/tkInt.h
index bd40a88..b152a7a 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -1179,6 +1179,13 @@ MODULE_SCOPE void TkUnderlineCharsInContext(Display *display,
int firstByte, int lastByte);
MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
Tcl_UniChar c, struct TkFontAttributes *faPtr);
+#ifdef __WIN32__
+#define TkParseColor XParseColor
+#else
+MODULE_SCOPE Status TkParseColor (Display * display,
+ Colormap map, CONST char* spec,
+ XColor * colorPtr);
+#endif
/*
* Unsupported commands.
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index 9c154e8..170ada7 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -45,6 +45,12 @@ MODULE_SCOPE TkIntXlibStubs tkIntXlibStubs;
MODULE_SCOPE TkPlatStubs tkPlatStubs;
MODULE_SCOPE TkStubs tkStubs;
+#ifndef __WIN32__
+/* Make sure that extensions which call XParseColor through
+ * the stub table, call TkParseColor in stead. See bug #3486474 */
+# define XParseColor TkParseColor
+#endif
+
/*
* WARNING: The contents of this file is automatically generated by the
* tools/genStubs.tcl script. Any modifications to the function declarations
diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c
index b6b1d18..359c8a6 100644
--- a/macosx/tkMacOSXColor.c
+++ b/macosx/tkMacOSXColor.c
@@ -591,7 +591,7 @@ TkpGetColor(
}
}
- if (XParseColor(display, colormap, name, &color) == 0) {
+ if (TkParseColor(display, colormap, name, &color) == 0) {
return (TkColor *) NULL;
}
diff --git a/unix/tkUnixColor.c b/unix/tkUnixColor.c
index e9fdf11..d3dba23 100644
--- a/unix/tkUnixColor.c
+++ b/unix/tkUnixColor.c
@@ -166,7 +166,7 @@ TkpGetColor(
FindClosestColor(tkwin, &screen, &color);
}
} else {
- if (XParseColor(display, colormap, buf, &color) == 0) {
+ if (TkParseColor(display, colormap, buf, &color) == 0) {
return NULL;
}
if (XAllocColor(display, colormap, &color) != 0) {
diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c
index 2169d1c..1ab238e 100644
--- a/unix/tkUnixCursor.c
+++ b/unix/tkUnixCursor.c
@@ -274,7 +274,7 @@ TkGetCursorByName(
fg.red = fg.green = fg.blue = 0;
bg.red = bg.green = bg.blue = 65535;
} else {
- if (XParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) {
+ if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[1],
"\"", NULL);
goto cleanup;
@@ -282,7 +282,7 @@ TkGetCursorByName(
if (argc == 2) {
bg.red = bg.green = bg.blue = 0;
maskIndex = namePtr->shape;
- } else if (XParseColor(display, Tk_Colormap(tkwin), argv[2],
+ } else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2],
&bg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"", argv[2],
"\"", NULL);
@@ -456,7 +456,7 @@ CreateCursorFromTableOrFile(
bg.red = bg.green = bg.blue = 65535;
} else if (argc == 2) {
fgColor = argv[1];
- if (XParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
+ if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"",
fgColor, "\"", NULL);
goto cleanup;
@@ -475,12 +475,12 @@ CreateCursorFromTableOrFile(
fgColor = argv[2];
bgColor = argv[3];
}
- if (XParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
+ if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"",
fgColor, "\"", NULL);
goto cleanup;
}
- if (XParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {
+ if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) {
Tcl_AppendResult(interp, "invalid color name \"",
bgColor, "\"", NULL);
goto cleanup;
diff --git a/win/configure b/win/configure
index 70b9eca..37df097 100755
--- a/win/configure
+++ b/win/configure
@@ -4028,6 +4028,73 @@ fi
+#-------------------------------------------
+# Check for _strtoi64
+#-------------------------------------------
+
+echo "$as_me:$LINENO: checking availability of _strtoi64" >&5
+echo $ECHO_N "checking availability of _strtoi64... $ECHO_C" >&6
+if test "${tcl_have_strtoi64+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+_strtoi64(0,0,0)
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ tcl_have_strtoi64=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_have_strtoi64=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_have_strtoi64" >&5
+echo "${ECHO_T}$tcl_have_strtoi64" >&6
+if test $tcl_have_strtoi64 = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_STRTOI64 1
+_ACEOF
+
+fi
+
#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------
diff --git a/win/configure.in b/win/configure.in
index a8e1012..7570b17 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -115,6 +115,18 @@ SC_CONFIG_CFLAGS
AC_CHECK_HEADER(errno.h, , MAN2TCLFLAGS="-DNO_ERRNO_H")
AC_SUBST(MAN2TCLFLAGS)
+#-------------------------------------------
+# Check for _strtoi64
+#-------------------------------------------
+
+AC_CACHE_CHECK([availability of _strtoi64], tcl_have_strtoi64, [
+ AC_TRY_LINK([#include <stdlib.h>],
+ [_strtoi64(0,0,0)],
+ tcl_have_strtoi64=yes, tcl_have_strtoi64=no)])
+if test $tcl_have_strtoi64 = no; then
+ AC_DEFINE(NO_STRTOI64, 1, [Is _strtoi64 function available?])
+fi
+
#--------------------------------------------------------------------
# Windows XP theme engine header for Ttk
#--------------------------------------------------------------------
diff --git a/win/tkWinColor.c b/win/tkWinColor.c
index 234c736..f52f6ed 100644
--- a/win/tkWinColor.c
+++ b/win/tkWinColor.c
@@ -200,7 +200,7 @@ TkpGetColor(
if (((strncasecmp(name, "system", 6) == 0)
&& FindSystemColor(name+6, &color, &index))
- || XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
+ || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name,
&color)) {
winColPtr = (WinColor *) ckalloc(sizeof(WinColor));
winColPtr->info.color = color;
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c
index 64fca8b..55152e9 100644
--- a/win/tkWinDialog.c
+++ b/win/tkWinDialog.c
@@ -834,6 +834,11 @@ GetFileNameW(
if ((winCode != 0)
|| ((cdlgerr == FNERR_BUFFERTOOSMALL)
&& (ofn.Flags & OFN_ALLOWMULTISELECT))) {
+ int gotFilename = 0; /* Flag for tracking whether we have any
+ * filename at all. For details, see
+ * http://stackoverflow.com/q/9227859/301832
+ */
+
if (ofn.Flags & OFN_ALLOWMULTISELECT) {
/*
* The result in dynFileBuffer contains many items, separated by
@@ -870,6 +875,7 @@ GetFileNameW(
Tcl_AppendToObj(fullnameObj, "/", -1);
Tcl_AppendToObj(fullnameObj, Tcl_DStringValue(&filenameBuf),
Tcl_DStringLength(&filenameBuf));
+ gotFilename = 1;
Tcl_DStringFree(&filenameBuf);
Tcl_ListObjAppendElement(NULL, returnList, fullnameObj);
}
@@ -883,18 +889,19 @@ GetFileNameW(
Tcl_ListObjAppendElement(NULL, returnList,
Tcl_NewStringObj(Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds)));
+ gotFilename |= (Tcl_DStringLength(&ds) > 0);
}
Tcl_SetObjResult(interp, returnList);
Tcl_DStringFree(&ds);
} else {
Tcl_AppendResult(interp, ConvertExternalFilename(unicodeEncoding,
(char *) ofn.lpstrFile, &ds), NULL);
+ gotFilename = (Tcl_DStringLength(&ds) > 0);
Tcl_DStringFree(&ds);
}
result = TCL_OK;
- if ((ofn.nFilterIndex > 0) &&
- Tcl_GetCharLength(Tcl_GetObjResult(interp)) > 0 &&
- typeVariableObj && filterObj) {
+ if ((ofn.nFilterIndex > 0) && gotFilename && typeVariableObj
+ && filterObj) {
int listObjc, count;
Tcl_Obj **listObjv = NULL;
Tcl_Obj **typeInfo = NULL;
diff --git a/xlib/xcolors.c b/xlib/xcolors.c
index ad33b7b..3a48faa 100644
--- a/xlib/xcolors.c
+++ b/xlib/xcolors.c
@@ -10,14 +10,7 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <tkInt.h>
-
-/*
- * This value will be set to the number of colors in the color table
- * the first time it is needed.
- */
-
-static int numXColors = 0;
+#include "tkInt.h"
/*
* Forward declarations for functions used only in this file.
@@ -32,11 +25,11 @@ static int FindColor(const char *name, XColor *colorPtr);
*/
typedef struct {
- char *name;
+ const char *name;
unsigned char red, green, blue;
} XColorEntry;
-static XColorEntry xColors[] = {
+static const XColorEntry xColors[] = {
{ "alice blue", 240, 248, 255 },
{ "AliceBlue", 240, 248, 255 },
{ "antique white", 250, 235, 215 },
@@ -789,7 +782,6 @@ static XColorEntry xColors[] = {
{ "yellow3", 205, 205, 0 },
{ "yellow4", 139, 139, 0 },
{ "YellowGreen", 154, 205, 50 },
- { NULL, 0, 0, 0 }
};
/*
@@ -818,23 +810,11 @@ FindColor(
int l, u, r, i = 0;
/*
- * Count the number of elements in the color array if we haven't done so
- * yet.
- */
-
- if (numXColors == 0) {
- XColorEntry *ePtr;
- for (ePtr = xColors; ePtr->name != NULL; ePtr++) {
- numXColors++;
- }
- }
-
- /*
* Perform a binary search on the sorted array of colors.
*/
l = 0;
- u = numXColors - 1;
+ u = sizeof(xColors)/sizeof(xColors[0]) - 1;
while (l <= u) {
i = (l + u) / 2;
r = strcasecmp(name, xColors[i].name);
@@ -871,6 +851,35 @@ FindColor(
*----------------------------------------------------------------------
*/
+#ifdef __WIN32__
+# ifdef NO_STRTOI64
+/* This version only handles hex-strings without 0x prefix */
+static __int64
+_strtoi64(const char *spec, char **p, int base)
+{
+ __int64 result = 0;
+ char c;
+ while ((c = *spec)) {
+ if ((c >= '0') && (c <= '9')) {
+ c -= '0';
+ } else if ((c >= 'A') && (c <= 'F')) {
+ c += (10 - 'A');
+ } else if ((c >= 'a') && (c <= 'f')) {
+ c += (10 - 'a');
+ } else {
+ break;
+ }
+ result = (result << 4) + c;
+ ++spec;
+ }
+ *p = (char *) spec;
+ return result;
+}
+# endif
+#else
+# define _strtoi64 strtoll
+#endif
+
Status
XParseColor(
Display *display,
@@ -879,24 +888,33 @@ XParseColor(
XColor *colorPtr)
{
if (spec[0] == '#') {
- char fmt[16];
- int i, red, green, blue;
-
- if ((i = (int) strlen(spec+1))%3) {
- return 0;
- }
- i /= 3;
+ char *p;
+ Tcl_WideInt value = _strtoi64(++spec, &p, 16);
- sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i);
- if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) {
+ switch ((int)(p-spec)) {
+ case 3:
+ colorPtr->red = (unsigned short) (((value >> 8) & 0xf) * 0x1111);
+ colorPtr->green = (unsigned short) (((value >> 4) & 0xf) * 0x1111);
+ colorPtr->blue = (unsigned short) ((value & 0xf) * 0x1111);
+ break;
+ case 6:
+ colorPtr->red = (unsigned short) (((value >> 16) & 0xff) | ((value >> 8) & 0xff00));
+ colorPtr->green = (unsigned short) (((value >> 8) & 0xff) | (value & 0xff00));
+ colorPtr->blue = (unsigned short) ((value & 0xff) | (value << 8));
+ break;
+ case 9:
+ colorPtr->red = (unsigned short) (((value >> 32) & 0xf) | ((value >> 20) & 0xfff0));
+ colorPtr->green = (unsigned short) (((value >> 20) & 0xf) | ((value >> 8) & 0xfff0));
+ colorPtr->blue = (unsigned short) (((value >> 8) & 0xf) | (value << 4));
+ break;
+ case 12:
+ colorPtr->red = (unsigned short) (value >> 32);
+ colorPtr->green = (unsigned short) (value >> 16);
+ colorPtr->blue = (unsigned short) value;
+ break;
+ default:
return 0;
}
- colorPtr->red = (((unsigned short) red) << (4 * (4 - i)))
- | ((unsigned short) red);
- colorPtr->green = (((unsigned short) green) << (4 * (4 - i)))
- | ((unsigned short) green);
- colorPtr->blue = (((unsigned short) blue) << (4 * (4 - i)))
- | ((unsigned short) blue);
} else {
if (!FindColor(spec, colorPtr)) {
return 0;