summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2018-10-20 23:08:39 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2018-10-20 23:08:39 (GMT)
commit03880fd134adfb470ff24cf0af43d7e45ae56530 (patch)
treef4cea4f1bce37df61bf97a6c05638d35e8eb6558 /generic
parent0a018d6ac1df162044309966c31de5f0941ebf27 (diff)
parent38f526f519657d58703e013e4415a7e4788ec33f (diff)
downloadtk-03880fd134adfb470ff24cf0af43d7e45ae56530.zip
tk-03880fd134adfb470ff24cf0af43d7e45ae56530.tar.gz
tk-03880fd134adfb470ff24cf0af43d7e45ae56530.tar.bz2
merge trunk
Diffstat (limited to 'generic')
-rw-r--r--generic/ks_names.h19
-rw-r--r--generic/tk.decls78
-rw-r--r--generic/tk.h98
-rw-r--r--generic/tk3d.h4
-rw-r--r--generic/tkBind.c91
-rw-r--r--generic/tkBusy.c41
-rw-r--r--generic/tkButton.c38
-rw-r--r--generic/tkCanvPs.c10
-rw-r--r--generic/tkCanvText.c9
-rw-r--r--generic/tkCanvUtil.c8
-rw-r--r--generic/tkCanvas.c567
-rw-r--r--generic/tkClipboard.c5
-rw-r--r--generic/tkCmds.c9
-rw-r--r--generic/tkColor.c10
-rw-r--r--generic/tkColor.h4
-rw-r--r--generic/tkConfig.c124
-rw-r--r--generic/tkConsole.c20
-rw-r--r--generic/tkCursor.c10
-rw-r--r--generic/tkDecls.h174
-rw-r--r--generic/tkEntry.c189
-rw-r--r--generic/tkEntry.h15
-rw-r--r--generic/tkError.c33
-rw-r--r--generic/tkEvent.c13
-rw-r--r--generic/tkFont.c109
-rw-r--r--generic/tkFont.h10
-rw-r--r--generic/tkFrame.c53
-rw-r--r--generic/tkGC.c12
-rw-r--r--generic/tkGrab.c4
-rw-r--r--generic/tkGrid.c33
-rw-r--r--generic/tkImgBmap.c9
-rw-r--r--generic/tkImgGIF.c103
-rw-r--r--generic/tkImgListFormat.c1141
-rw-r--r--generic/tkImgPNG.c79
-rw-r--r--generic/tkImgPPM.c19
-rw-r--r--generic/tkImgPhInstance.c55
-rw-r--r--generic/tkImgPhoto.c873
-rw-r--r--generic/tkImgPhoto.h17
-rw-r--r--generic/tkInt.decls107
-rw-r--r--generic/tkInt.h79
-rw-r--r--generic/tkIntDecls.h43
-rw-r--r--generic/tkIntPlatDecls.h11
-rw-r--r--generic/tkIntXlibDecls.h149
-rw-r--r--generic/tkListbox.c95
-rw-r--r--generic/tkMain.c21
-rw-r--r--generic/tkMenu.c45
-rw-r--r--generic/tkMenu.h16
-rw-r--r--generic/tkMenuDraw.c36
-rw-r--r--generic/tkMenubutton.c21
-rw-r--r--generic/tkMessage.c25
-rw-r--r--generic/tkObj.c35
-rw-r--r--generic/tkOldConfig.c25
-rw-r--r--generic/tkOldTest.c4
-rw-r--r--generic/tkOption.c9
-rw-r--r--generic/tkPack.c21
-rw-r--r--generic/tkPanedWindow.c96
-rw-r--r--generic/tkPlace.c4
-rw-r--r--generic/tkRectOval.c102
-rw-r--r--generic/tkScale.c65
-rw-r--r--generic/tkScale.h8
-rw-r--r--generic/tkScrollbar.c31
-rw-r--r--generic/tkScrollbar.h26
-rw-r--r--generic/tkSelect.c11
-rw-r--r--generic/tkSquare.c12
-rw-r--r--generic/tkStubInit.c79
-rw-r--r--generic/tkStyle.c74
-rw-r--r--generic/tkTest.c204
-rw-r--r--generic/tkText.c670
-rw-r--r--generic/tkText.h31
-rw-r--r--generic/tkTextBTree.c23
-rw-r--r--generic/tkTextDisp.c239
-rw-r--r--generic/tkTextImage.c8
-rw-r--r--generic/tkTextIndex.c52
-rw-r--r--generic/tkTextMark.c10
-rw-r--r--generic/tkTextTag.c65
-rw-r--r--generic/tkTextWind.c10
-rw-r--r--generic/tkUndo.c52
-rw-r--r--generic/tkUndo.h4
-rw-r--r--generic/tkUtil.c120
-rw-r--r--generic/tkVisual.c22
-rw-r--r--generic/tkWindow.c347
-rw-r--r--generic/ttk/ttkBlink.c2
-rw-r--r--generic/ttk/ttkButton.c50
-rw-r--r--generic/ttk/ttkCache.c3
-rw-r--r--generic/ttk/ttkClamTheme.c22
-rw-r--r--generic/ttk/ttkClassicTheme.c34
-rw-r--r--generic/ttk/ttkDefaultTheme.c13
-rw-r--r--generic/ttk/ttkElements.c4
-rw-r--r--generic/ttk/ttkEntry.c110
-rw-r--r--generic/ttk/ttkFrame.c3
-rw-r--r--generic/ttk/ttkGenStubs.tcl965
-rw-r--r--generic/ttk/ttkImage.c39
-rw-r--r--generic/ttk/ttkInit.c5
-rw-r--r--generic/ttk/ttkLabel.c17
-rw-r--r--generic/ttk/ttkLayout.c9
-rw-r--r--generic/ttk/ttkManager.c5
-rw-r--r--generic/ttk/ttkManager.h2
-rw-r--r--generic/ttk/ttkNotebook.c95
-rw-r--r--generic/ttk/ttkPanedwindow.c7
-rw-r--r--generic/ttk/ttkProgress.c79
-rw-r--r--generic/ttk/ttkScale.c35
-rw-r--r--generic/ttk/ttkScroll.c2
-rw-r--r--generic/ttk/ttkScrollbar.c9
-rw-r--r--generic/ttk/ttkSeparator.c3
-rw-r--r--generic/ttk/ttkSquare.c30
-rw-r--r--generic/ttk/ttkState.c11
-rw-r--r--generic/ttk/ttkStubLib.c2
-rw-r--r--generic/ttk/ttkTagSet.c7
-rw-r--r--generic/ttk/ttkTheme.c21
-rw-r--r--generic/ttk/ttkTheme.h12
-rw-r--r--generic/ttk/ttkThemeInt.h4
-rw-r--r--generic/ttk/ttkTrace.c19
-rw-r--r--generic/ttk/ttkTrack.c2
-rw-r--r--generic/ttk/ttkTreeview.c24
-rw-r--r--generic/ttk/ttkWidget.c5
-rw-r--r--generic/ttk/ttkWidget.h4
115 files changed, 5659 insertions, 3188 deletions
diff --git a/generic/ks_names.h b/generic/ks_names.h
index 22d9fc5..9f49130 100644
--- a/generic/ks_names.h
+++ b/generic/ks_names.h
@@ -1,5 +1,15 @@
/*
- * This file is generated from $(INCLUDESRC)/keysymdef.h. Do not edit.
+ * This file should be maintained in sync with xlib/X11/keysymdefs.h
+ *
+ * Note that this should be done manually only, because in some cases
+ * keysymdefs.h defines the same integer for multiple keysyms, e.g.:
+ *
+ * #define XK_Greek_LAMDA 0x7cb
+ * #define XK_Greek_LAMBDA 0x7cb
+ *
+ * #define XK_Cyrillic_DZHE 0x6bf
+ * #define XK_Serbian_DZE 0x6bf (deprecated)
+ *
*/
{ "BackSpace", 0xFF08 },
{ "Tab", 0xFF09 },
@@ -920,3 +930,10 @@
{ "hebrew_shin", 0xcf9 },
{ "hebrew_taf", 0xcfa },
{ "Hebrew_switch", 0xFF7E },
+{ "XF86AudioLowerVolume", 0x1008FF11 },
+{ "XF86AudioMute", 0x1008FF12 },
+{ "XF86AudioRaiseVolume", 0x1008FF13 },
+{ "XF86AudioPlay", 0x1008FF14 },
+{ "XF86AudioStop", 0x1008FF15 },
+{ "XF86AudioPrev", 0x1008FF16 },
+{ "XF86AudioNext", 0x1008FF17 },
diff --git a/generic/tk.decls b/generic/tk.decls
index 9ceb3af..16de241 100644
--- a/generic/tk.decls
+++ b/generic/tk.decls
@@ -105,7 +105,7 @@ declare 18 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 19 {
- CONST86 char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
@@ -146,7 +146,7 @@ declare 28 {
declare 29 {
int Tk_ConfigureWidget(Tcl_Interp *interp,
Tk_Window tkwin, const Tk_ConfigSpec *specs,
- int argc, CONST84 char **argv, char *widgRec,
+ int argc, const char **argv, char *widgRec,
int flags)
}
declare 30 {
@@ -245,7 +245,7 @@ declare 54 {
void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
- CONST84_RETURN char *Tk_DisplayName(Tk_Window tkwin)
+ const char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
@@ -326,7 +326,7 @@ declare 75 {
declare 76 {
void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}
-declare 77 {
+declare 77 {deprecated {function does nothing, call can be removed}} {
void Tk_FreeXId(Display *display, XID xid)
}
declare 78 {
@@ -348,10 +348,10 @@ declare 82 {
const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
- CONST84_RETURN char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
+ const char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
- CONST84_RETURN char *Tk_GetBinding(Tcl_Interp *interp,
+ const char *Tk_GetBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable, ClientData object,
const char *eventStr)
}
@@ -404,7 +404,7 @@ declare 97 {
}
declare 98 {
ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
- const char *name, CONST86 Tk_ImageType **typePtrPtr)
+ const char *name, const Tk_ImageType **typePtrPtr)
}
declare 99 {
Tk_ItemType *Tk_GetItemTypes(void)
@@ -439,7 +439,7 @@ declare 107 {
}
declare 108 {
int Tk_GetScrollInfo(Tcl_Interp *interp,
- int argc, CONST84 char **argv, double *dblPtr, int *intPtr)
+ int argc, const char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
int Tk_GetScreenMM(Tcl_Interp *interp,
@@ -518,37 +518,37 @@ declare 129 {
void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y)
}
declare 130 {
- CONST84_RETURN char *Tk_NameOf3DBorder(Tk_3DBorder border)
+ const char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
- CONST84_RETURN char *Tk_NameOfAnchor(Tk_Anchor anchor)
+ const char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
- CONST84_RETURN char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
+ const char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
- CONST84_RETURN char *Tk_NameOfCapStyle(int cap)
+ const char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
- CONST84_RETURN char *Tk_NameOfColor(XColor *colorPtr)
+ const char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
- CONST84_RETURN char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
+ const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
- CONST84_RETURN char *Tk_NameOfFont(Tk_Font font)
+ const char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
- CONST84_RETURN char *Tk_NameOfImage(Tk_ImageMaster imageMaster)
+ const char *Tk_NameOfImage(Tk_ImageMaster imageMaster)
}
declare 138 {
- CONST84_RETURN char *Tk_NameOfJoinStyle(int join)
+ const char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
- CONST84_RETURN char *Tk_NameOfJustify(Tk_Justify justify)
+ const char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
- CONST84_RETURN char *Tk_NameOfRelief(int relief)
+ const char *Tk_NameOfRelief(int relief)
}
declare 141 {
Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
@@ -561,15 +561,15 @@ declare 142 {
}
declare 143 {
int Tk_ParseArgv(Tcl_Interp *interp,
- Tk_Window tkwin, int *argcPtr, CONST84 char **argv,
+ Tk_Window tkwin, int *argcPtr, const char **argv,
const Tk_ArgvInfo *argTable, int flags)
}
-declare 144 {
+declare 144 {deprecated {function signature changed}} {
void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height)
}
-declare 145 {
+declare 145 {deprecated {function signature changed}} {
void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
@@ -581,13 +581,13 @@ declare 146 {
declare 147 {
void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
-declare 148 {
+declare 148 {deprecated {function signature changed}} {
void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height )
}
declare 149 {
void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}
-declare 150 {
+declare 150 {deprecated {function signature changed}} {
void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
@@ -744,7 +744,7 @@ declare 194 {
void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 195 {
- void Tk_FreeConfigOptions(char *recordPtr, Tk_OptionTable optionToken,
+ void Tk_FreeConfigOptions(void *recordPtr, Tk_OptionTable optionToken,
Tk_Window tkwin)
}
declare 196 {
@@ -774,11 +774,11 @@ declare 203 {
}
declare 204 {
Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp,
- char *recordPtr, Tk_OptionTable optionTable,
+ void *recordPtr, Tk_OptionTable optionTable,
Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
- Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, char *recordPtr,
+ Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 206 {
@@ -802,7 +802,7 @@ declare 210 {
int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
- int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
+ int Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {
@@ -813,7 +813,7 @@ declare 213 {
void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
- int Tk_SetOptions(Tcl_Interp *interp, char *recordPtr,
+ int Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionTable, int objc,
Tcl_Obj *const objv[], Tk_Window tkwin,
Tk_SavedOptions *savePtr, int *maskPtr)
@@ -943,12 +943,12 @@ declare 244 {
declare 245 {
void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
-declare 246 {
+declare 246 {deprecated {function signature changed}} {
void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int compRule)
}
-declare 247 {
+declare 247 {deprecated {function signature changed}} {
void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
@@ -1001,22 +1001,22 @@ declare 260 {
}
declare 261 {
void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
- char *recordPtr, Tk_Window tkwin, int width, int height,
+ void *recordPtr, Tk_Window tkwin, int width, int height,
int inner, int *widthPtr, int *heightPtr)
}
declare 262 {
void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element,
- char *recordPtr, Tk_Window tkwin, int x, int y, int width,
+ void *recordPtr, Tk_Window tkwin, int x, int y, int width,
int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
int *heightPtr)
}
declare 263 {
int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element,
- char *recordPtr, Tk_Window tkwin)
+ void *recordPtr, Tk_Window tkwin)
}
declare 264 {
void Tk_DrawElement(Tk_Style style, Tk_StyledElement element,
- char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y,
+ void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y,
int width, int height, int state)
}
@@ -1148,6 +1148,14 @@ export {
const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
int exact)
}
+export {
+ void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
+ Tcl_Interp *interp)
+}
+export {
+ void Tk_MainExW(int argc, wchar_t **argv,
+ Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
+}
# Local Variables:
# mode: tcl
diff --git a/generic/tk.h b/generic/tk.h
index 6abb05e..6f1c98a 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -17,17 +17,10 @@
#define _TK
#include <tcl.h>
-#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6)
+#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
# error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better
#endif
-#ifndef CONST84
-# define CONST84 const
-# define CONST84_RETURN const
-#endif
-#ifndef CONST86
-# define CONST86 CONST84
-#endif
#ifndef EXTERN
# define EXTERN extern TCL_STORAGE_CLASS
#endif
@@ -59,8 +52,8 @@ extern "C" {
* and update the version numbers:
*
* library/tk.tcl (1 LOC patch)
- * unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch)
- * win/configure.in (as above)
+ * unix/configure.ac (2 LOC Major, 2 LOC minor, 1 LOC patch)
+ * win/configure.ac (as above)
* README (sections 0 and 1)
* macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC
* win/README (not patchlevel)
@@ -75,10 +68,10 @@ extern "C" {
#define TK_MAJOR_VERSION 8
#define TK_MINOR_VERSION 7
#define TK_RELEASE_LEVEL TCL_ALPHA_RELEASE
-#define TK_RELEASE_SERIAL 0
+#define TK_RELEASE_SERIAL 2
#define TK_VERSION "8.7"
-#define TK_PATCH_LEVEL "8.7a0"
+#define TK_PATCH_LEVEL "8.7a2"
/*
* A special definition used to allow this header file to be included from
@@ -105,6 +98,10 @@ extern "C" {
#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
+#else
+# ifndef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
+# endif
#endif
/*
@@ -190,13 +187,14 @@ typedef struct Tk_OptionSpec {
const char *defValue; /* Default value for option if not specified
* in command line, the option database, or
* the system. */
- int objOffset; /* Where in record to store a Tcl_Obj * that
+#if TCL_MAJOR_VERSION > 8
+ size_t objOffset; /* Where in record to store a Tcl_Obj * that
* holds the value of this option, specified
* as an offset in bytes from the start of the
* record. Use the Tk_Offset macro to generate
* values for this. -1 means don't store the
* Tcl_Obj in the record. */
- int internalOffset; /* Where in record to store the internal
+ size_t internalOffset; /* Where in record to store the internal
* representation of the value of this option,
* such as an int or XColor *. This field is
* specified as an offset in bytes from the
@@ -204,6 +202,10 @@ typedef struct Tk_OptionSpec {
* macro to generate values for it. -1 means
* don't store the internal representation in
* the record. */
+#else
+ int objOffset;
+ int internalOffset;
+#endif
int flags; /* Any combination of the values defined
* below. */
const void *clientData; /* An alternate place to put option-specific
@@ -290,7 +292,7 @@ typedef struct Tk_SavedOption {
double internalForm; /* The old value of the option, in some
* internal representation such as an int or
* (XColor *). Valid only if the field
- * optionPtr->specPtr->objOffset is < 0. The
+ * optionPtr->specPtr->objOffset is -1. The
* space must be large enough to accommodate a
* double, a long, or a pointer; right now it
* looks like a double (i.e., 8 bytes) is big
@@ -306,11 +308,15 @@ typedef struct Tk_SavedOption {
#endif
typedef struct Tk_SavedOptions {
- char *recordPtr; /* The data structure in which to restore
+ void *recordPtr; /* The data structure in which to restore
* configuration options. */
Tk_Window tkwin; /* Window associated with recordPtr; needed to
* restore certain options. */
- int numItems; /* The number of valid items in items field. */
+#if TCL_MAJOR_VERSION > 8
+ size_t numItems; /* The number of valid items in items field. */
+#else
+ int numItems;
+#endif
Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
/* Items used to hold old values. */
struct Tk_SavedOptions *nextPtr;
@@ -335,8 +341,8 @@ typedef struct Tk_SavedOptions {
#ifndef __NO_OLD_CONFIG
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
- Tk_Window tkwin, CONST84 char *value, char *widgRec, int offset);
-typedef CONST86 char *(Tk_OptionPrintProc) (ClientData clientData,
+ Tk_Window tkwin, const char *value, char *widgRec, int offset);
+typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
typedef struct Tk_CustomOption {
@@ -362,19 +368,23 @@ typedef struct Tk_ConfigSpec {
int type; /* Type of option, such as TK_CONFIG_COLOR;
* see definitions below. Last option in table
* must have type TK_CONFIG_END. */
- CONST86 char *argvName; /* Switch used to specify option in argv. NULL
+ const char *argvName; /* Switch used to specify option in argv. NULL
* means this spec is part of a group. */
Tk_Uid dbName; /* Name for option in option database. */
Tk_Uid dbClass; /* Class for option in database. */
Tk_Uid defValue; /* Default value for option if not specified
* in command line or database. */
- int offset; /* Where in widget record to store value; use
+#if TCL_MAJOR_VERSION > 8
+ size_t offset; /* Where in widget record to store value; use
* Tk_Offset macro to generate values for
* this. */
+#else
+ int offset;
+#endif
int specFlags; /* Any combination of the values defined
* below; other bits are used internally by
* tkConfig.c. */
- CONST86 Tk_CustomOption *customPtr;
+ const Tk_CustomOption *customPtr;
/* If type is TK_CONFIG_CUSTOM then this is a
* pointer to info about how to parse and
* print the option. Otherwise it is
@@ -414,7 +424,9 @@ typedef enum {
#define TK_CONFIG_COLOR_ONLY (1 << 1)
#define TK_CONFIG_MONO_ONLY (1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT (1 << 3)
-#define TK_CONFIG_OPTION_SPECIFIED (1 << 4)
+#ifndef TK_NO_DEPRECATED
+# define TK_CONFIG_OPTION_SPECIFIED (1 << 4)
+#endif /* !TK_NO_DEPRECATED */
#define TK_CONFIG_USER_BIT 0x100
#endif /* __NO_OLD_CONFIG */
@@ -423,14 +435,14 @@ typedef enum {
*/
typedef struct {
- CONST86 char *key; /* The key string that flags the option in the
+ const char *key; /* The key string that flags the option in the
* argv array. */
int type; /* Indicates option type; see below. */
char *src; /* Value to be used in setting dst; usage
* depends on type. */
char *dst; /* Address of value to be modified; usage
* depends on type. */
- CONST86 char *help; /* Documentation message describing this
+ const char *help; /* Documentation message describing this
* option. */
} Tk_ArgvInfo;
@@ -676,7 +688,7 @@ typedef struct {
* request. */
Display *display; /* Display the event was read from. */
Window event; /* Window on which event was requested. */
- Window root; /* Root window that the event occured on. */
+ Window root; /* Root window that the event occurred on. */
Window subwindow; /* Child window. */
Time time; /* Milliseconds. */
int x, y; /* Pointer x, y coordinates in event
@@ -746,9 +758,10 @@ typedef XActivateDeactivateEvent XDeactivateEvent;
(((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE)
#define Tk_ReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->reqWidth)
#define Tk_ReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->reqHeight)
-/* Tk_InternalBorderWidth is deprecated */
+#ifndef TK_NO_DEPRECATED
#define Tk_InternalBorderWidth(tkwin) \
(((Tk_FakeWin *) (tkwin))->internalBorderLeft)
+#endif /* !TK_NO_DEPRECATED */
#define Tk_InternalBorderLeft(tkwin) \
(((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
@@ -814,6 +827,9 @@ typedef struct Tk_FakeWin {
int minReqWidth;
int minReqHeight;
char *dummy20; /* geometryMaster */
+#ifdef TK_USE_INPUT_METHODS
+ int dummy21;
+#endif /* TK_USE_INPUT_METHODS */
} Tk_FakeWin;
/*
@@ -915,7 +931,7 @@ typedef enum {
} Tk_State;
typedef struct Tk_SmoothMethod {
- CONST86 char *name;
+ const char *name;
int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints,
int numSteps, XPoint xPoints[], double dblPoints[]);
void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas,
@@ -1043,14 +1059,18 @@ typedef void (Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
#ifndef __NO_OLD_CONFIG
typedef struct Tk_ItemType {
- CONST86 char *name; /* The name of this type of item, such as
+ const char *name; /* The name of this type of item, such as
* "line". */
- int itemSize; /* Total amount of space needed for item's
+#if TCL_MAJOR_VERSION > 8
+ size_t itemSize; /* Total amount of space needed for item's
* record. */
+#else
+ int itemSize;
+#endif
Tk_ItemCreateProc *createProc;
/* Procedure to create a new item of this
* type. */
- CONST86 Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
+ const Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
* this type. Used for returning configuration
* info. */
Tk_ItemConfigureProc *configProc;
@@ -1171,7 +1191,7 @@ typedef struct Tk_TSOffset {
} Tk_TSOffset;
/*
- * Bit fields in Tk_Offset->flags:
+ * Bit fields in Tk_TSOffset->flags:
*/
#define TK_OFFSET_INDEX 1
@@ -1220,8 +1240,8 @@ typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
char **argv, Tk_ImageType *typePtr, Tk_ImageMaster master,
ClientData *masterDataPtr);
#else
-typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, CONST86 char *name, int objc,
- Tcl_Obj *const objv[], CONST86 Tk_ImageType *typePtr, Tk_ImageMaster master,
+typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, int objc,
+ Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageMaster master,
ClientData *masterDataPtr);
#endif /* USE_OLD_IMAGE */
typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData masterData);
@@ -1245,7 +1265,7 @@ typedef int (Tk_ImagePostscriptProc) (ClientData clientData,
*/
struct Tk_ImageType {
- CONST86 char *name; /* Name of image type. */
+ const char *name; /* Name of image type. */
Tk_ImageCreateProc *createProc;
/* Procedure to call to create a new image of
* this type. */
@@ -1357,7 +1377,7 @@ typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format,
*/
struct Tk_PhotoImageFormat {
- CONST86 char *name; /* Name of image file format */
+ const char *name; /* Name of image file format */
Tk_ImageFileMatchProc *fileMatchProc;
/* Procedure to call to determine whether an
* image file matches this format. */
@@ -1528,7 +1548,7 @@ typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr);
typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp,
- CONST86 char *portion);
+ const char *portion);
typedef void (Tk_LostSelProc) (ClientData clientData);
typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData,
XEvent *eventPtr);
@@ -1556,12 +1576,13 @@ typedef int (Tk_SelectionProc) (ClientData clientData, int offset,
*----------------------------------------------------------------------
*
* Allow users to say that they don't want to alter their source to add extra
- * arguments to Tk_PhotoPutBlock() et al; DO NOT DEFINE THIS WHEN BUILDING TK.
+ * arguments to Tk_PhotoPutBlock() et al.
*
* This goes after the inclusion of the stubbed-decls so that the declarations
* of what is actually there can be correct.
*/
+#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
# ifdef Tk_PhotoPutBlock
# undef Tk_PhotoPutBlock
@@ -1594,6 +1615,7 @@ typedef int (Tk_SelectionProc) (ClientData clientData, int offset,
# endif
# define Tk_PhotoSetSize Tk_PhotoSetSize_Panic
#endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
+#endif /* !TK_NO_DEPRECATED */
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tk3d.h b/generic/tk3d.h
index 891e927..f574de7 100644
--- a/generic/tk3d.h
+++ b/generic/tk3d.h
@@ -28,7 +28,7 @@ typedef struct TkBorder {
* the border will be used. */
Colormap colormap; /* Colormap out of which pixels are
* allocated. */
- int resourceRefCount; /* Number of active uses of this color (each
+ TkSizeT resourceRefCount; /* Number of active uses of this color (each
* active use corresponds to a call to
* Tk_Alloc3DBorderFromObj or Tk_Get3DBorder).
* If this count is 0, then this structure is
@@ -37,7 +37,7 @@ typedef struct TkBorder {
* because there are objects referring to it.
* The structure is freed when objRefCount and
* resourceRefCount are both 0. */
- int objRefCount; /* The number of Tcl objects that reference
+ TkSizeT objRefCount; /* The number of Tcl objects that reference
* this structure. */
XColor *bgColorPtr; /* Background color (intensity between
* lightColorPtr and darkColorPtr). */
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 9cd3b7b..cc0b582 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -1260,6 +1260,16 @@ Tk_BindEvent(
}
}
+ /*
+ * Ignore event types which are not in flagArray and all zeroes there.
+ * Most notably, NoExpose events can fill the ring buffer and disturb
+ * (thus masking out) event sequences of interest.
+ */
+
+ if ((eventPtr->type >= TK_LASTEVENT) || !flagArray[eventPtr->type]) {
+ return;
+ }
+
dispPtr = ((TkWindow *) tkwin)->dispPtr;
bindInfoPtr = winPtr->mainPtr->bindInfo;
@@ -1728,9 +1738,10 @@ MatchPatterns(
}
if (psPtr->flags & PAT_NEARBY) {
XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent];
- int timeDiff;
+ long timeDiff;
- timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time;
+ timeDiff = ((long)firstPtr->xkey.time -
+ (long)eventPtr->xkey.time);
if ((firstPtr->xkey.x_root
< (eventPtr->xkey.x_root - NEARBY_PIXELS))
|| (firstPtr->xkey.x_root
@@ -1911,7 +1922,8 @@ ExpandPercents(
Tcl_DString *dsPtr) /* Dynamic string in which to append new
* command. */
{
- int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl
+ size_t spaceNeeded;
+ int cvtFlags; /* Used to substitute string as proper Tcl
* list element. */
int number, flags, length;
#define NUM_SIZE 40
@@ -2493,7 +2505,7 @@ DeleteVirtualEventTable(
* already defined, the new definition augments those that already exist.
*
* Results:
- * The return value is TCL_ERROR if an error occured while creating the
+ * The return value is TCL_ERROR if an error occurred while creating the
* virtual binding. In this case, an error message will be left in the
* interp's result. If all went well then the return value is TCL_OK.
*
@@ -2868,7 +2880,7 @@ GetAllVirtualEvents(
* Any other fields in eventPtr which are not specified by the pattern
* string or the optional arguments, are set to 0.
*
- * The event may be handled sychronously or asynchronously, depending on
+ * The event may be handled synchronously or asynchronously, depending on
* the value specified by the optional "-when" option. The default
* setting is synchronous.
*
@@ -3323,9 +3335,9 @@ HandleEventGenerate(
return TCL_ERROR;
}
if (flags & KEY_BUTTON_MOTION_CROSSING) {
- event.general.xkey.time = (Time) number;
+ event.general.xkey.time = number;
} else if (flags & PROP) {
- event.general.xproperty.time = (Time) number;
+ event.general.xproperty.time = number;
} else {
goto badopt;
}
@@ -3456,12 +3468,23 @@ HandleEventGenerate(
if ((warp != 0) && Tk_IsMapped(tkwin)) {
TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);
+ Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display,
+ event.general.xmotion.window);
+
if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
Tcl_DoWhenIdle(DoWarp, dispPtr);
dispPtr->flags |= TK_DISPLAY_IN_WARP;
}
- dispPtr->warpWindow = Tk_IdToWindow(Tk_Display(mainWin),
- event.general.xmotion.window);
+
+ if (warpWindow != dispPtr->warpWindow) {
+ if (warpWindow) {
+ Tcl_Preserve(warpWindow);
+ }
+ if (dispPtr->warpWindow) {
+ Tcl_Release(dispPtr->warpWindow);
+ }
+ dispPtr->warpWindow = warpWindow;
+ }
dispPtr->warpMainwin = mainWin;
dispPtr->warpX = event.general.xmotion.x;
dispPtr->warpY = event.general.xmotion.y;
@@ -3535,8 +3558,25 @@ DoWarp(
{
TkDisplay *dispPtr = clientData;
- TkpWarpPointer(dispPtr);
- XForceScreenSaver(dispPtr->display, ScreenSaverReset);
+ /*
+ * DoWarp was scheduled only if the window was mapped. It needs to be
+ * still mapped at the time the present idle callback is executed. Also
+ * one needs to guard against window destruction in the meantime.
+ * Finally, the case warpWindow == NULL is special in that it means
+ * the whole screen.
+ */
+
+ if ((dispPtr->warpWindow == NULL) ||
+ (Tk_IsMapped(dispPtr->warpWindow)
+ && (Tk_WindowId(dispPtr->warpWindow) != None))) {
+ TkpWarpPointer(dispPtr);
+ XForceScreenSaver(dispPtr->display, ScreenSaverReset);
+ }
+
+ if (dispPtr->warpWindow) {
+ Tcl_Release(dispPtr->warpWindow);
+ dispPtr->warpWindow = None;
+ }
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
@@ -3937,7 +3977,7 @@ ParseEventDescription(
p = GetField(p, field, FIELD_SIZE);
}
if (*field != '\0') {
- if ((*field >= '1') && (*field <= '5') && (field[1] == '\0')) {
+ if ((*field >= '1') && (*field <= '9') && (field[1] == '\0')) {
if (eventFlags == 0) {
patPtr->eventType = ButtonPress;
eventMask = ButtonPressMask;
@@ -4278,6 +4318,33 @@ TkpGetBindingXEvent(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TkpCancelWarp --
+ *
+ * This function cancels an outstanding pointer warp and
+ * is called during tear down of the display.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpCancelWarp(
+ TkDisplay *dispPtr)
+{
+ if (dispPtr->flags & TK_DISPLAY_IN_WARP) {
+ Tcl_CancelIdleCall(DoWarp, dispPtr);
+ dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
+ }
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tkBusy.c b/generic/tkBusy.c
index 65248a2..8b8db66 100644
--- a/generic/tkBusy.c
+++ b/generic/tkBusy.c
@@ -17,16 +17,14 @@
#include "default.h"
/*
- * Things about the busy system that may be configured. Note that currently on
- * OSX/Aqua, that's nothing at all.
+ * Things about the busy system that may be configured. Note that on some
+ * platforms this may or may not have an effect.
*/
static const Tk_OptionSpec busyOptionSpecs[] = {
-#ifndef MAC_OSX_TK
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor),
TK_OPTION_NULL_OK, 0, 0},
-#endif
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};
@@ -433,6 +431,10 @@ MakeTransparentWindowExist(
TkpMakeTransparentWindowExist(tkwin, parent);
+ if (winPtr->window == None) {
+ return; /* Platform didn't make Window. */
+ }
+
dispPtr = winPtr->dispPtr;
hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *) winPtr->window,
&notUsed);
@@ -569,7 +571,7 @@ CreateBusy(
busyPtr->cursor = None;
Tk_SetClass(tkBusy, "Busy");
busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
- if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable,
+ if (Tk_InitOptions(interp, busyPtr, busyPtr->optionTable,
tkBusy) != TCL_OK) {
Tk_DestroyWindow(tkBusy);
return NULL;
@@ -636,7 +638,7 @@ ConfigureBusy(
{
Tk_Cursor oldCursor = busyPtr->cursor;
- if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc,
+ if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
@@ -759,6 +761,9 @@ HoldBusy(
} else {
TkpHideBusyWindow(busyPtr);
}
+ if (result == TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
+ }
return result;
}
@@ -792,11 +797,12 @@ Tk_BusyObjCmd(
Tcl_Obj *objPtr;
int index, result = TCL_OK;
static const char *const optionStrings[] = {
- "cget", "configure", "current", "forget", "hold", "status", NULL
+ "busywindow", "cget", "configure", "current", "forget", "hold",
+ "status", NULL
};
enum options {
- BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD,
- BUSY_STATUS
+ BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET,
+ BUSY_HOLD, BUSY_STATUS
};
if (objc < 2) {
@@ -821,6 +827,19 @@ Tk_BusyObjCmd(
return TCL_ERROR;
}
switch ((enum options) index) {
+ case BUSY_BUSYWINDOW:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "window");
+ return TCL_ERROR;
+ }
+ busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
+ if (busyPtr == NULL) {
+ Tcl_ResetResult(interp);
+ return TCL_OK;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
+ return TCL_OK;
+
case BUSY_CGET:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "window option");
@@ -831,7 +850,7 @@ Tk_BusyObjCmd(
return TCL_ERROR;
}
Tcl_Preserve(busyPtr);
- objPtr = Tk_GetOptionValue(interp, (char *) busyPtr,
+ objPtr = Tk_GetOptionValue(interp, busyPtr,
busyPtr->optionTable, objv[3], busyPtr->tkBusy);
if (objPtr == NULL) {
result = TCL_ERROR;
@@ -852,7 +871,7 @@ Tk_BusyObjCmd(
}
Tcl_Preserve(busyPtr);
if (objc <= 4) {
- objPtr = Tk_GetOptionInfo(interp, (char *) busyPtr,
+ objPtr = Tk_GetOptionInfo(interp, busyPtr,
busyPtr->optionTable, (objc == 4) ? objv[3] : NULL,
busyPtr->tkBusy);
if (objPtr == NULL) {
diff --git a/generic/tkButton.c b/generic/tkButton.c
index b7e314e..ddc267d 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -749,7 +749,7 @@ ButtonCreate(
ExposureMask|StructureNotifyMask|FocusChangeMask,
ButtonEventProc, butPtr);
- if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin)
+ if (Tk_InitOptions(interp, butPtr, optionTable, tkwin)
!= TCL_OK) {
Tk_DestroyWindow(butPtr->tkwin);
return TCL_ERROR;
@@ -810,7 +810,7 @@ ButtonWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "cget option");
goto error;
}
- objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
+ objPtr = Tk_GetOptionValue(interp, butPtr,
butPtr->optionTable, objv[2], butPtr->tkwin);
if (objPtr == NULL) {
goto error;
@@ -820,7 +820,7 @@ ButtonWidgetObjCmd(
case COMMAND_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
+ objPtr = Tk_GetOptionInfo(interp, butPtr,
butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
butPtr->tkwin);
if (objPtr == NULL) {
@@ -1068,7 +1068,7 @@ ConfigureButton(
* First pass: set options to new values.
*/
- if (Tk_SetOptions(interp, (char *) butPtr,
+ if (Tk_SetOptions(interp, butPtr,
butPtr->optionTable, objc, objv,
butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
@@ -1611,6 +1611,19 @@ ButtonVarProc(
Tcl_Obj *valuePtr;
/*
+ * See ticket [5d991b82].
+ */
+
+ if (butPtr->selVarNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ButtonVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is being unset, then just re-establish the trace unless
* the whole interpreter is going away.
*/
@@ -1692,8 +1705,8 @@ static char *
ButtonTextVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
TkButton *butPtr = clientData;
@@ -1704,6 +1717,19 @@ ButtonTextVarProc(
}
/*
+ * See ticket [5d991b82].
+ */
+
+ if (butPtr->textVarNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ButtonTextVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c
index c6470dd..609901b 100644
--- a/generic/tkCanvPs.c
+++ b/generic/tkCanvPs.c
@@ -491,7 +491,7 @@ TkCanvPostscriptCmd(
Tcl_AppendObjToObj(psObj, preambleObj);
if (psInfo.chan != NULL) {
- if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
+ if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
channelWriteFailed:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"problem writing postscript data to channel: %s",
@@ -545,7 +545,7 @@ TkCanvPostscriptCmd(
psInfo.x, Tk_PostscriptY((double)psInfo.y2,
(Tk_PostscriptInfo)psInfoPtr));
if (psInfo.chan != NULL) {
- if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
+ if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
goto channelWriteFailed;
}
Tcl_DecrRefCount(psObj);
@@ -587,7 +587,7 @@ TkCanvPostscriptCmd(
Tcl_AppendToObj(psObj, "grestore\n", -1);
if (psInfo.chan != NULL) {
- if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
+ if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
goto channelWriteFailed;
}
Tcl_DecrRefCount(psObj);
@@ -608,7 +608,7 @@ TkCanvPostscriptCmd(
"%%EOF\n", -1);
if (psInfo.chan != NULL) {
- if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
+ if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
goto channelWriteFailed;
}
}
@@ -825,7 +825,7 @@ Tk_PostscriptFont(
fontname = Tcl_DStringValue(&ds);
Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp),
"/%s findfont %d scalefont%s setfont\n",
- fontname, TkFontGetPoints(psInfoPtr->tkwin, points),
+ fontname, (int)(TkFontGetPoints(psInfoPtr->tkwin, points) + 0.5),
strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : "");
Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i);
Tcl_DStringFree(&ds);
diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c
index eb8dfe3..7c088b5 100644
--- a/generic/tkCanvText.c
+++ b/generic/tkCanvText.c
@@ -1006,12 +1006,13 @@ TextInsert(
Tcl_Obj *obj) /* New characters to be inserted. */
{
TextItem *textPtr = (TextItem *) itemPtr;
- int byteIndex, byteCount, charsAdded;
+ int byteIndex, charsAdded;
+ size_t byteCount;
char *newStr, *text;
const char *string;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
- string = Tcl_GetStringFromObj(obj, &byteCount);
+ string = TkGetStringFromObj(obj, &byteCount);
text = textPtr->text;
@@ -1343,11 +1344,11 @@ GetTextIndex(
* index. */
{
TextItem *textPtr = (TextItem *) itemPtr;
- int length;
+ size_t length;
int c;
TkCanvas *canvasPtr = (TkCanvas *) canvas;
Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
- const char *string = Tcl_GetStringFromObj(obj, &length);
+ const char *string = TkGetStringFromObj(obj, &length);
c = string[0];
diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c
index cbbc2b4..09ce98c 100644
--- a/generic/tkCanvUtil.c
+++ b/generic/tkCanvUtil.c
@@ -1136,7 +1136,9 @@ Tk_ConfigOutlineGC(
if (mask && (dash->number != 0)) {
gcValues->line_style = LineOnOffDash;
gcValues->dash_offset = outline->offset;
- if (dash->number > 0) {
+ if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
+ gcValues->dashes = dash->pattern.pt[0];
+ } else if (dash->number != 0) {
gcValues->dashes = dash->pattern.array[0];
} else {
gcValues->dashes = (char) (4 * width + 0.5);
@@ -1340,7 +1342,9 @@ Tk_ResetOutlineGC(
if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 &&
(dash->pattern.array[0] != dash->pattern.array[1])) ||
((dash->number == -1) && (dash->pattern.array[0] != ','))) {
- if (dash->number > 0) {
+ if ((unsigned int)ABS(dash->number) > sizeof(char *)) {
+ dashList = dash->pattern.pt[0];
+ } else if (dash->number != 0) {
dashList = dash->pattern.array[0];
} else {
dashList = (char) (4 * width + 0.5);
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index 9c4d60a..fa7559c 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -15,9 +15,9 @@
/* #define USE_OLD_TAG_SEARCH 1 */
-#include "default.h"
#include "tkInt.h"
#include "tkCanvas.h"
+#include "default.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
@@ -268,6 +268,7 @@ static int ConfigureCanvas(Tcl_Interp *interp,
TkCanvas *canvasPtr, int argc,
Tcl_Obj *const *argv, int flags);
static void DestroyCanvas(char *memPtr);
+static int DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
static void DisplayCanvas(ClientData clientData);
static void DoItem(Tcl_Obj *accumObj,
Tk_Item *itemPtr, Tk_Uid tag);
@@ -805,6 +806,7 @@ CanvasWidgetCmd(
"canvasy", "cget", "configure", "coords",
"create", "dchars", "delete", "dtag",
"find", "focus", "gettags", "icursor",
+ "image",
"imove", "index", "insert", "itemcget",
"itemconfigure",
"lower", "move", "moveto", "postscript",
@@ -817,6 +819,7 @@ CanvasWidgetCmd(
CANV_CANVASY, CANV_CGET, CANV_CONFIGURE, CANV_COORDS,
CANV_CREATE, CANV_DCHARS, CANV_DELETE, CANV_DTAG,
CANV_FIND, CANV_FOCUS, CANV_GETTAGS, CANV_ICURSOR,
+ CANV_IMAGE,
CANV_IMOVE, CANV_INDEX, CANV_INSERT, CANV_ITEMCGET,
CANV_ITEMCONFIGURE,
CANV_LOWER, CANV_MOVE, CANV_MOVETO, CANV_POSTSCRIPT,
@@ -1186,8 +1189,8 @@ CanvasWidgetCmd(
FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
int index;
- int x1,x2,y1,y2;
- int dontRedraw1,dontRedraw2;
+ int x1, x2, y1, y2;
+ int dontRedraw1, dontRedraw2;
/*
* The TK_MOVABLE_POINTS flag should only be set for types that
@@ -1217,11 +1220,11 @@ CanvasWidgetCmd(
itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
ItemDelChars(canvasPtr, itemPtr, index, index);
- dontRedraw1=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
+ dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
ItemInsert(canvasPtr, itemPtr, index, tmpObj);
- dontRedraw2=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
+ dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
if (!(dontRedraw1 && dontRedraw2)) {
Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
@@ -1249,8 +1252,7 @@ CanvasWidgetCmd(
result = TCL_ERROR;
goto done;
}
- arg = Tcl_GetString(objv[2]);
- length = objv[2]->length;
+ arg = TkGetStringFromObj(objv[2], &length);
c = arg[0];
/*
@@ -1334,7 +1336,7 @@ CanvasWidgetCmd(
}
case CANV_DCHARS: {
int first, last;
- int x1,x2,y1,y2;
+ int x1, x2, y1, y2;
if ((objc != 4) && (objc != 5)) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
@@ -1362,7 +1364,7 @@ CanvasWidgetCmd(
/*
* Redraw both item's old and new areas: it's possible that a
* delete could result in a new area larger than the old area.
- * Except if the insertProc sets the TK_ITEM_DONT_REDRAW flag,
+ * Except if the dCharsProc sets the TK_ITEM_DONT_REDRAW flag,
* nothing more needs to be done.
*/
@@ -1572,7 +1574,7 @@ CanvasWidgetCmd(
}
case CANV_INSERT: {
int beforeThis;
- int x1,x2,y1,y2;
+ int x1, x2, y1, y2;
if (objc != 5) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
@@ -1800,7 +1802,8 @@ CanvasWidgetCmd(
}
case CANV_RCHARS: {
int first, last;
- int x1,x2,y1,y2;
+ int x1, x2, y1, y2;
+ int dontRedraw1, dontRedraw2;
if (objc != 6) {
Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
@@ -1831,12 +1834,16 @@ CanvasWidgetCmd(
x1 = itemPtr->x1; y1 = itemPtr->y1;
x2 = itemPtr->x2; y2 = itemPtr->y2;
- itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
+ itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
ItemDelChars(canvasPtr, itemPtr, first, last);
+ dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
+
+ itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
ItemInsert(canvasPtr, itemPtr, first, objv[5]);
+ dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
- if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
+ if (!(dontRedraw1 && dontRedraw2)) {
Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
x1, y1, x2, y2);
EventuallyRedrawItem(canvasPtr, itemPtr);
@@ -2126,6 +2133,46 @@ CanvasWidgetCmd(
CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
break;
}
+ case CANV_IMAGE: {
+ Tk_PhotoHandle photohandle;
+ int subsample = 1, zoom = 1;
+
+ if (objc < 3 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?");
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) {
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * If we are given a subsample or a zoom then grab them.
+ */
+
+ if (objc >= 4 && Tcl_GetIntFromObj(interp, objv[3], &subsample) != TCL_OK) {
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (objc >= 5 && Tcl_GetIntFromObj(interp, objv[4], &zoom) != TCL_OK) {
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * Set the image size to zero, which allows the DrawCanvas() function
+ * to expand the image automatically when it copies the pixmap into it.
+ */
+
+ if (Tk_PhotoSetSize(interp, photohandle, 0, 0) != TCL_OK) {
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ result = DrawCanvas(interp, clientData, photohandle, subsample, zoom);
+ }
}
done:
@@ -2414,6 +2461,500 @@ CanvasWorldChanged(
/*
*----------------------------------------------------------------------
*
+ * DecomposeMaskToShiftAndBits --
+ *
+ * Given a 32 bit pixel mask, we find the position of the lowest bit and the
+ * width of the mask bits.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+* None.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+DecomposeMaskToShiftAndBits(
+ unsigned long mask, /* The pixel mask to examine */
+ int *shift, /* Where to put the shift count (position of lowest bit) */
+ int *bits) /* Where to put the bit count (width of the pixel mask) */
+{
+ int i;
+
+ *shift = 0;
+ *bits = 0;
+
+ /*
+ * Find the lowest '1' bit in the mask.
+ */
+
+ for (i = 0; i < 32; ++i) {
+ if (mask & 1 << i)
+ break;
+ }
+ if (i < 32) {
+ *shift = i;
+
+ /*
+ * Now find the next '0' bit and the width of the mask.
+ */
+
+ for ( ; i < 32; ++i) {
+ if ((mask & 1 << i) == 0)
+ break;
+ else
+ ++*bits;
+ }
+
+ /*
+ * Limit to the top 8 bits if the mask was wider than 8.
+ */
+
+ if (*bits > 8) {
+ *shift += *bits - 8;
+ *bits = 8;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawCanvas --
+ *
+ * This function draws the contents of a canvas into the given Photo image.
+ * This function is called from the widget "image" subcommand.
+ * The canvas does not need to be mapped (one of it's ancestors must be)
+ * in order for this function to work.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Canvas contents from within the -scrollregion or widget size are rendered
+ * into the Photo. Any errors are left in the result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define OVERDRAW_PIXELS 32 /* How much larger we make the pixmap
+ * that the canvas objects are drawn into */
+
+/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */
+#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)
+
+#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
+#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))
+
+static int
+DrawCanvas(
+ Tcl_Interp *interp, /* As passed to the widget command, and we will leave errors here */
+ ClientData clientData,
+ Tk_PhotoHandle photohandle, /* The photo we are rendering into */
+ int subsample, /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
+ int zoom)
+{
+ TkCanvas * canvasPtr = clientData;
+ Tk_Window tkwin;
+ Display *displayPtr;
+ Tk_PhotoImageBlock blockPtr = {0};
+ Window wid;
+ Tk_Item * itemPtr;
+ Pixmap pixmap = 0;
+ XImage *ximagePtr = NULL;
+ Visual *visualPtr;
+ GC xgc = 0;
+ XGCValues xgcValues;
+ int canvasX1, canvasY1, canvasX2, canvasY2, cWidth, cHeight,
+ pixmapX1, pixmapY1, pixmapX2, pixmapY2, pmWidth, pmHeight,
+ bitsPerPixel, bytesPerPixel, x, y, result = TCL_OK,
+ rshift, gshift, bshift, rbits, gbits, bbits;
+
+#ifdef DEBUG_DRAWCANVAS
+ char buffer[128];
+#endif
+
+ if ((tkwin = canvasPtr->tkwin) == NULL) {
+ Tcl_AppendResult(interp, "canvas tkwin is NULL!", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * If this canvas is unmapped, then we won't have a window id, so we will
+ * try the ancestors of the canvas until we find a window that has a
+ * valid window id. The Tk_GetPixmap() call requires a valid window id.
+ */
+
+ do {
+
+ if ((displayPtr = Tk_Display(tkwin)) == NULL) {
+ Tcl_AppendResult(interp, "canvas (or parent) display is NULL!", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ if ((wid = Tk_WindowId(tkwin)) != 0) {
+ continue;
+ }
+
+ if ((tkwin = Tk_Parent(tkwin)) == NULL) {
+ Tcl_AppendResult(interp, "canvas has no parent with a valid window id! Is the toplevel window mapped?", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ } while (wid == 0);
+
+ bitsPerPixel = Tk_Depth(tkwin);
+ visualPtr = Tk_Visual(tkwin);
+
+ if (subsample == 0) {
+ Tcl_AppendResult(interp, "subsample cannot be zero", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * Scan through the item list, registering the bounding box for all items
+ * that didn't do that for the final coordinates yet. This can be
+ * determined by the FORCE_REDRAW flag.
+ */
+
+ for (itemPtr = canvasPtr -> firstItemPtr; itemPtr != NULL;
+ itemPtr = itemPtr -> nextPtr) {
+ if (itemPtr -> redraw_flags & FORCE_REDRAW) {
+ itemPtr -> redraw_flags &= ~FORCE_REDRAW;
+ EventuallyRedrawItem(canvasPtr, itemPtr);
+ itemPtr -> redraw_flags &= ~FORCE_REDRAW;
+ }
+ }
+
+ /*
+ * The DisplayCanvas() function works out the region that needs redrawing,
+ * but we don't do this. We grab the whole scrollregion or canvas window
+ * area. If we have a defined -scrollregion we use that as the drawing
+ * region, otherwise use the canvas window height and width with an origin
+ * of 0,0.
+ */
+ if (canvasPtr->scrollX1 != 0 || canvasPtr->scrollY1 != 0 ||
+ canvasPtr->scrollX2 != 0 || canvasPtr->scrollY2 != 0) {
+
+ canvasX1 = canvasPtr->scrollX1;
+ canvasY1 = canvasPtr->scrollY1;
+ canvasX2 = canvasPtr->scrollX2;
+ canvasY2 = canvasPtr->scrollY2;
+ cWidth = canvasX2 - canvasX1 + 1;
+ cHeight = canvasY2 - canvasY1 + 1;
+
+ } else {
+
+ cWidth = Tk_Width(tkwin);
+ cHeight = Tk_Height(tkwin);
+ canvasX1 = 0;
+ canvasY1 = 0;
+ canvasX2 = canvasX1 + cWidth - 1;
+ canvasY2 = canvasY1 + cHeight - 1;
+ }
+
+ /*
+ * Allocate a pixmap to draw into. We add OVERDRAW_PIXELS in the same way
+ * that DisplayCanvas() does to avoid problems on some systems when objects
+ * are being drawn too close to the edge.
+ */
+
+ pixmapX1 = canvasX1 - OVERDRAW_PIXELS;
+ pixmapY1 = canvasY1 - OVERDRAW_PIXELS;
+ pixmapX2 = canvasX2 + OVERDRAW_PIXELS;
+ pixmapY2 = canvasY2 + OVERDRAW_PIXELS;
+ pmWidth = pixmapX2 - pixmapX1 + 1;
+ pmHeight = pixmapY2 - pixmapY1 + 1;
+ if ((pixmap = Tk_GetPixmap(displayPtr, Tk_WindowId(tkwin), pmWidth, pmHeight,
+ bitsPerPixel)) == 0) {
+ Tcl_AppendResult(interp, "failed to create drawing Pixmap", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+ /*
+ * Before we can draw the canvas objects into the pixmap it's background
+ * should be filled with canvas background colour.
+ */
+
+ xgcValues.function = GXcopy;
+ xgcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
+ xgc = XCreateGC(displayPtr, pixmap, GCFunction|GCForeground, &xgcValues);
+ XFillRectangle(displayPtr,pixmap,xgc,0,0,pmWidth,pmHeight);
+
+ /*
+ * Draw all the cavas items into the pixmap
+ */
+
+ canvasPtr->drawableXOrigin = pixmapX1;
+ canvasPtr->drawableYOrigin = pixmapY1;
+ for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
+ itemPtr = itemPtr->nextPtr) {
+ if ((itemPtr->x1 >= pixmapX2) || (itemPtr->y1 >= pixmapY2) ||
+ (itemPtr->x2 < pixmapX1) || (itemPtr->y2 < pixmapY1)) {
+ if (!AlwaysRedraw(itemPtr)) {
+ continue;
+ }
+ }
+ if (itemPtr->state == TK_STATE_HIDDEN ||
+ (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state
+ == TK_STATE_HIDDEN)) {
+ continue;
+ }
+ ItemDisplay(canvasPtr, itemPtr, pixmap, pixmapX1, pixmapY1, pmWidth,
+ pmHeight);
+ }
+
+ /*
+ * Copy the Pixmap into an ZPixmap format XImage so we can copy it across
+ * to the photo image. This seems to be the only way to get Pixmap image
+ * data out of an image. Note we have to account for the OVERDRAW_PIXELS
+ * border width.
+ */
+
+ if ((ximagePtr = XGetImage(displayPtr, pixmap, -pixmapX1, -pixmapY1, cWidth,
+ cHeight, AllPlanes, ZPixmap)) == NULL) {
+ Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+
+#ifdef DEBUG_DRAWCANVAS
+ Tcl_AppendResult(interp, "ximagePtr {", NULL);
+ sprintf(buffer,"%d",ximagePtr->width); Tcl_AppendResult(interp, " width ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->height); Tcl_AppendResult(interp, " height ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->format); Tcl_AppendResult(interp, " format ", buffer, NULL);
+ Tcl_AppendResult(interp, " ximagePtr->data", NULL);
+ if (ximagePtr->data != NULL) {
+ int ix, iy;
+
+ Tcl_AppendResult(interp, " {", NULL);
+ for (iy = 0; iy < ximagePtr->height; ++ iy) {
+ Tcl_AppendResult(interp, " {", NULL);
+ for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
+ if (ix > 0) {
+ if (ix % 4 == 0)
+ Tcl_AppendResult(interp, "-", NULL);
+ else
+ Tcl_AppendResult(interp, " ", NULL);
+ }
+ sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
+ Tcl_AppendResult(interp, buffer, NULL);
+ }
+ Tcl_AppendResult(interp, " }", NULL);
+ }
+ Tcl_AppendResult(interp, " }", NULL);
+ } else
+ sprintf(buffer," NULL");
+ sprintf(buffer,"%d",ximagePtr->byte_order); Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->bitmap_unit); Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->bitmap_pad); Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->depth); Tcl_AppendResult(interp, " depth ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->bytes_per_line); Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
+ sprintf(buffer,"%d",ximagePtr->bits_per_pixel); Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
+ sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask); Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
+ sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
+ sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask); Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
+ Tcl_AppendResult(interp, " }", NULL);
+
+ Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
+ sprintf(buffer,"0x%8.8lx",visualPtr->red_mask); Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
+ sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
+ sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask); Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
+ Tcl_AppendResult(interp, " }", NULL);
+
+#endif
+
+ /*
+ * Fill in the PhotoImageBlock structure abd allocate a block of memory
+ * for the converted image data. Note we allocate an alpha channel even
+ * though we don't use one, because this layout helps Tk_PhotoPutBlock()
+ * use memcpy() instead of the slow pixel or line copy.
+ */
+
+ blockPtr.width = cWidth;
+ blockPtr.height = cHeight;
+ blockPtr.pixelSize = 4;
+ blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;
+ blockPtr.offset[0] = 0;
+ blockPtr.offset[1] = 1;
+ blockPtr.offset[2] = 2;
+ blockPtr.offset[3] = 3;
+ blockPtr.pixelPtr = ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);
+
+ /*
+ * Now convert the image data pixel by pixel from XImage to 32bit RGBA
+ * format suitable for Tk_PhotoPutBlock().
+ */
+
+ DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
+ DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
+ DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);
+
+#ifdef DEBUG_DRAWCANVAS
+ sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
+ sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
+ sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
+ sprintf(buffer,"%d",rbits); Tcl_AppendResult(interp, " rbits ", buffer, NULL);
+ sprintf(buffer,"%d",gbits); Tcl_AppendResult(interp, " gbits ", buffer, NULL);
+ sprintf(buffer,"%d",bbits); Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
+ Tcl_AppendResult(interp, "\nConverted_image {", NULL);
+#endif
+
+ /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
+ * below to get this to work on Windows. X11 correctly sets the bitmap
+ *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
+ * respectively!
+ */
+
+ bytesPerPixel = ximagePtr->bits_per_pixel/8;
+ for (y = 0; y < blockPtr.height; ++y) {
+
+#ifdef DEBUG_DRAWCANVAS
+ Tcl_AppendResult(interp, " {", NULL);
+#endif
+
+ for(x = 0; x < blockPtr.width; ++x) {
+ unsigned long pixel = 0;
+
+ switch (ximagePtr->bits_per_pixel) {
+
+ /*
+ * Get an 8 bit pixel from the XImage.
+ */
+
+ case 8 :
+ pixel = *((unsigned char *)(ximagePtr->data + bytesPerPixel * x
+ + ximagePtr->bytes_per_line * y));
+ break;
+
+ /*
+ * Get a 16 bit pixel from the XImage, and correct the
+ * byte order as necessary.
+ */
+
+ case 16 :
+ pixel = *((unsigned short *)(ximagePtr->data + bytesPerPixel * x
+ + ximagePtr->bytes_per_line * y));
+ if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
+ || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
+ pixel = BYTE_SWAP16(pixel);
+ break;
+
+ /*
+ * Grab a 32 bit pixel from the XImage, and correct the
+ * byte order as necessary.
+ */
+
+ case 32 :
+ pixel = *((unsigned long *)(ximagePtr->data + bytesPerPixel * x
+ + ximagePtr->bytes_per_line * y));
+ if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
+ || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
+ pixel = BYTE_SWAP32(pixel);
+ break;
+ }
+
+ /*
+ * We have a pixel with the correct byte order, so pull out the
+ * colours and place them in the photo block. Perhaps we could
+ * just not bother with the alpha byte because we are using
+ * TK_PHOTO_COMPOSITE_SET later?
+ * ***Windows: We have to swap the red and blue values. The
+ * XImage storage is B - G - R - A which becomes a 32bit ARGB
+ * quad. However the visual mask is a 32bit ABGR quad. And
+ * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
+ * If the visual mask was correct there would be no need to
+ * swap anything here.
+ */
+
+#ifdef _WIN32
+#define R_OFFSET 2
+#define B_OFFSET 0
+#else
+#define R_OFFSET 0
+#define B_OFFSET 2
+#endif
+ blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =
+ (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
+ blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
+ (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
+ blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] =
+ (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
+ blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF;
+
+#ifdef DEBUG_DRAWCANVAS
+ {
+ int ix;
+ if (x > 0)
+ Tcl_AppendResult(interp, "-", NULL);
+ for (ix = 0; ix < 4; ++ix) {
+ if (ix > 0)
+ Tcl_AppendResult(interp, " ", NULL);
+ sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y
+ + blockPtr.pixelSize * x + ix]&0xFF);
+ Tcl_AppendResult(interp, buffer, NULL);
+ }
+ }
+#endif
+
+ }
+
+#ifdef DEBUG_DRAWCANVAS
+ Tcl_AppendResult(interp, " }", NULL);
+#endif
+
+ }
+
+#ifdef DEBUG_DRAWCANVAS
+ Tcl_AppendResult(interp, " }", NULL);
+#endif
+
+ /*
+ * Now put the copied pixmap into the photo.
+ * If either zoom or subsample are not 1, we use the zoom function.
+ */
+
+ if (subsample != 1 || zoom != 1) {
+ if ((result = Tk_PhotoPutZoomedBlock(interp, photohandle, &blockPtr,
+ 0, 0, cWidth * zoom / subsample, cHeight * zoom / subsample,
+ zoom, zoom, subsample, subsample, TK_PHOTO_COMPOSITE_SET))
+ != TCL_OK) {
+ goto done;
+ }
+ } else {
+ if ((result = Tk_PhotoPutBlock(interp, photohandle, &blockPtr, 0, 0,
+ cWidth, cHeight, TK_PHOTO_COMPOSITE_SET)) != TCL_OK) {
+ goto done;
+ }
+ }
+
+ /*
+ * Clean up anything we have allocated and exit.
+ */
+
+done:
+ if (blockPtr.pixelPtr)
+ ckfree(blockPtr.pixelPtr);
+ if (pixmap)
+ Tk_FreePixmap(Tk_Display(tkwin), pixmap);
+ if (ximagePtr)
+ XDestroyImage(ximagePtr);
+ if (xgc)
+ XFreeGC(displayPtr,xgc);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* DisplayCanvas --
*
* This function redraws the contents of a canvas window. It is invoked
diff --git a/generic/tkClipboard.c b/generic/tkClipboard.c
index b902625..aa6bb93 100644
--- a/generic/tkClipboard.c
+++ b/generic/tkClipboard.c
@@ -449,10 +449,11 @@ Tk_ClipboardObjCmd(
"-displayof", "-format", "-type", NULL
};
enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
- int subIndex, length;
+ int subIndex;
+ size_t length;
for (i = 2; i < objc - 1; i++) {
- string = Tcl_GetStringFromObj(objv[i], &length);
+ string = TkGetStringFromObj(objv[i], &length);
if (string[0] != '-') {
break;
}
diff --git a/generic/tkCmds.c b/generic/tkCmds.c
index 6196b17..81bb335 100644
--- a/generic/tkCmds.c
+++ b/generic/tkCmds.c
@@ -101,6 +101,7 @@ Tk_BellObjCmd(
enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE };
Tk_Window tkwin = clientData;
int i, index, nice = 0;
+ Tk_ErrorHandler handler;
if (objc > 4) {
wrongArgs:
@@ -128,11 +129,13 @@ Tk_BellObjCmd(
break;
}
}
+ handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL);
XBell(Tk_Display(tkwin), 0);
if (!nice) {
XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset);
}
XFlush(Tk_Display(tkwin));
+ Tk_DeleteErrorHandler(handler);
return TCL_OK;
}
@@ -2068,14 +2071,14 @@ TkGetDisplayOf(
* present. */
{
const char *string;
- int length;
+ size_t length;
if (objc < 1) {
return 0;
}
- string = Tcl_GetStringFromObj(objv[0], &length);
+ string = TkGetStringFromObj(objv[0], &length);
if ((length >= 2) &&
- (strncmp(string, "-displayof", (unsigned) length) == 0)) {
+ (strncmp(string, "-displayof", length) == 0)) {
if (objc < 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"value for \"-displayof\" missing", -1));
diff --git a/generic/tkColor.c b/generic/tkColor.c
index 9abb448..9d5e157 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -480,8 +480,7 @@ Tk_FreeColor(
Tcl_Panic("Tk_FreeColor called with bogus color");
}
- tkColPtr->resourceRefCount--;
- if (tkColPtr->resourceRefCount > 0) {
+ if (tkColPtr->resourceRefCount-- > 1) {
return;
}
@@ -587,8 +586,7 @@ FreeColorObj(
TkColor *tkColPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (tkColPtr != NULL) {
- tkColPtr->objRefCount--;
- if ((tkColPtr->objRefCount == 0)
+ if ((tkColPtr->objRefCount-- <= 1)
&& (tkColPtr->resourceRefCount == 0)) {
ckfree(tkColPtr);
}
@@ -820,9 +818,9 @@ TkDebugColor(
Tcl_Obj *objPtr = Tcl_NewObj();
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(tkColPtr->resourceRefCount));
+ Tcl_NewWideIntObj(tkColPtr->resourceRefCount));
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(tkColPtr->objRefCount));
+ Tcl_NewWideIntObj(tkColPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
diff --git a/generic/tkColor.h b/generic/tkColor.h
index 05ef295..d5bde9d 100644
--- a/generic/tkColor.h
+++ b/generic/tkColor.h
@@ -38,7 +38,7 @@ typedef struct TkColor {
Colormap colormap; /* Colormap from which this entry was
* allocated. */
Visual *visual; /* Visual associated with colormap. */
- int resourceRefCount; /* Number of active uses of this color (each
+ TkSizeT resourceRefCount; /* Number of active uses of this color (each
* active use corresponds to a call to
* Tk_AllocColorFromObj or Tk_GetColor). If
* this count is 0, then this TkColor
@@ -48,7 +48,7 @@ typedef struct TkColor {
* referring to it. The structure is freed
* when resourceRefCount and objRefCount are
* both 0. */
- int objRefCount; /* The number of Tcl objects that reference
+ TkSizeT objRefCount; /* The number of Tcl objects that reference
* this structure. */
int type; /* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */
Tcl_HashEntry *hashPtr; /* Pointer to hash table entry for this
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index 9c159e6..46300d3 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -91,7 +91,7 @@ typedef struct TkOption {
*/
typedef struct OptionTable {
- int refCount; /* Counts the number of uses of this table
+ size_t refCount; /* Counts the number of uses of this table
* (the number of times Tk_CreateOptionTable
* has returned it). This can be greater than
* 1 if it is shared along several option
@@ -103,7 +103,7 @@ typedef struct OptionTable {
* templates, this points to the table
* corresponding to the next template in the
* chain. */
- int numOptions; /* The number of items in the options array
+ size_t numOptions; /* The number of items in the options array
* below. */
Option options[1]; /* Information about the individual options in
* the table. This must be the last field in
@@ -115,14 +115,14 @@ typedef struct OptionTable {
* Forward declarations for functions defined later in this file:
*/
-static int DoObjConfig(Tcl_Interp *interp, char *recordPtr,
+static int DoObjConfig(Tcl_Interp *interp, void *recordPtr,
Option *optionPtr, Tcl_Obj *valuePtr,
Tk_Window tkwin, Tk_SavedOption *savePtr);
static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
- char *internalPtr, Tk_Window tkwin);
-static Tcl_Obj * GetConfigList(char *recordPtr,
+ void *internalPtr, Tk_Window tkwin);
+static Tcl_Obj * GetConfigList(void *recordPtr,
Option *optionPtr, Tk_Window tkwin);
-static Tcl_Obj * GetObjectForOption(char *recordPtr,
+static Tcl_Obj * GetObjectForOption(void *recordPtr,
Option *optionPtr, Tk_Window tkwin);
static Option * GetOption(const char *name, OptionTable *tablePtr);
static Option * GetOptionFromObj(Tcl_Interp *interp,
@@ -177,7 +177,7 @@ Tk_CreateOptionTable(
OptionTable *tablePtr;
const Tk_OptionSpec *specPtr, *specPtr2;
Option *optionPtr;
- int numOptions, i;
+ size_t numOptions, i;
ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -279,7 +279,7 @@ Tk_CreateOptionTable(
}
}
if (((specPtr->type == TK_OPTION_STRING)
- && (specPtr->internalOffset >= 0))
+ && (specPtr->internalOffset != TCL_AUTO_LENGTH))
|| (specPtr->type == TK_OPTION_COLOR)
|| (specPtr->type == TK_OPTION_FONT)
|| (specPtr->type == TK_OPTION_BITMAP)
@@ -330,10 +330,9 @@ Tk_DeleteOptionTable(
{
OptionTable *tablePtr = (OptionTable *) optionTable;
Option *optionPtr;
- int count;
+ size_t count;
- tablePtr->refCount--;
- if (tablePtr->refCount > 0) {
+ if (tablePtr->refCount-- > 1) {
return;
}
@@ -382,7 +381,7 @@ int
Tk_InitOptions(
Tcl_Interp *interp, /* Interpreter for error reporting. NULL means
* don't leave an error message. */
- char *recordPtr, /* Pointer to the record to configure. Note:
+ void *recordPtr, /* Pointer to the record to configure. Note:
* the caller should have properly initialized
* the record with NULL pointers for each
* option value. */
@@ -553,7 +552,7 @@ DoObjConfig(
Tcl_Interp *interp, /* Interpreter for error reporting. If NULL,
* then no message is left if an error
* occurs. */
- char *recordPtr, /* The record to modify to hold the new option
+ void *recordPtr, /* The record to modify to hold the new option
* value. */
Option *optionPtr, /* Pointer to information about the option. */
Tcl_Obj *valuePtr, /* New value for option. */
@@ -569,10 +568,10 @@ DoObjConfig(
* free the old value). */
{
Tcl_Obj **slotPtrPtr, *oldPtr;
- char *internalPtr; /* Points to location in record where internal
+ void *internalPtr; /* Points to location in record where internal
* representation of value should be stored,
* or NULL. */
- char *oldInternalPtr; /* Points to location in which to save old
+ void *oldInternalPtr; /* Points to location in which to save old
* internal representation of value. */
Tk_SavedOption internal; /* Used to save the old internal
* representation of the value if
@@ -585,8 +584,8 @@ DoObjConfig(
*/
specPtr = optionPtr->specPtr;
- if (specPtr->objOffset >= 0) {
- slotPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
+ if (specPtr->objOffset != TCL_AUTO_LENGTH) {
+ slotPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
oldPtr = *slotPtrPtr;
} else {
slotPtrPtr = NULL;
@@ -598,8 +597,8 @@ DoObjConfig(
* object and internal forms, if they exist.
*/
- if (specPtr->internalOffset >= 0) {
- internalPtr = recordPtr + specPtr->internalOffset;
+ if (specPtr->internalOffset != TCL_AUTO_LENGTH) {
+ internalPtr = (char *)recordPtr + specPtr->internalOffset;
} else {
internalPtr = NULL;
}
@@ -657,14 +656,14 @@ DoObjConfig(
case TK_OPTION_STRING: {
char *newStr;
const char *value;
- int length;
+ size_t length;
if (nullOK && ObjectIsEmpty(valuePtr)) {
valuePtr = NULL;
}
if (internalPtr != NULL) {
if (valuePtr != NULL) {
- value = Tcl_GetStringFromObj(valuePtr, &length);
+ value = TkGetStringFromObj(valuePtr, &length);
newStr = ckalloc(length + 1);
strcpy(newStr, value);
} else {
@@ -937,16 +936,13 @@ static int
ObjectIsEmpty(
Tcl_Obj *objPtr) /* Object to test. May be NULL. */
{
- int length;
-
if (objPtr == NULL) {
return 1;
}
- if (objPtr->bytes != NULL) {
- return (objPtr->length == 0);
+ if (objPtr->bytes == NULL) {
+ Tcl_GetString(objPtr);
}
- (void)Tcl_GetStringFromObj(objPtr, &length);
- return (length == 0);
+ return (objPtr->length == 0);
}
/*
@@ -978,7 +974,7 @@ GetOption(
Option *bestPtr, *optionPtr;
OptionTable *tablePtr2;
const char *p1, *p2;
- int count;
+ size_t count;
/*
* Search through all of the option tables in the chain to find the best
@@ -1226,7 +1222,7 @@ int
Tk_SetOptions(
Tcl_Interp *interp, /* Interpreter for error reporting. If NULL,
* then no error message is returned.*/
- char *recordPtr, /* The record to configure. */
+ void *recordPtr, /* The record to configure. */
Tk_OptionTable optionTable, /* Describes valid options. */
int objc, /* The number of elements in objv. */
Tcl_Obj *const objv[], /* Contains one or more name-value pairs. */
@@ -1344,12 +1340,12 @@ Tk_RestoreSavedOptions(
Tk_SavedOptions *savePtr) /* Holds saved option information; must have
* been passed to Tk_SetOptions. */
{
- int i;
+ size_t i;
Option *optionPtr;
Tcl_Obj *newPtr; /* New object value of option, which we
* replace with old value and free. Taken from
* record. */
- char *internalPtr; /* Points to internal value of option in
+ void *internalPtr; /* Points to internal value of option in
* record. */
const Tk_OptionSpec *specPtr;
@@ -1364,7 +1360,7 @@ Tk_RestoreSavedOptions(
ckfree(savePtr->nextPtr);
savePtr->nextPtr = NULL;
}
- for (i = savePtr->numItems - 1; i >= 0; i--) {
+ for (i = savePtr->numItems - 1; i != (size_t)-1; i--) {
optionPtr = savePtr->items[i].optionPtr;
specPtr = optionPtr->specPtr;
@@ -1373,13 +1369,13 @@ Tk_RestoreSavedOptions(
* record.
*/
- if (specPtr->objOffset >= 0) {
- newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset));
+ if (specPtr->objOffset != TCL_AUTO_LENGTH) {
+ newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
} else {
newPtr = NULL;
}
- if (specPtr->internalOffset >= 0) {
- internalPtr = savePtr->recordPtr + specPtr->internalOffset;
+ if (specPtr->internalOffset != TCL_AUTO_LENGTH) {
+ internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
} else {
internalPtr = NULL;
}
@@ -1394,11 +1390,11 @@ Tk_RestoreSavedOptions(
* Now restore the old value of the option.
*/
- if (specPtr->objOffset >= 0) {
- *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset))
+ if (specPtr->objOffset != TCL_AUTO_LENGTH) {
+ *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset))
= savePtr->items[i].valuePtr;
}
- if (specPtr->internalOffset >= 0) {
+ if (specPtr->internalOffset != TCL_AUTO_LENGTH) {
register char *ptr = (char *) &savePtr->items[i].internalForm;
CLANG_ASSERT(internalPtr);
@@ -1491,7 +1487,7 @@ Tk_FreeSavedOptions(
Tk_SavedOptions *savePtr) /* Contains options saved in a previous call
* to Tk_SetOptions. */
{
- int count;
+ size_t count;
Tk_SavedOption *savedOptionPtr;
if (savePtr->nextPtr != NULL) {
@@ -1531,7 +1527,7 @@ Tk_FreeSavedOptions(
/* ARGSUSED */
void
Tk_FreeConfigOptions(
- char *recordPtr, /* Record whose fields contain current values
+ void *recordPtr, /* Record whose fields contain current values
* for options. */
Tk_OptionTable optionTable, /* Describes legal options. */
Tk_Window tkwin) /* Window associated with recordPtr; needed
@@ -1539,9 +1535,9 @@ Tk_FreeConfigOptions(
{
OptionTable *tablePtr;
Option *optionPtr;
- int count;
+ size_t count;
Tcl_Obj **oldPtrPtr, *oldPtr;
- char *oldInternalPtr;
+ void *oldInternalPtr;
const Tk_OptionSpec *specPtr;
for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
@@ -1552,15 +1548,15 @@ Tk_FreeConfigOptions(
if (specPtr->type == TK_OPTION_SYNONYM) {
continue;
}
- if (specPtr->objOffset >= 0) {
- oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
+ if (specPtr->objOffset != TCL_AUTO_LENGTH) {
+ oldPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
oldPtr = *oldPtrPtr;
*oldPtrPtr = NULL;
} else {
oldPtr = NULL;
}
- if (specPtr->internalOffset >= 0) {
- oldInternalPtr = recordPtr + specPtr->internalOffset;
+ if (specPtr->internalOffset != TCL_AUTO_LENGTH) {
+ oldInternalPtr = (char *)recordPtr + specPtr->internalOffset;
} else {
oldInternalPtr = NULL;
}
@@ -1597,10 +1593,10 @@ FreeResources(
Option *optionPtr, /* Description of the configuration option. */
Tcl_Obj *objPtr, /* The current value of the option, specified
* as an object. */
- char *internalPtr, /* A pointer to an internal representation for
+ void *internalPtr, /* A pointer to an internal representation for
* the option's value, such as an int or
* (XColor *). Only valid if
- * optionPtr->specPtr->internalOffset >= 0. */
+ * optionPtr->specPtr->internalOffset != -1. */
Tk_Window tkwin) /* The window in which this option is used. */
{
int internalFormExists;
@@ -1611,7 +1607,7 @@ FreeResources(
* form, then use the object form.
*/
- internalFormExists = optionPtr->specPtr->internalOffset >= 0;
+ internalFormExists = optionPtr->specPtr->internalOffset != TCL_AUTO_LENGTH;
switch (optionPtr->specPtr->type) {
case TK_OPTION_STRING:
if (internalFormExists) {
@@ -1643,8 +1639,6 @@ FreeResources(
if (internalFormExists) {
Tk_FreeStyle(*((Tk_Style *) internalPtr));
*((Tk_Style *) internalPtr) = NULL;
- } else if (objPtr != NULL) {
- Tk_FreeStyleFromObj(objPtr);
}
break;
case TK_OPTION_BITMAP:
@@ -1719,7 +1713,7 @@ Tcl_Obj *
Tk_GetOptionInfo(
Tcl_Interp *interp, /* Interpreter for error reporting. If NULL,
* then no error message is created. */
- char *recordPtr, /* Record whose fields contain current values
+ void *recordPtr, /* Record whose fields contain current values
* for options. */
Tk_OptionTable optionTable, /* Describes all the legal options. */
Tcl_Obj *namePtr, /* If non-NULL, the string value selects a
@@ -1733,7 +1727,7 @@ Tk_GetOptionInfo(
Tcl_Obj *resultPtr;
OptionTable *tablePtr = (OptionTable *) optionTable;
Option *optionPtr;
- int count;
+ size_t count;
/*
* If information is only wanted for a single configuration spec, then
@@ -1787,7 +1781,7 @@ Tk_GetOptionInfo(
static Tcl_Obj *
GetConfigList(
- char *recordPtr, /* Pointer to record holding current values of
+ void *recordPtr, /* Pointer to record holding current values of
* configuration options. */
Option *optionPtr, /* Pointer to information describing a
* particular option. */
@@ -1830,8 +1824,8 @@ GetConfigList(
}
Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);
- if (optionPtr->specPtr->objOffset >= 0) {
- elementPtr = *((Tcl_Obj **) (recordPtr
+ if (optionPtr->specPtr->objOffset != TCL_AUTO_LENGTH) {
+ elementPtr = *((Tcl_Obj **) ((char *)recordPtr
+ optionPtr->specPtr->objOffset));
if (elementPtr == NULL) {
elementPtr = Tcl_NewObj();
@@ -1865,7 +1859,7 @@ GetConfigList(
static Tcl_Obj *
GetObjectForOption(
- char *recordPtr, /* Pointer to record holding current values of
+ void *recordPtr, /* Pointer to record holding current values of
* configuration options. */
Option *optionPtr, /* Pointer to information describing an option
* whose internal value is stored in
@@ -1873,10 +1867,10 @@ GetObjectForOption(
Tk_Window tkwin) /* Window corresponding to recordPtr. */
{
Tcl_Obj *objPtr;
- char *internalPtr; /* Points to internal value of option in
+ void *internalPtr; /* Points to internal value of option in
* record. */
- internalPtr = recordPtr + optionPtr->specPtr->internalOffset;
+ internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
objPtr = NULL;
switch (optionPtr->specPtr->type) {
case TK_OPTION_BOOLEAN:
@@ -2007,7 +2001,7 @@ Tk_GetOptionValue(
Tcl_Interp *interp, /* Interpreter for error reporting. If NULL
* then no messages are provided for
* errors. */
- char *recordPtr, /* Record whose fields contain current values
+ void *recordPtr, /* Record whose fields contain current values
* for options. */
Tk_OptionTable optionTable, /* Describes legal options. */
Tcl_Obj *namePtr, /* Gives the command-line name for the option
@@ -2025,8 +2019,8 @@ Tk_GetOptionValue(
if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
optionPtr = optionPtr->extra.synonymPtr;
}
- if (optionPtr->specPtr->objOffset >= 0) {
- resultPtr = *((Tcl_Obj **) (recordPtr+optionPtr->specPtr->objOffset));
+ if (optionPtr->specPtr->objOffset != TCL_AUTO_LENGTH) {
+ resultPtr = *((Tcl_Obj **) ((char *)recordPtr+optionPtr->specPtr->objOffset));
if (resultPtr == NULL) {
/*
* This option has a null value and is represented by a null
@@ -2096,9 +2090,9 @@ TkDebugConfig(
if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(tablePtr->refCount));
+ Tcl_NewWideIntObj(tablePtr->refCount));
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(tablePtr->numOptions));
+ Tcl_NewWideIntObj(tablePtr->numOptions));
Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
tablePtr->options[0].specPtr->optionName, -1));
}
diff --git a/generic/tkConsole.c b/generic/tkConsole.c
index 8bfbe9b..7a74344 100644
--- a/generic/tkConsole.c
+++ b/generic/tkConsole.c
@@ -24,7 +24,7 @@
typedef struct ConsoleInfo {
Tcl_Interp *consoleInterp; /* Interpreter displaying the console. */
Tcl_Interp *interp; /* Interpreter controlled by console. */
- int refCount;
+ size_t refCount;
} ConsoleInfo;
/*
@@ -223,7 +223,7 @@ Tk_InitConsoleChannels(
* Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
return;
}
@@ -318,7 +318,7 @@ Tk_InitConsoleChannels(
* Tk_CreateConsoleWindow --
*
* Initialize the console. This code actually creates a new application
- * and associated interpreter. This effectivly hides the implementation
+ * and associated interpreter. This effectively hides the implementation
* from the main application.
*
* Results:
@@ -344,9 +344,13 @@ Tk_CreateConsoleWindow(
/* Init an interp with Tcl and Tk */
Tcl_Interp *consoleInterp = Tcl_CreateInterp();
if (Tcl_Init(consoleInterp) != TCL_OK) {
+ Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp);
+ Tcl_SetObjResult(interp, result_obj);
goto error;
}
if (Tk_Init(consoleInterp) != TCL_OK) {
+ Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp);
+ Tcl_SetObjResult(interp, result_obj);
goto error;
}
@@ -452,7 +456,7 @@ Tk_CreateConsoleWindow(
if (mainWindow) {
Tk_DeleteEventHandler(mainWindow, StructureNotifyMask,
ConsoleEventProc, info);
- if (--info->refCount <= 0) {
+ if (info->refCount-- <= 1) {
ckfree(info);
}
}
@@ -592,7 +596,7 @@ ConsoleClose(
ConsoleInfo *info = data->info;
if (info) {
- if (--info->refCount <= 0) {
+ if (info->refCount-- <= 1) {
/*
* Assuming the Tcl_Interp * fields must already be NULL.
*/
@@ -881,7 +885,7 @@ InterpDeleteProc(
Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp);
info->consoleInterp = NULL;
}
- if (--info->refCount <= 0) {
+ if (info->refCount-- <= 1) {
ckfree(info);
}
}
@@ -912,7 +916,7 @@ ConsoleDeleteProc(
if (info->consoleInterp) {
Tcl_DeleteInterp(info->consoleInterp);
}
- if (--info->refCount <= 0) {
+ if (info->refCount-- <= 1) {
ckfree(info);
}
}
@@ -949,7 +953,7 @@ ConsoleEventProc(
Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL);
}
- if (--info->refCount <= 0) {
+ if (info->refCount-- <= 1) {
ckfree(info);
}
}
diff --git a/generic/tkCursor.c b/generic/tkCursor.c
index 6b2d5f4..e337b37 100644
--- a/generic/tkCursor.c
+++ b/generic/tkCursor.c
@@ -463,8 +463,7 @@ FreeCursor(
{
TkCursor *prevPtr;
- cursorPtr->resourceRefCount--;
- if (cursorPtr->resourceRefCount > 0) {
+ if (cursorPtr->resourceRefCount-- > 1) {
return;
}
@@ -590,8 +589,7 @@ FreeCursorObj(
TkCursor *cursorPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (cursorPtr != NULL) {
- cursorPtr->objRefCount--;
- if ((cursorPtr->objRefCount == 0)
+ if ((cursorPtr->objRefCount-- <= 1)
&& (cursorPtr->resourceRefCount == 0)) {
ckfree(cursorPtr);
}
@@ -864,9 +862,9 @@ TkDebugCursor(
for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) {
objPtr = Tcl_NewObj();
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(cursorPtr->resourceRefCount));
+ Tcl_NewWideIntObj(cursorPtr->resourceRefCount));
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(cursorPtr->objRefCount));
+ Tcl_NewWideIntObj(cursorPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
diff --git a/generic/tkDecls.h b/generic/tkDecls.h
index 64c32cd..eb3af95 100644
--- a/generic/tkDecls.h
+++ b/generic/tkDecls.h
@@ -17,6 +17,14 @@
#define TCL_STORAGE_CLASS DLLEXPORT
#endif
+#if !defined(BUILD_tk)
+# define TK_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg)
+#elif defined(TK_NO_DEPRECATED)
+# define TK_DEPRECATED(msg) MODULE_SCOPE
+#else
+# define TK_DEPRECATED(msg) EXTERN
+#endif
+
/*
* WARNING: This file is automatically generated by the tools/genStubs.tcl
* script. Any modifications to the function declarations below should be made
@@ -95,7 +103,7 @@ EXTERN int Tk_CanvasTagsParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 19 */
-EXTERN CONST86 char * Tk_CanvasTagsPrintProc(ClientData clientData,
+EXTERN const char * Tk_CanvasTagsPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 20 */
@@ -133,7 +141,7 @@ EXTERN int Tk_ConfigureValue(Tcl_Interp *interp,
/* 29 */
EXTERN int Tk_ConfigureWidget(Tcl_Interp *interp,
Tk_Window tkwin, const Tk_ConfigSpec *specs,
- int argc, CONST84 char **argv, char *widgRec,
+ int argc, const char **argv, char *widgRec,
int flags);
/* 30 */
EXTERN void Tk_ConfigureWindow(Tk_Window tkwin,
@@ -215,7 +223,7 @@ EXTERN void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
/* 54 */
EXTERN void Tk_DestroyWindow(Tk_Window tkwin);
/* 55 */
-EXTERN CONST84_RETURN char * Tk_DisplayName(Tk_Window tkwin);
+EXTERN const char * Tk_DisplayName(Tk_Window tkwin);
/* 56 */
EXTERN int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
int y);
@@ -281,7 +289,8 @@ EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap);
/* 76 */
EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout);
/* 77 */
-EXTERN void Tk_FreeXId(Display *display, XID xid);
+TK_DEPRECATED("function does nothing, call can be removed")
+void Tk_FreeXId(Display *display, XID xid);
/* 78 */
EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable);
/* 79 */
@@ -298,9 +307,9 @@ EXTERN void Tk_GetAllBindings(Tcl_Interp *interp,
EXTERN int Tk_GetAnchor(Tcl_Interp *interp, const char *str,
Tk_Anchor *anchorPtr);
/* 83 */
-EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom);
+EXTERN const char * Tk_GetAtomName(Tk_Window tkwin, Atom atom);
/* 84 */
-EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp,
+EXTERN const char * Tk_GetBinding(Tcl_Interp *interp,
Tk_BindingTable bindingTable,
ClientData object, const char *eventStr);
/* 85 */
@@ -348,7 +357,7 @@ EXTERN Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
/* 98 */
EXTERN ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
const char *name,
- CONST86 Tk_ImageType **typePtrPtr);
+ const Tk_ImageType **typePtrPtr);
/* 99 */
EXTERN Tk_ItemType * Tk_GetItemTypes(void);
/* 100 */
@@ -376,7 +385,7 @@ EXTERN void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
int *yPtr);
/* 108 */
EXTERN int Tk_GetScrollInfo(Tcl_Interp *interp, int argc,
- CONST84 char **argv, double *dblPtr,
+ const char **argv, double *dblPtr,
int *intPtr);
/* 109 */
EXTERN int Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
@@ -438,28 +447,27 @@ EXTERN void Tk_MoveWindow(Tk_Window tkwin, int x, int y);
/* 129 */
EXTERN void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y);
/* 130 */
-EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border);
+EXTERN const char * Tk_NameOf3DBorder(Tk_3DBorder border);
/* 131 */
-EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor);
+EXTERN const char * Tk_NameOfAnchor(Tk_Anchor anchor);
/* 132 */
-EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap);
+EXTERN const char * Tk_NameOfBitmap(Display *display, Pixmap bitmap);
/* 133 */
-EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap);
+EXTERN const char * Tk_NameOfCapStyle(int cap);
/* 134 */
-EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr);
+EXTERN const char * Tk_NameOfColor(XColor *colorPtr);
/* 135 */
-EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display,
- Tk_Cursor cursor);
+EXTERN const char * Tk_NameOfCursor(Display *display, Tk_Cursor cursor);
/* 136 */
-EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font);
+EXTERN const char * Tk_NameOfFont(Tk_Font font);
/* 137 */
-EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster imageMaster);
+EXTERN const char * Tk_NameOfImage(Tk_ImageMaster imageMaster);
/* 138 */
-EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join);
+EXTERN const char * Tk_NameOfJoinStyle(int join);
/* 139 */
-EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify);
+EXTERN const char * Tk_NameOfJustify(Tk_Justify justify);
/* 140 */
-EXTERN CONST84_RETURN char * Tk_NameOfRelief(int relief);
+EXTERN const char * Tk_NameOfRelief(int relief);
/* 141 */
EXTERN Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
const char *pathName, Tk_Window tkwin);
@@ -468,14 +476,16 @@ EXTERN void Tk_OwnSelection(Tk_Window tkwin, Atom selection,
Tk_LostSelProc *proc, ClientData clientData);
/* 143 */
EXTERN int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
- int *argcPtr, CONST84 char **argv,
+ int *argcPtr, const char **argv,
const Tk_ArgvInfo *argTable, int flags);
/* 144 */
-EXTERN void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height);
/* 145 */
-EXTERN void Tk_PhotoPutZoomedBlock_NoComposite(
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoPutZoomedBlock_NoComposite(
Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
@@ -486,13 +496,15 @@ EXTERN int Tk_PhotoGetImage(Tk_PhotoHandle handle,
/* 147 */
EXTERN void Tk_PhotoBlank(Tk_PhotoHandle handle);
/* 148 */
-EXTERN void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
int width, int height);
/* 149 */
EXTERN void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
int *heightPtr);
/* 150 */
-EXTERN void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
int width, int height);
/* 151 */
EXTERN int Tk_PointToChar(Tk_TextLayout layout, int x, int y);
@@ -620,7 +632,7 @@ EXTERN void Tk_FreeBitmapFromObj(Tk_Window tkwin,
/* 194 */
EXTERN void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 195 */
-EXTERN void Tk_FreeConfigOptions(char *recordPtr,
+EXTERN void Tk_FreeConfigOptions(void *recordPtr,
Tk_OptionTable optionToken, Tk_Window tkwin);
/* 196 */
EXTERN void Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);
@@ -642,12 +654,12 @@ EXTERN XColor * Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 203 */
EXTERN Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 204 */
-EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr,
+EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionTable, Tcl_Obj *namePtr,
Tk_Window tkwin);
/* 205 */
EXTERN Tcl_Obj * Tk_GetOptionValue(Tcl_Interp *interp,
- char *recordPtr, Tk_OptionTable optionTable,
+ void *recordPtr, Tk_OptionTable optionTable,
Tcl_Obj *namePtr, Tk_Window tkwin);
/* 206 */
EXTERN int Tk_GetJustifyFromObj(Tcl_Interp *interp,
@@ -667,7 +679,7 @@ EXTERN int Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[], double *dblPtr,
int *intPtr);
/* 211 */
-EXTERN int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
+EXTERN int Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionToken, Tk_Window tkwin);
/* 212 */
EXTERN void Tk_MainEx(int argc, char **argv,
@@ -676,7 +688,7 @@ EXTERN void Tk_MainEx(int argc, char **argv,
/* 213 */
EXTERN void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
/* 214 */
-EXTERN int Tk_SetOptions(Tcl_Interp *interp, char *recordPtr,
+EXTERN int Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
Tk_OptionTable optionTable, int objc,
Tcl_Obj *const objv[], Tk_Window tkwin,
Tk_SavedOptions *savePtr, int *maskPtr);
@@ -776,11 +788,13 @@ EXTERN void Tk_SetMinimumRequestSize(Tk_Window tkwin,
EXTERN void Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
int height);
/* 246 */
-EXTERN void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int compRule);
/* 247 */
-EXTERN void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
+TK_DEPRECATED("function signature changed")
+void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr, int x, int y,
int width, int height, int zoomX, int zoomY,
int subsampleX, int subsampleY, int compRule);
@@ -818,22 +832,22 @@ EXTERN Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
Tk_OptionTable optionTable);
/* 261 */
EXTERN void Tk_GetElementSize(Tk_Style style,
- Tk_StyledElement element, char *recordPtr,
+ Tk_StyledElement element, void *recordPtr,
Tk_Window tkwin, int width, int height,
int inner, int *widthPtr, int *heightPtr);
/* 262 */
EXTERN void Tk_GetElementBox(Tk_Style style,
- Tk_StyledElement element, char *recordPtr,
+ Tk_StyledElement element, void *recordPtr,
Tk_Window tkwin, int x, int y, int width,
int height, int inner, int *xPtr, int *yPtr,
int *widthPtr, int *heightPtr);
/* 263 */
EXTERN int Tk_GetElementBorderWidth(Tk_Style style,
- Tk_StyledElement element, char *recordPtr,
+ Tk_StyledElement element, void *recordPtr,
Tk_Window tkwin);
/* 264 */
EXTERN void Tk_DrawElement(Tk_Style style,
- Tk_StyledElement element, char *recordPtr,
+ Tk_StyledElement element, void *recordPtr,
Tk_Window tkwin, Drawable d, int x, int y,
int width, int height, int state);
/* 265 */
@@ -895,7 +909,7 @@ typedef struct TkStubs {
double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */
void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */
int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 18 */
- CONST86 char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */
+ const char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */
Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */
void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */
void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */
@@ -905,7 +919,7 @@ typedef struct TkStubs {
int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */
int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */
- int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */
+ int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, const char **argv, char *widgRec, int flags); /* 29 */
void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */
Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */
Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */
@@ -931,7 +945,7 @@ typedef struct TkStubs {
void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */
void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */
void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */
- CONST84_RETURN char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
+ const char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */
void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */
void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */
@@ -953,14 +967,14 @@ typedef struct TkStubs {
void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */
void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */
void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */
- void (*tk_FreeXId) (Display *display, XID xid); /* 77 */
+ TCL_DEPRECATED_API("function does nothing, call can be removed") void (*tk_FreeXId) (Display *display, XID xid); /* 77 */
GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */
void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */
Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */
void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */
int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */
- CONST84_RETURN char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
- CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */
+ const char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
+ const char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */
Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */
Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const void *source, int width, int height); /* 86 */
int (*tk_GetCapStyle) (Tcl_Interp *interp, const char *str, int *capPtr); /* 87 */
@@ -974,7 +988,7 @@ typedef struct TkStubs {
void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */
GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */
Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */
- ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, CONST86 Tk_ImageType **typePtrPtr); /* 98 */
+ ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, const Tk_ImageType **typePtrPtr); /* 98 */
Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */
int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */
int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */
@@ -984,7 +998,7 @@ typedef struct TkStubs {
Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */
int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */
void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */
- int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); /* 108 */
+ int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, const char **argv, double *dblPtr, int *intPtr); /* 108 */
int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */
int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */
Tk_Uid (*tk_GetUid) (const char *str); /* 111 */
@@ -1006,27 +1020,27 @@ typedef struct TkStubs {
void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */
void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */
void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */
- CONST84_RETURN char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
- CONST84_RETURN char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
- CONST84_RETURN char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
- CONST84_RETURN char * (*tk_NameOfCapStyle) (int cap); /* 133 */
- CONST84_RETURN char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
- CONST84_RETURN char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
- CONST84_RETURN char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
- CONST84_RETURN char * (*tk_NameOfImage) (Tk_ImageMaster imageMaster); /* 137 */
- CONST84_RETURN char * (*tk_NameOfJoinStyle) (int join); /* 138 */
- CONST84_RETURN char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
- CONST84_RETURN char * (*tk_NameOfRelief) (int relief); /* 140 */
+ const char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
+ const char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
+ const char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
+ const char * (*tk_NameOfCapStyle) (int cap); /* 133 */
+ const char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
+ const char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
+ const char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
+ const char * (*tk_NameOfImage) (Tk_ImageMaster imageMaster); /* 137 */
+ const char * (*tk_NameOfJoinStyle) (int join); /* 138 */
+ const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
+ const char * (*tk_NameOfRelief) (int relief); /* 140 */
Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */
void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */
- int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
- void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
- void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */
+ int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */
int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */
void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */
- void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
- void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */
int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */
int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */
void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */
@@ -1071,7 +1085,7 @@ typedef struct TkStubs {
void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */
void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */
void (*tk_FreeColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */
- void (*tk_FreeConfigOptions) (char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */
+ void (*tk_FreeConfigOptions) (void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */
void (*tk_FreeSavedOptions) (Tk_SavedOptions *savePtr); /* 196 */
void (*tk_FreeCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 197 */
void (*tk_FreeFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 198 */
@@ -1080,17 +1094,17 @@ typedef struct TkStubs {
Pixmap (*tk_GetBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 201 */
XColor * (*tk_GetColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 202 */
Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
- Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
- Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
+ Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
+ Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
- int (*tk_InitOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
+ int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
- int (*tk_SetOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
+ int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
@@ -1122,8 +1136,8 @@ typedef struct TkStubs {
void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */
void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */
void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */
- void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
- void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
+ TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */
int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */
Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */
Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */
@@ -1137,10 +1151,10 @@ typedef struct TkStubs {
Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */
void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */
Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 260 */
- void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
- void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
- int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin); /* 263 */
- void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
+ void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
+ void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
+ int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin); /* 263 */
+ void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */
int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */
int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */
@@ -1721,12 +1735,30 @@ extern const TkStubs *tkStubsPtr;
#undef Tk_SafeInit
#undef Tk_CreateConsoleWindow
+#undef Tk_FreeXId
+#define Tk_FreeXId(display,xid)
+#undef Tk_GetStyleFromObj
+#undef Tk_FreeStyleFromObj
+#define Tk_GetStyleFromObj(obj) Tk_AllocStyleFromObj(NULL, obj)
+#define Tk_FreeStyleFromObj(obj) /* no-op */
+
+
#if defined(_WIN32) && defined(UNICODE)
# define Tk_MainEx Tk_MainExW
EXTERN void Tk_MainExW(int argc, wchar_t **argv,
Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif
+
+#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
+#undef Tk_PhotoPutBlock_NoComposite
+#undef Tk_PhotoPutZoomedBlock_NoComposite
+#undef Tk_PhotoExpand_Panic
+#undef Tk_PhotoPutBlock_Panic
+#undef Tk_PhotoPutZoomedBlock_Panic
+#undef Tk_PhotoSetSize_Panic
+#endif /* TK_NO_DEPRECATED */
+
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index ea8d7f1..8a69010 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -16,8 +16,8 @@
*/
#include "tkInt.h"
-#include "default.h"
#include "tkEntry.h"
+#include "default.h"
/*
* The following macro defines how many extra pixels to leave on each side of
@@ -118,6 +118,12 @@ static const Tk_OptionSpec entryOptSpec[] = {
NULL, 0, -1, 0, "-invalidcommand", 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},
+ {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
+ DEF_ENTRY_PLACEHOLDER, -1, Tk_Offset(Entry, placeholderString),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
+ "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, -1,
+ Tk_Offset(Entry, placeholderColorPtr), 0, 0, 0},
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
@@ -258,6 +264,12 @@ static const Tk_OptionSpec sbOptSpec[] = {
NULL, 0, -1, 0, "-invalidcommand", 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},
+ {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
+ DEF_ENTRY_PLACEHOLDER, -1, Tk_Offset(Entry, placeholderString),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
+ "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, -1,
+ Tk_Offset(Entry, placeholderColorPtr), 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
@@ -537,6 +549,8 @@ Tk_EntryObjCmd(
entryPtr->avgWidth = 1;
entryPtr->validate = VALIDATE_NONE;
+ entryPtr->placeholderGC = None;
+
/*
* Keep a hold of the associated tkwin until we destroy the entry,
* otherwise Tk might free it while we still need it.
@@ -552,7 +566,7 @@ Tk_EntryObjCmd(
Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
EntryFetchSelection, entryPtr, XA_STRING);
- if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
+ if ((Tk_InitOptions(interp, entryPtr, optionTable, tkwin)
!= TCL_OK) ||
(ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
Tk_DestroyWindow(entryPtr->tkwin);
@@ -640,7 +654,7 @@ EntryWidgetObjCmd(
goto error;
}
- objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
+ objPtr = Tk_GetOptionValue(interp, entryPtr,
entryPtr->optionTable, objv[2], entryPtr->tkwin);
if (objPtr == NULL) {
goto error;
@@ -650,7 +664,7 @@ EntryWidgetObjCmd(
case COMMAND_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
+ objPtr = Tk_GetOptionInfo(interp, entryPtr,
entryPtr->optionTable,
(objc == 3) ? objv[2] : NULL,
entryPtr->tkwin);
@@ -887,7 +901,8 @@ EntryWidgetObjCmd(
entryPtr->selectLast = index2;
}
if (!(entryPtr->flags & GOT_SELECTION)
- && (entryPtr->exportSelection)) {
+ && (entryPtr->exportSelection)
+ && (!Tcl_IsSafe(entryPtr->interp))) {
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
EntryLostSelection, entryPtr);
entryPtr->flags |= GOT_SELECTION;
@@ -1122,7 +1137,7 @@ ConfigureEntry(
* value.
*/
- oldExport = entryPtr->exportSelection;
+ oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp));
if (entryPtr->type == TK_SPINBOX) {
oldValues = sbPtr->valueStr;
oldFormat = sbPtr->reqFormat;
@@ -1136,7 +1151,7 @@ ConfigureEntry(
* First pass: set options to new values.
*/
- if (Tk_SetOptions(interp, (char *) entryPtr,
+ if (Tk_SetOptions(interp, entryPtr,
entryPtr->optionTable, objc, objv,
entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
@@ -1176,13 +1191,15 @@ ConfigureEntry(
if (entryPtr->type == TK_SPINBOX) {
if (sbPtr->fromValue > sbPtr->toValue) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "-to value must be greater than -from value",
- -1));
- Tcl_SetErrorCode(interp, "TK", "SPINBOX", "RANGE_SANITY",
- NULL);
- continue;
- }
+ /*
+ * Swap -from and -to values.
+ */
+
+ double tmpFromTo = sbPtr->fromValue;
+
+ sbPtr->fromValue = sbPtr->toValue;
+ sbPtr->toValue = tmpFromTo;
+ }
if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) {
/*
@@ -1276,6 +1293,7 @@ ConfigureEntry(
*/
if (entryPtr->exportSelection && (!oldExport)
+ && (!Tcl_IsSafe(entryPtr->interp))
&& (entryPtr->selectFirst != -1)
&& !(entryPtr->flags & GOT_SELECTION)) {
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
@@ -1485,8 +1503,20 @@ EntryWorldChanged(
}
entryPtr->textGC = gc;
+ if (entryPtr->placeholderColorPtr != NULL) {
+ gcValues.foreground = entryPtr->placeholderColorPtr->pixel;
+ }
+ mask = GCForeground | GCFont | GCGraphicsExposures;
+ gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
+ if (entryPtr->placeholderGC != None) {
+ Tk_FreeGC(entryPtr->display, entryPtr->placeholderGC);
+ }
+ entryPtr->placeholderGC = gc;
+
if (entryPtr->selFgColorPtr != NULL) {
gcValues.foreground = entryPtr->selFgColorPtr->pixel;
+ } else {
+ gcValues.foreground = colorPtr->pixel;
}
gcValues.font = Tk_FontId(entryPtr->tkfont);
mask = GCForeground | GCFont;
@@ -1734,9 +1764,15 @@ DisplayEntry(
* selected portion on top of it.
*/
- Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
+ if ((entryPtr->numChars != 0) || (entryPtr->placeholderChars == 0)) {
+ Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
entryPtr->leftIndex, entryPtr->numChars);
+ } else {
+ Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->placeholderGC,
+ entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY,
+ entryPtr->placeholderLeftIndex, entryPtr->placeholderChars);
+ }
if (showSelection && (entryPtr->state != STATE_DISABLED)
&& (entryPtr->selTextGC != entryPtr->textGC)
@@ -1924,8 +1960,8 @@ EntryComputeGeometry(
*/
if (entryPtr->showChar != NULL) {
- Tcl_UniChar ch;
- char buf[TCL_UTF_MAX];
+ int ch;
+ char buf[6];
int size;
/*
@@ -1935,19 +1971,72 @@ EntryComputeGeometry(
* resulting string.
*/
- Tcl_UtfToUniChar(entryPtr->showChar, &ch);
- size = Tcl_UniCharToUtf(ch, buf);
+ TkUtfToUniChar(entryPtr->showChar, &ch);
+ size = TkUniCharToUtf(ch, buf);
entryPtr->numDisplayBytes = entryPtr->numChars * size;
p = ckalloc(entryPtr->numDisplayBytes + 1);
entryPtr->displayString = p;
for (i = entryPtr->numChars; --i >= 0; ) {
- p += Tcl_UniCharToUtf(ch, p);
+ memcpy(p, buf, size);
+ p += size;
}
*p = '\0';
}
+ /* Recompute layout of placeholder text.
+ * Only the placeholderX and placeholderLeftIndex value is needed.
+ * We use the same font so we can use the layoutY value from below.
+ */
+
+ Tk_FreeTextLayout(entryPtr->placeholderLayout);
+ if (entryPtr->placeholderString) {
+ entryPtr->placeholderChars = strlen(entryPtr->placeholderString);
+ entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
+ entryPtr->placeholderString, entryPtr->placeholderChars, 0,
+ entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, NULL);
+ overflow = totalLength -
+ (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth);
+ if (overflow <= 0) {
+ entryPtr->placeholderLeftIndex = 0;
+ if (entryPtr->justify == TK_JUSTIFY_LEFT) {
+ entryPtr->placeholderX = entryPtr->inset;
+ } else if (entryPtr->justify == TK_JUSTIFY_RIGHT) {
+ entryPtr->placeholderX = Tk_Width(entryPtr->tkwin) - entryPtr->inset
+ - entryPtr->xWidth - totalLength;
+ } else {
+ entryPtr->placeholderX = (Tk_Width(entryPtr->tkwin)
+ - entryPtr->xWidth - totalLength)/2;
+ }
+ } else {
+
+ /*
+ * The whole string can't fit in the window. Compute the maximum
+ * number of characters that may be off-screen to the left without
+ * leaving empty space on the right of the window, then don't let
+ * placeholderLeftIndex be any greater than that.
+ */
+
+ maxOffScreen = Tk_PointToChar(entryPtr->placeholderLayout, overflow, 0);
+ Tk_CharBbox(entryPtr->placeholderLayout, maxOffScreen,
+ &rightX, NULL, NULL, NULL);
+ if (rightX < overflow) {
+ maxOffScreen++;
+ }
+ entryPtr->placeholderLeftIndex = maxOffScreen;
+ Tk_CharBbox(entryPtr->placeholderLayout, entryPtr->placeholderLeftIndex, &rightX,
+ NULL, NULL, NULL);
+ entryPtr->placeholderX = entryPtr->inset -rightX;
+ }
+ } else {
+ entryPtr->placeholderChars = 0;
+ entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
+ entryPtr->placeholderString, 0, 0,
+ entryPtr->justify, TK_IGNORE_NEWLINES, NULL, NULL);
+ entryPtr->placeholderX = entryPtr->inset;
+ }
+
Tk_FreeTextLayout(entryPtr->textLayout);
entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
entryPtr->displayString, entryPtr->numChars, 0,
@@ -2043,9 +2132,7 @@ InsertChars(
const char *value) /* New characters to add (NULL-terminated
* string). */
{
- ptrdiff_t byteIndex;
- size_t byteCount, newByteCount;
- int oldChars, charsAdded;
+ size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;
const char *string;
char *newStr;
@@ -2744,7 +2831,8 @@ EntrySelectTo(
* Grab the selection if we don't own it already.
*/
- if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) {
+ if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
+ && (!Tcl_IsSafe(entryPtr->interp))) {
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
entryPtr);
entryPtr->flags |= GOT_SELECTION;
@@ -2811,7 +2899,8 @@ EntryFetchSelection(
const char *string;
const char *selStart, *selEnd;
- if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) {
+ if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection)
+ || Tcl_IsSafe(entryPtr->interp)) {
return -1;
}
string = entryPtr->displayString;
@@ -2864,7 +2953,8 @@ EntryLostSelection(
*/
if (TkpAlwaysShowSelection(entryPtr->tkwin)
- && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) {
+ && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection
+ && (!Tcl_IsSafe(entryPtr->interp))) {
entryPtr->selectFirst = -1;
entryPtr->selectLast = -1;
EventuallyRedraw(entryPtr);
@@ -3129,8 +3219,8 @@ static char *
EntryTextVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Entry *entryPtr = clientData;
@@ -3144,6 +3234,19 @@ EntryTextVarProc(
}
/*
+ * See ticket [5d991b82].
+ */
+
+ if (entryPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ EntryTextVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
@@ -3245,7 +3348,7 @@ EntryValidate(
*
* Results:
* TCL_OK if the validatecommand accepts the new string, TCL_ERROR if any
- * problems occured with validatecommand.
+ * problems occurred with validatecommand.
*
* Side effects:
* The insertion/deletion may be aborted, and the validatecommand might
@@ -3302,7 +3405,7 @@ EntryValidateChange(
/*
* If e->validate has become VALIDATE_NONE during the validation, or we
* now have VALIDATE_VAR set (from EntrySetValue) and didn't before, it
- * means that a loop condition almost occured. Do not allow this
+ * means that a loop condition almost occurred. Do not allow this
* validation result to finish.
*/
@@ -3411,7 +3514,7 @@ ExpandPercents(
* list element. */
int number, length;
register const char *string;
- Tcl_UniChar ch;
+ int ch;
char numStorage[2*TCL_INTEGER_SPACE];
while (1) {
@@ -3444,7 +3547,7 @@ ExpandPercents(
before++; /* skip over % */
if (*before != '\0') {
- before += Tcl_UtfToUniChar(before, &ch);
+ before += TkUtfToUniChar(before, &ch);
} else {
ch = '%';
}
@@ -3464,7 +3567,7 @@ ExpandPercents(
string = Tk_PathName(entryPtr->tkwin);
break;
default:
- length = Tcl_UniCharToUtf(ch, numStorage);
+ length = TkUniCharToUtf(ch, numStorage);
numStorage[length] = '\0';
string = numStorage;
break;
@@ -3524,7 +3627,7 @@ ExpandPercents(
string = Tk_PathName(entryPtr->tkwin);
break;
default:
- length = Tcl_UniCharToUtf(ch, numStorage);
+ length = TkUniCharToUtf(ch, numStorage);
numStorage[length] = '\0';
string = numStorage;
break;
@@ -3639,6 +3742,8 @@ Tk_SpinboxObjCmd(
sbPtr->bdRelief = TK_RELIEF_FLAT;
sbPtr->buRelief = TK_RELIEF_FLAT;
+ entryPtr->placeholderGC = None;
+
/*
* Keep a hold of the associated tkwin until we destroy the spinbox,
* otherwise Tk might free it while we still need it.
@@ -3654,7 +3759,7 @@ Tk_SpinboxObjCmd(
Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
EntryFetchSelection, entryPtr, XA_STRING);
- if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin)
+ if (Tk_InitOptions(interp, sbPtr, optionTable, tkwin)
!= TCL_OK) {
Tk_DestroyWindow(entryPtr->tkwin);
return TCL_ERROR;
@@ -3749,7 +3854,7 @@ SpinboxWidgetObjCmd(
goto error;
}
- objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
+ objPtr = Tk_GetOptionValue(interp, entryPtr,
entryPtr->optionTable, objv[2], entryPtr->tkwin);
if (objPtr == NULL) {
goto error;
@@ -3759,7 +3864,7 @@ SpinboxWidgetObjCmd(
case SB_CMD_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
+ objPtr = Tk_GetOptionInfo(interp, entryPtr,
entryPtr->optionTable, (objc == 3) ? objv[2] : NULL,
entryPtr->tkwin);
if (objPtr == NULL) {
@@ -4033,7 +4138,8 @@ SpinboxWidgetObjCmd(
entryPtr->selectLast = index2;
}
if (!(entryPtr->flags & GOT_SELECTION)
- && entryPtr->exportSelection) {
+ && entryPtr->exportSelection
+ && (!Tcl_IsSafe(entryPtr->interp))) {
Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
EntryLostSelection, entryPtr);
entryPtr->flags |= GOT_SELECTION;
@@ -4278,16 +4384,17 @@ SpinboxInvoke(
* there. If not, move to the first element of the list.
*/
- int i, listc, elemLen, length = entryPtr->numChars;
+ int i, listc;
+ size_t elemLen, length = entryPtr->numChars;
const char *bytes;
Tcl_Obj **listv;
Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
for (i = 0; i < listc; i++) {
- bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
+ bytes = TkGetStringFromObj(listv[i], &elemLen);
if ((length == elemLen) &&
(memcmp(bytes, entryPtr->string,
- (size_t) length) == 0)) {
+ length) == 0)) {
sbPtr->eIndex = i;
break;
}
diff --git a/generic/tkEntry.h b/generic/tkEntry.h
index 52535c8..e74b52b 100644
--- a/generic/tkEntry.h
+++ b/generic/tkEntry.h
@@ -129,6 +129,19 @@ typedef struct {
* only used by the Entry widget. */
/*
+ * Fields used in displaying help text if entry value is empty
+ */
+
+ Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */
+ char *placeholderString; /* String value of placeholder. */
+ int placeholderChars; /* Number of chars in placeholder. */
+ XColor *placeholderColorPtr;/* Color value of placeholder foreground. */
+ GC placeholderGC; /* For drawing placeholder text. */
+ int placeholderX; /* Origin for layout. */
+ int placeholderLeftIndex; /* Character index of left-most character
+ * visible in window. */
+
+ /*
* Fields whose values are derived from the current values of the
* configuration settings above.
*/
@@ -221,7 +234,7 @@ typedef struct {
* value that the users requests. Malloc'ed */
char *valueFormat; /* Sprintf conversion specifier used for the
* value. */
- char digitFormat[10]; /* Sprintf conversion specifier computed from
+ char digitFormat[16]; /* Sprintf conversion specifier computed from
* digits and other information; used for the
* value. */
diff --git a/generic/tkError.c b/generic/tkError.c
index fc223e6..5aa6d88 100644
--- a/generic/tkError.c
+++ b/generic/tkError.c
@@ -82,8 +82,8 @@ Tk_CreateErrorHandler(
* errors. */
ClientData clientData) /* Arbitrary value to pass to errorProc. */
{
- register TkErrorHandler *errorPtr;
- register TkDisplay *dispPtr;
+ TkErrorHandler *errorPtr;
+ TkDisplay *dispPtr;
/*
* Find the display. If Tk doesn't know about this display then it's an
@@ -147,8 +147,8 @@ Tk_DeleteErrorHandler(
Tk_ErrorHandler handler) /* Token for handler to delete; was previous
* return value from Tk_CreateErrorHandler. */
{
- register TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
- register TkDisplay *dispPtr = errorPtr->dispPtr;
+ TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
+ TkDisplay *dispPtr = errorPtr->dispPtr;
errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;
@@ -164,19 +164,26 @@ Tk_DeleteErrorHandler(
* there are many handlers that stay around forever).
*/
- dispPtr->deleteCount += 1;
- if (dispPtr->deleteCount >= 10) {
- register TkErrorHandler *prevPtr;
+ if (dispPtr->deleteCount++ >= 9) {
+ TkErrorHandler *prevPtr;
TkErrorHandler *nextPtr;
- int lastSerial;
+ unsigned long lastSerial = LastKnownRequestProcessed(dispPtr->display);
+ /*
+ * Last chance to catch errors for this handler: if no event/error
+ * processing took place to follow up the end of this error handler
+ * we need a round trip with the X server now.
+ */
+
+ if (errorPtr->lastRequest > lastSerial) {
+ XSync(dispPtr->display, False);
+ }
dispPtr->deleteCount = 0;
- lastSerial = LastKnownRequestProcessed(dispPtr->display);
errorPtr = dispPtr->errorPtr;
for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) {
nextPtr = errorPtr->nextPtr;
if ((errorPtr->lastRequest != (unsigned long) -1)
- && (errorPtr->lastRequest <= (unsigned long) lastSerial)) {
+ && (errorPtr->lastRequest <= lastSerial)) {
if (prevPtr == NULL) {
dispPtr->errorPtr = nextPtr;
} else {
@@ -213,11 +220,11 @@ Tk_DeleteErrorHandler(
static int
ErrorProc(
Display *display, /* Display for which error occurred. */
- register XErrorEvent *errEventPtr)
+ XErrorEvent *errEventPtr)
/* Information about error. */
{
- register TkDisplay *dispPtr;
- register TkErrorHandler *errorPtr;
+ TkDisplay *dispPtr;
+ TkErrorHandler *errorPtr;
/*
* See if we know anything about the display. If not, then invoke the
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index 95aeda1..d058e7c 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -356,6 +356,7 @@ CreateXIC(
/* XCreateIC failed. */
return;
}
+ winPtr->ximGeneration = dispPtr->ximGeneration;
/*
* Adjust the window's event mask if the IM requires it.
@@ -1288,6 +1289,14 @@ Tk_HandleEvent(
*/
#ifdef TK_USE_INPUT_METHODS
+ /*
+ * If the XIC has been invalidated, it must be recreated.
+ */
+ if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
+ winPtr->flags &= ~TK_CHECKED_IC;
+ winPtr->inputContext = NULL;
+ }
+
if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
winPtr->flags |= TK_CHECKED_IC;
@@ -1295,7 +1304,9 @@ Tk_HandleEvent(
CreateXIC(winPtr);
}
}
- if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) {
+ if ((eventPtr->type == FocusIn) &&
+ (winPtr->dispPtr->inputMethod != NULL) &&
+ (winPtr->inputContext != NULL)) {
XSetICFocus(winPtr->inputContext);
}
}
diff --git a/generic/tkFont.c b/generic/tkFont.c
index 102fc6e..c0ff7d0 100644
--- a/generic/tkFont.c
+++ b/generic/tkFont.c
@@ -41,7 +41,7 @@ typedef struct TkFontInfo {
*/
typedef struct NamedFont {
- int refCount; /* Number of users of named font. */
+ size_t refCount; /* Number of users of named font. */
int deletePending; /* Non-zero if font should be deleted when
* last reference goes away. */
TkFontAttributes fa; /* Desired attributes for named font. */
@@ -351,7 +351,7 @@ const Tcl_ObjType tkFontObjType = {
FreeFontObjProc, /* freeIntRepProc */
DupFontObjProc, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetFontFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -497,7 +497,7 @@ Tk_FontObjCmd(
const char *s;
Tk_Font tkfont;
Tcl_Obj *optPtr, *charPtr, *resultPtr;
- Tcl_UniChar uniChar = 0;
+ int uniChar = 0;
const TkFontAttributes *faPtr;
TkFontAttributes fa;
@@ -562,17 +562,19 @@ Tk_FontObjCmd(
*/
if (charPtr != NULL) {
- if (Tcl_GetCharLength(charPtr) != 1) {
+ const char *string = Tcl_GetString(charPtr);
+ size_t len = TkUtfToUniChar(string, &uniChar);
+
+ if (len != (size_t)charPtr->length) {
resultPtr = Tcl_NewStringObj(
"expected a single character but got \"", -1);
- Tcl_AppendLimitedToObj(resultPtr, Tcl_GetString(charPtr),
+ Tcl_AppendLimitedToObj(resultPtr, string,
-1, 40, "...");
Tcl_AppendToObj(resultPtr, "\"", -1);
Tcl_SetObjResult(interp, resultPtr);
Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);
return TCL_ERROR;
}
- uniChar = Tcl_GetUniChar(charPtr, 0);
}
/*
@@ -710,7 +712,8 @@ Tk_FontObjCmd(
case FONT_MEASURE: {
const char *string;
Tk_Font tkfont;
- int length = 0, skip = 0;
+ size_t length = 0;
+ int skip = 0;
if (objc > 4) {
skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
@@ -727,7 +730,7 @@ Tk_FontObjCmd(
if (tkfont == NULL) {
return TCL_ERROR;
}
- string = Tcl_GetStringFromObj(objv[3 + skip], &length);
+ string = TkGetStringFromObj(objv[3 + skip], &length);
Tcl_SetObjResult(interp, Tcl_NewIntObj(
Tk_TextWidth(tkfont, string, length)));
Tk_FreeFont(tkfont);
@@ -1226,7 +1229,7 @@ Tk_AllocFontFromObj(
descent = fontPtr->fm.descent;
fontPtr->underlinePos = descent / 2;
- fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10;
+ fontPtr->underlineHeight = (int) (TkFontGetPixels(tkwin, fontPtr->fa.size) / 10 + 0.5);
if (fontPtr->underlineHeight == 0) {
fontPtr->underlineHeight = 1;
}
@@ -1421,8 +1424,7 @@ Tk_FreeFont(
if (fontPtr == NULL) {
return;
}
- fontPtr->resourceRefCount--;
- if (fontPtr->resourceRefCount > 0) {
+ if (fontPtr->resourceRefCount-- > 1) {
return;
}
if (fontPtr->namedHashPtr != NULL) {
@@ -1432,8 +1434,7 @@ Tk_FreeFont(
*/
nfPtr = Tcl_GetHashValue(fontPtr->namedHashPtr);
- nfPtr->refCount--;
- if ((nfPtr->refCount == 0) && nfPtr->deletePending) {
+ if ((nfPtr->refCount-- <= 1) && nfPtr->deletePending) {
Tcl_DeleteHashEntry(fontPtr->namedHashPtr);
ckfree(nfPtr);
}
@@ -1520,8 +1521,7 @@ FreeFontObj(
TkFont *fontPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (fontPtr != NULL) {
- fontPtr->objRefCount--;
- if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) {
+ if ((fontPtr->objRefCount-- <= 1) && (fontPtr->resourceRefCount == 0)) {
ckfree(fontPtr);
}
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
@@ -1694,7 +1694,7 @@ Tk_PostscriptFontName(
} else if (strcasecmp(family, "ZapfDingbats") == 0) {
family = "ZapfDingbats";
} else {
- Tcl_UniChar ch;
+ int ch;
/*
* Inline, capitalize the first letter of each word, lowercase the
@@ -1712,14 +1712,14 @@ Tk_PostscriptFontName(
src++;
upper = 1;
}
- src += Tcl_UtfToUniChar(src, &ch);
+ src += TkUtfToUniChar(src, &ch);
if (upper) {
ch = Tcl_UniCharToUpper(ch);
upper = 0;
} else {
ch = Tcl_UniCharToLower(ch);
}
- dest += Tcl_UniCharToUtf(ch, dest);
+ dest += TkUniCharToUtf(ch, dest);
}
*dest = '\0';
Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
@@ -1794,7 +1794,7 @@ Tk_PostscriptFontName(
}
}
- return fontPtr->fa.size;
+ return (int)(fontPtr->fa.size + 0.5);
}
/*
@@ -3145,14 +3145,13 @@ TkIntersectAngledTextLayout(
cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent;
cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth;
cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent;
- if ( !PointInQuadrilateral(cx, cy, rx[0], ry[0]) ||
- !PointInQuadrilateral(cx, cy, rx[1], ry[1]) ||
- !PointInQuadrilateral(cx, cy, rx[2], ry[2]) ||
- !PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
- goto notReverseInside;
- }
+ if ( PointInQuadrilateral(cx, cy, rx[0], ry[0]) &&
+ PointInQuadrilateral(cx, cy, rx[1], ry[1]) &&
+ PointInQuadrilateral(cx, cy, rx[2], ry[2]) &&
+ PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
+ return 0;
+ }
}
- return 0;
/*
* If we're overlapping now, we must be partially in and out of at least
@@ -3160,7 +3159,6 @@ TkIntersectAngledTextLayout(
* rectangle that is touching or crossing a line segment of a chunk.
*/
- notReverseInside:
chunkPtr = layoutPtr->chunks;
for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
@@ -3246,10 +3244,11 @@ Tk_TextLayoutToPostscript(
LayoutChunk *chunkPtr = layoutPtr->chunks;
int baseline = chunkPtr->y;
Tcl_Obj *psObj = Tcl_NewObj();
- int i, j, len;
+ int i, j;
+ size_t len;
const char *p, *glyphname;
char uindex[5], c, *ps;
- Tcl_UniChar ch;
+ int ch;
Tcl_AppendToObj(psObj, "[(", -1);
for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) {
@@ -3272,7 +3271,7 @@ Tk_TextLayoutToPostscript(
* international postscript fonts.
*/
- p += Tcl_UtfToUniChar(p, &ch);
+ p += TkUtfToUniChar(p, &ch);
if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) {
/*
* Tricky point: the "03" is necessary in the sprintf below,
@@ -3298,10 +3297,13 @@ Tk_TextLayoutToPostscript(
* use the full glyph name.
*/
+ if (ch > 0xffff) {
+ goto noMapping;
+ }
sprintf(uindex, "%04X", ch); /* endianness? */
glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0);
if (glyphname) {
- ps = Tcl_GetStringFromObj(psObj, &len);
+ ps = TkGetStringFromObj(psObj, &len);
if (ps[len-1] == '(') {
/*
* In-place edit. Ewww!
@@ -3318,6 +3320,7 @@ Tk_TextLayoutToPostscript(
* No known mapping for the character into the space of
* PostScript glyphs. Ignore it. :-(
*/
+noMapping: ;
#ifdef TK_DEBUG_POSTSCRIPT_OUTPUT
fprintf(stderr, "Warning: no mapping to PostScript "
@@ -3399,7 +3402,7 @@ ConfigAttributesObj(
if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) {
return TCL_ERROR;
}
- faPtr->size = n;
+ faPtr->size = (double)n;
break;
case FONT_WEIGHT:
n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr);
@@ -3490,7 +3493,11 @@ GetAttributeInfoObj(
break;
case FONT_SIZE:
- valuePtr = Tcl_NewIntObj(faPtr->size);
+ if (faPtr->size >= 0.0) {
+ valuePtr = Tcl_NewIntObj((int)(faPtr->size + 0.5));
+ } else {
+ valuePtr = Tcl_NewIntObj(-(int)(-faPtr->size + 0.5));
+ }
break;
case FONT_WEIGHT:
@@ -3639,7 +3646,7 @@ ParseFontNameObj(
if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) {
return TCL_ERROR;
}
- faPtr->size = n;
+ faPtr->size = (double)n;
}
i = 2;
@@ -3883,7 +3890,7 @@ TkFontParseXLFD(
* historical compatibility.
*/
- faPtr->size = 12;
+ faPtr->size = 12.0;
if (FieldSpecified(field[XLFD_POINT_SIZE])) {
if (field[XLFD_POINT_SIZE][0] == '[') {
@@ -3897,10 +3904,10 @@ TkFontParseXLFD(
* the purpose of, so I ignore them.
*/
- faPtr->size = atoi(field[XLFD_POINT_SIZE] + 1);
+ faPtr->size = atof(field[XLFD_POINT_SIZE] + 1);
} else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE],
- &faPtr->size) == TCL_OK) {
- faPtr->size /= 10;
+ &i) == TCL_OK) {
+ faPtr->size = i/10.0;
} else {
return TCL_ERROR;
}
@@ -3922,9 +3929,11 @@ TkFontParseXLFD(
* ignore them.
*/
- faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1);
+ faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1);
} else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE],
- &faPtr->size) != TCL_OK) {
+ &i) == TCL_OK) {
+ faPtr->size = (double)i;
+ } else {
return TCL_ERROR;
}
}
@@ -4000,21 +4009,21 @@ FieldSpecified(
*---------------------------------------------------------------------------
*/
-int
+double
TkFontGetPixels(
Tk_Window tkwin, /* For point->pixel conversion factor. */
- int size) /* Font size. */
+ double size) /* Font size. */
{
double d;
- if (size < 0) {
+ if (size <= 0.0) {
return -size;
}
d = size * 25.4 / 72.0;
d *= WidthOfScreen(Tk_Screen(tkwin));
d /= WidthMMOfScreen(Tk_Screen(tkwin));
- return (int) (d + 0.5);
+ return d;
}
/*
@@ -4034,21 +4043,21 @@ TkFontGetPixels(
*---------------------------------------------------------------------------
*/
-int
+double
TkFontGetPoints(
Tk_Window tkwin, /* For pixel->point conversion factor. */
- int size) /* Font size. */
+ double size) /* Font size. */
{
double d;
- if (size >= 0) {
+ if (size >= 0.0) {
return size;
}
d = -size * 72.0 / 25.4;
d *= WidthMMOfScreen(Tk_Screen(tkwin));
d /= WidthOfScreen(Tk_Screen(tkwin));
- return (int) (d + 0.5);
+ return d;
}
/*
@@ -4195,9 +4204,9 @@ TkDebugFont(
for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) {
objPtr = Tcl_NewObj();
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(fontPtr->resourceRefCount));
+ Tcl_NewWideIntObj(fontPtr->resourceRefCount));
Tcl_ListObjAppendElement(NULL, objPtr,
- Tcl_NewIntObj(fontPtr->objRefCount));
+ Tcl_NewWideIntObj(fontPtr->objRefCount));
Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
}
}
diff --git a/generic/tkFont.h b/generic/tkFont.h
index b8de885..50f79d2 100644
--- a/generic/tkFont.h
+++ b/generic/tkFont.h
@@ -23,7 +23,7 @@
struct TkFontAttributes {
Tk_Uid family; /* Font family, or NULL to represent plaform-
* specific default system font. */
- int size; /* Pointsize of font, 0 for default size, or
+ double size; /* Pointsize of font, 0.0 for default size, or
* negative number meaning pixel size. */
int weight; /* Weight flag; see below for def'n. */
int slant; /* Slant flag; see below for def'n. */
@@ -85,7 +85,7 @@ typedef struct TkFont {
* Fields used and maintained exclusively by generic code.
*/
- int resourceRefCount; /* Number of active uses of this font (each
+ TkSizeT resourceRefCount; /* Number of active uses of this font (each
* active use corresponds to a call to
* Tk_AllocFontFromTable or Tk_GetFont). If
* this count is 0, then this TkFont structure
@@ -95,7 +95,7 @@ typedef struct TkFont {
* The structure is freed when
* resourceRefCount and objRefCount are both
* 0. */
- int objRefCount; /* The number of Tcl objects that reference
+ TkSizeT objRefCount; /* The number of Tcl objects that reference
* this structure. */
Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
* used when deleting it. */
@@ -198,8 +198,8 @@ MODULE_SCOPE int TkFontParseXLFD(const char *string,
TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr);
MODULE_SCOPE const char *const * TkFontGetAliasList(const char *faceName);
MODULE_SCOPE const char *const *const * TkFontGetFallbacks(void);
-MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size);
-MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size);
+MODULE_SCOPE double TkFontGetPixels(Tk_Window tkwin, double size);
+MODULE_SCOPE double TkFontGetPoints(Tk_Window tkwin, double size);
MODULE_SCOPE const char *const * TkFontGetGlobalClass(void);
MODULE_SCOPE const char *const * TkFontGetSymbolClass(void);
MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin,
diff --git a/generic/tkFrame.c b/generic/tkFrame.c
index 057b4b8..53c019c 100644
--- a/generic/tkFrame.c
+++ b/generic/tkFrame.c
@@ -12,8 +12,8 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
+#include "default.h"
/*
* The following enum is used to define the type of the frame.
@@ -447,6 +447,29 @@ TkCreateFrame(
return result;
}
+int
+TkListCreateFrame(
+ ClientData clientData, /* Either NULL or pointer to option table. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ Tcl_Obj *listObj, /* List of arguments. */
+ int toplevel, /* Non-zero means create a toplevel window,
+ * zero means create a frame. */
+ Tcl_Obj *nameObj) /* Should only be non-NULL if there is no main
+ * window associated with the interpreter.
+ * Gives the base name to use for the new
+ * application. */
+{
+ int objc;
+ Tcl_Obj **objv;
+
+ if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) {
+ return TCL_ERROR;
+ }
+ return CreateFrame(clientData, interp, objc, objv,
+ toplevel ? TYPE_TOPLEVEL : TYPE_FRAME,
+ nameObj ? Tcl_GetString(nameObj) : NULL);
+}
+
static int
CreateFrame(
ClientData clientData, /* NULL. */
@@ -465,7 +488,8 @@ CreateFrame(
Tk_Window newWin;
const char *className, *screenName, *visualName, *colormapName;
const char *arg, *useOption;
- int i, length, depth;
+ int i, depth;
+ size_t length;
unsigned int mask;
Colormap colormap;
Visual *visual;
@@ -492,24 +516,24 @@ CreateFrame(
className = colormapName = screenName = visualName = useOption = NULL;
colormap = None;
for (i = 2; i < objc; i += 2) {
- arg = Tcl_GetStringFromObj(objv[i], &length);
+ arg = TkGetStringFromObj(objv[i], &length);
if (length < 2) {
continue;
}
if ((arg[1] == 'c') && (length >= 3)
- && (strncmp(arg, "-class", (unsigned) length) == 0)) {
+ && (strncmp(arg, "-class", length) == 0)) {
className = Tcl_GetString(objv[i+1]);
} else if ((arg[1] == 'c') && (length >= 3)
- && (strncmp(arg, "-colormap", (unsigned) length) == 0)) {
+ && (strncmp(arg, "-colormap", length) == 0)) {
colormapName = Tcl_GetString(objv[i+1]);
} else if ((arg[1] == 's') && (type == TYPE_TOPLEVEL)
- && (strncmp(arg, "-screen", (unsigned) length) == 0)) {
+ && (strncmp(arg, "-screen", length) == 0)) {
screenName = Tcl_GetString(objv[i+1]);
} else if ((arg[1] == 'u') && (type == TYPE_TOPLEVEL)
- && (strncmp(arg, "-use", (unsigned) length) == 0)) {
+ && (strncmp(arg, "-use", length) == 0)) {
useOption = Tcl_GetString(objv[i+1]);
} else if ((arg[1] == 'v')
- && (strncmp(arg, "-visual", (unsigned) length) == 0)) {
+ && (strncmp(arg, "-visual", length) == 0)) {
visualName = Tcl_GetString(objv[i+1]);
}
}
@@ -659,7 +683,7 @@ CreateFrame(
mask |= ActivateMask;
}
Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr);
- if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin)
+ if ((Tk_InitOptions(interp, framePtr, optionTable, newWin)
!= TCL_OK) ||
(ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
goto error;
@@ -720,7 +744,8 @@ FrameWidgetObjCmd(
};
register Frame *framePtr = clientData;
int result = TCL_OK, index;
- int c, i, length;
+ int c, i;
+ size_t length;
Tcl_Obj *objPtr;
if (objc < 2) {
@@ -739,7 +764,7 @@ FrameWidgetObjCmd(
result = TCL_ERROR;
goto done;
}
- objPtr = Tk_GetOptionValue(interp, (char *) framePtr,
+ objPtr = Tk_GetOptionValue(interp, framePtr,
framePtr->optionTable, objv[2], framePtr->tkwin);
if (objPtr == NULL) {
result = TCL_ERROR;
@@ -749,7 +774,7 @@ FrameWidgetObjCmd(
break;
case FRAME_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) framePtr,
+ objPtr = Tk_GetOptionInfo(interp, framePtr,
framePtr->optionTable, (objc == 3) ? objv[2] : NULL,
framePtr->tkwin);
if (objPtr == NULL) {
@@ -764,7 +789,7 @@ FrameWidgetObjCmd(
*/
for (i = 2; i < objc; i++) {
- const char *arg = Tcl_GetStringFromObj(objv[i], &length);
+ const char *arg = TkGetStringFromObj(objv[i], &length);
if (length < 2) {
continue;
@@ -937,7 +962,7 @@ ConfigureFrame(
if (framePtr->type == TYPE_LABELFRAME) {
oldWindow = labelframePtr->labelWin;
}
- if (Tk_SetOptions(interp, (char *) framePtr,
+ if (Tk_SetOptions(interp, framePtr,
framePtr->optionTable, objc, objv,
framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
if (oldMenuName != NULL) {
diff --git a/generic/tkGC.c b/generic/tkGC.c
index 5663ede..55e5774 100644
--- a/generic/tkGC.c
+++ b/generic/tkGC.c
@@ -23,7 +23,7 @@
typedef struct {
GC gc; /* Graphics context. */
Display *display; /* Display to which gc belongs. */
- int refCount; /* Number of active uses of gc. */
+ size_t refCount; /* Number of active uses of gc. */
Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
* this structure). */
} TkGC;
@@ -312,9 +312,7 @@ Tk_FreeGC(
Tcl_Panic("Tk_FreeGC received unknown gc argument");
}
gcPtr = Tcl_GetHashValue(idHashPtr);
- gcPtr->refCount--;
- if (gcPtr->refCount == 0) {
- Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
+ if (gcPtr->refCount-- <= 1) {
XFreeGC(gcPtr->display, gcPtr->gc);
Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
Tcl_DeleteHashEntry(idHashPtr);
@@ -351,12 +349,6 @@ TkGCCleanup(
entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) {
gcPtr = Tcl_GetHashValue(entryPtr);
- /*
- * This call is not needed, as it is only used on Unix to restore the
- * Id to the stack pool, and we don't want to use them anymore.
- * Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc));
- */
-
XFreeGC(gcPtr->display, gcPtr->gc);
Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
Tcl_DeleteHashEntry(entryPtr);
diff --git a/generic/tkGrab.c b/generic/tkGrab.c
index 00d4511..c37b6be 100644
--- a/generic/tkGrab.c
+++ b/generic/tkGrab.c
@@ -190,7 +190,7 @@ Tk_GrabObjCmd(
TkDisplay *dispPtr;
const char *arg;
int index;
- int len;
+ size_t len;
static const char *const optionStrings[] = {
"current", "release", "set", "status", NULL
};
@@ -227,7 +227,7 @@ Tk_GrabObjCmd(
* First check for a window name or "-global" as the first argument.
*/
- arg = Tcl_GetStringFromObj(objv[1], &len);
+ arg = TkGetStringFromObj(objv[1], &len);
if (arg[0] == '.') {
/* [grab window] */
if (objc != 2) {
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index 2a88b76..aaed30f 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.c
@@ -2868,17 +2868,18 @@ GridStructureProc(
}
}
} else if (eventPtr->type == DestroyNotify) {
- register Gridder *gridPtr2, *nextPtr;
+ register Gridder *slavePtr, *nextPtr;
if (gridPtr->masterPtr != NULL) {
Unlink(gridPtr);
}
- for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
- gridPtr2 = nextPtr) {
- Tk_UnmapWindow(gridPtr2->tkwin);
- gridPtr2->masterPtr = NULL;
- nextPtr = gridPtr2->nextPtr;
- gridPtr2->nextPtr = NULL;
+ for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
+ slavePtr = nextPtr) {
+ Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL);
+ Tk_UnmapWindow(slavePtr->tkwin);
+ slavePtr->masterPtr = NULL;
+ nextPtr = slavePtr->nextPtr;
+ slavePtr->nextPtr = NULL;
}
Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
(char *) gridPtr->tkwin));
@@ -2894,11 +2895,11 @@ GridStructureProc(
Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
}
} else if (eventPtr->type == UnmapNotify) {
- register Gridder *gridPtr2;
+ register Gridder *slavePtr;
- for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
- gridPtr2 = gridPtr2->nextPtr) {
- Tk_UnmapWindow(gridPtr2->tkwin);
+ for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
+ slavePtr = slavePtr->nextPtr) {
+ Tk_UnmapWindow(slavePtr->tkwin);
}
}
}
@@ -2964,10 +2965,10 @@ ConfigureSlaves(
firstChar = 0;
for (numWindows=0, i=0; i < objc; i++) {
- int length;
+ size_t length;
char prevChar = firstChar;
- string = Tcl_GetStringFromObj(objv[i], &length);
+ string = TkGetStringFromObj(objv[i], &length);
firstChar = string[0];
if (firstChar == '.') {
@@ -3083,7 +3084,8 @@ ConfigureSlaves(
}
/*
- * If no -row is given, use the first unoccupied row of the master.
+ * If no -row is given, use the next row after the highest occupied row
+ * of the master.
*/
if (defaultRow < 0) {
@@ -3314,6 +3316,9 @@ ConfigureSlaves(
}
if (slavePtr->masterPtr != NULL && slavePtr->masterPtr != masterPtr) {
+ if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
+ Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
+ }
Unlink(slavePtr);
slavePtr->masterPtr = NULL;
}
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index 0906673..80b1c9c 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -49,7 +49,7 @@ typedef struct BitmapMaster {
*/
typedef struct BitmapInstance {
- int refCount; /* Number of instances that share this data
+ size_t refCount; /* Number of instances that share this data
* structure. */
BitmapMaster *masterPtr; /* Pointer to master for image. */
Tk_Window tkwin; /* Window in which the instances will be
@@ -951,8 +951,7 @@ ImgBmapFree(
BitmapInstance *instancePtr = clientData;
BitmapInstance *prevPtr;
- instancePtr->refCount--;
- if (instancePtr->refCount > 0) {
+ if (instancePtr->refCount-- > 1) {
return;
}
@@ -1080,10 +1079,10 @@ GetByte(
Tcl_Channel chan) /* The channel we read from. */
{
char buffer;
- int size;
+ size_t size;
size = Tcl_Read(chan, &buffer, 1);
- if (size <= 0) {
+ if ((size + 1) < 2) {
return EOF;
} else {
return buffer;
diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c
index 1c28b54..aacde56 100644
--- a/generic/tkImgGIF.c
+++ b/generic/tkImgGIF.c
@@ -55,7 +55,7 @@ typedef struct mFile {
unsigned char *data; /* mmencoded source string */
int c; /* bits left over from previous character */
int state; /* decoder state (0-4 or GIF_DONE) */
- int length; /* Total amount of bytes in data */
+ size_t length; /* Total amount of bytes in data */
} MFile;
/*
@@ -111,8 +111,8 @@ typedef struct {
* serializing in the GIF format.
*/
-typedef int (WriteBytesFunc) (ClientData clientData, const char *bytes,
- int byteCount);
+typedef size_t (WriteBytesFunc) (ClientData clientData, const char *bytes,
+ size_t byteCount);
/*
* The format record for the GIF file format:
@@ -187,14 +187,14 @@ static int ReadImage(GIFImageConfig *gifConfPtr,
* these are for the BASE64 image reader code only
*/
-static int Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
+static size_t Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
size_t size, size_t count, Tcl_Channel chan);
-static int Mread(unsigned char *dst, size_t size, size_t count,
+static size_t Mread(unsigned char *dst, size_t size, size_t count,
MFile *handle);
static int Mgetc(MFile *handle);
static int char64(int c);
static void mInit(unsigned char *string, MFile *handle,
- int length);
+ size_t length);
/*
* Types, defines and variables needed to write and compress a GIF.
@@ -757,10 +757,10 @@ StringMatchGIF(
Tcl_Interp *interp) /* not used */
{
unsigned char *data, header[10];
- int got, length;
+ size_t got, length;
MFile handle;
- data = Tcl_GetByteArrayFromObj(dataObj, &length);
+ data = TkGetByteArrayFromObj(dataObj, &length);
/*
* Header is a minimum of 10 bytes.
@@ -826,9 +826,9 @@ StringReadGIF(
int srcX, int srcY)
{
MFile handle, *hdlPtr = &handle;
- int length;
+ size_t length;
const char *xferFormat;
- unsigned char *data = Tcl_GetByteArrayFromObj(dataObj, &length);
+ unsigned char *data = TkGetByteArrayFromObj(dataObj, &length);
mInit(data, hdlPtr, length);
@@ -917,7 +917,7 @@ ReadColorMap(
unsigned char rgb[3];
for (i = 0; i < number; ++i) {
- if (Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) <= 0) {
+ if (((size_t)Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) + 1) < 2) {
return 0;
}
@@ -983,11 +983,11 @@ GetDataBlock(
{
unsigned char count;
- if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) {
+ if (((size_t)Fread(gifConfPtr, &count, 1, 1, chan) + 1) < 2) {
return -1;
}
- if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) {
+ if ((count != 0) && (((size_t)Fread(gifConfPtr, buf, count, 1, chan) + 1) < 2)) {
return -1;
}
@@ -1049,7 +1049,7 @@ ReadImage(
* Initialize the decoder
*/
- if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) {
+ if (((size_t)Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) + 1) < 2) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading GIF image: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
@@ -1141,9 +1141,9 @@ ReadImage(
* Last pass reset the decoder, so the first code we see
* must be a singleton. Seed the stack with it, and set up
* the old/first code pointers for insertion into the
- * string table. We can't just roll this into the
- * clearCode test above, because at that point we have not
- * yet read the next code.
+ * codes table. We can't just roll this into the clearCode
+ * test above, because at that point we have not yet read
+ * the next code.
*/
*top++ = append[code];
@@ -1154,11 +1154,11 @@ ReadImage(
inCode = code;
- if (code == maxCode) {
+ if ((code == maxCode) && (maxCode < (1 << MAX_LWZ_BITS))) {
/*
* maxCode is always one bigger than our highest assigned
* code. If the code we see is equal to maxCode, then we
- * are about to add a new string to the table. ???
+ * are about to add a new entry to the codes table.
*/
*top++ = firstCode;
@@ -1167,7 +1167,7 @@ ReadImage(
while (code > clearCode) {
/*
- * Populate the stack by tracing the string in the string
+ * Populate the stack by tracing the code in the codes
* table from its tail to its head
*/
@@ -1176,28 +1176,24 @@ ReadImage(
}
firstCode = append[code];
- /*
- * If there's no more room in our string table, quit.
- * Otherwise, add a new string to the table
- */
+ /*
+ * Push the head of the code onto the stack.
+ */
- if (maxCode >= (1 << MAX_LWZ_BITS)) {
- return TCL_OK;
- }
+ *top++ = firstCode;
- /*
- * Push the head of the string onto the stack.
- */
-
- *top++ = firstCode;
-
- /*
- * Add a new string to the string table
- */
+ if (maxCode < (1 << MAX_LWZ_BITS)) {
+ /*
+ * If there's still room in our codes table, add a new entry.
+ * Otherwise don't, and keep using the current table.
+ * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a
+ * specification.
+ */
- prefix[maxCode] = oldCode;
- append[maxCode] = firstCode;
- maxCode++;
+ prefix[maxCode] = oldCode;
+ append[maxCode] = firstCode;
+ maxCode++;
+ }
/*
* maxCode tells us the maximum code value we can accept. If
@@ -1377,7 +1373,7 @@ static void
mInit(
unsigned char *string, /* string containing initial mmencoded data */
MFile *handle, /* mmdecode "file" handle */
- int length) /* Number of bytes in string */
+ size_t length) /* Number of bytes in string */
{
handle->data = string;
handle->state = 0;
@@ -1403,15 +1399,15 @@ mInit(
*----------------------------------------------------------------------
*/
-static int
+static size_t
Mread(
unsigned char *dst, /* where to put the result */
size_t chunkSize, /* size of each transfer */
size_t numChunks, /* number of chunks */
MFile *handle) /* mmdecode "file" handle */
{
- register int i, c;
- int count = chunkSize * numChunks;
+ int c;
+ size_t i, count = chunkSize * numChunks;
for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
*dst++ = c;
@@ -1552,7 +1548,7 @@ char64(
*----------------------------------------------------------------------
*/
-static int
+static size_t
Fread(
GIFImageConfig *gifConfPtr,
unsigned char *dst, /* where to put the result */
@@ -1566,19 +1562,20 @@ Fread(
if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
MFile *handle = (MFile *) chan;
- if (handle->length <= 0 || (size_t) handle->length < hunk*count) {
- return -1;
+ if ((handle->length + 1 < 2) || (handle->length < hunk*count)) {
+ return (size_t)-1;
}
- memcpy(dst, handle->data, (size_t) (hunk * count));
+ memcpy(dst, handle->data, hunk * count);
handle->data += hunk * count;
- return (int)(hunk * count);
+ handle->length -= hunk * count;
+ return hunk * count;
}
/*
* Otherwise we've got a real file to read.
*/
- return Tcl_Read(chan, (char *) dst, (int) (hunk * count));
+ return Tcl_Read(chan, (char *) dst, hunk * count);
}
/*
@@ -1657,22 +1654,22 @@ StringWriteGIF(
return result;
}
-static int
+static size_t
WriteToChannel(
ClientData clientData,
const char *bytes,
- int byteCount)
+ size_t byteCount)
{
Tcl_Channel handle = clientData;
return Tcl_Write(handle, bytes, byteCount);
}
-static int
+static size_t
WriteToByteArray(
ClientData clientData,
const char *bytes,
- int byteCount)
+ size_t byteCount)
{
Tcl_Obj *objPtr = clientData;
Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount);
diff --git a/generic/tkImgListFormat.c b/generic/tkImgListFormat.c
new file mode 100644
index 0000000..4636c41
--- /dev/null
+++ b/generic/tkImgListFormat.c
@@ -0,0 +1,1141 @@
+/*
+ * tkImgListFormat.c --
+ *
+ * Implements the default image data format. I.e. the format used for
+ * [imageName data] and [imageName put] if no other format is specified.
+ *
+ * The default format consits of a list of scan lines (rows) with each
+ * list element being itself a list of pixels (or columns). For details,
+ * see the manpage photo.n
+ *
+ * This image format cannot read/write files, it is meant for string
+ * data only.
+ *
+ *
+ * Copyright (c) 1994 The Australian National University.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2002-2003 Donal K. Fellows
+ * Copyright (c) 2003 ActiveState Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * Authors:
+ * Paul Mackerras (paulus@cs.anu.edu.au),
+ * Department of Computer Science,
+ * Australian National University.
+ *
+ * Simon Bachmann (simonbachmann@bluewin.ch)
+ */
+
+
+#include "tkImgPhoto.h"
+
+/*
+ * Message to generate when an attempt to allocate memory for an image fails.
+ */
+
+#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
+ "not enough free memory for image buffer"
+
+
+/*
+ * Color name length limit: do not attempt to parse as color strings that are
+ * longer than this limit
+ */
+
+#define TK_PHOTO_MAX_COLOR_CHARS 99
+
+/*
+ * Symbols for the different formats of a color string.
+ */
+
+enum ColorFormatType {
+ COLORFORMAT_TKCOLOR,
+ COLORFORMAT_EMPTYSTRING,
+ COLORFORMAT_LIST,
+ COLORFORMAT_RGB1,
+ COLORFORMAT_RGB2,
+ COLORFORMAT_RGBA1,
+ COLORFORMAT_RGBA2
+};
+
+/*
+ * Names for the color format types above.
+ * Order must match the one in enum ColorFormatType
+ */
+
+static const char *const colorFormatNames[] = {
+ "tkcolor",
+ "emptystring",
+ "list",
+ "rgb-short",
+ "rgb",
+ "rgba-short",
+ "rgba",
+ NULL
+};
+
+/*
+ * The following data structure is used to return information from
+ * ParseFormatOptions:
+ */
+
+struct FormatOptions {
+ int options; /* Individual bits indicate which options were
+ * specified - see below. */
+ Tcl_Obj *formatName; /* Name specified without an option. */
+ enum ColorFormatType colorFormat;
+ /* The color format type given with the
+ * -colorformat option */
+};
+
+/*
+ * Bit definitions for use with ParseFormatOptions: each bit is set in the
+ * allowedOptions parameter on a call to ParseFormatOptions if that option
+ * is allowed for the current photo image subcommand. On return, the bit is
+ * set in the options field of the FormatOptions structure if that option
+ * was specified.
+ *
+ * OPT_COLORFORMAT: Set if -alpha option allowed/specified.
+ */
+
+#define OPT_COLORFORMAT 1
+
+/*
+ * List of format option names. The order here must match the order of
+ * declarations of the FMT_OPT_* constants above.
+ */
+
+static const char *const formatOptionNames[] = {
+ "-colorformat",
+ NULL
+};
+
+/*
+ * Forward declarations
+ */
+
+static int ParseFormatOptions(Tcl_Interp *interp, int allowedOptions,
+ int objc, Tcl_Obj *const objv[], int *indexPtr,
+ struct FormatOptions *optPtr);
+static Tcl_Obj *GetBadOptMsg(const char *badValue, int allowedOpts);
+static int StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString,
+ int *widthPtr, int *heightPtr, Tcl_Interp *interp);
+static int StringReadDef(Tcl_Interp *interp, Tcl_Obj *data,
+ Tcl_Obj *formatString, Tk_PhotoHandle imageHandle,
+ int destX, int destY, int width, int height,
+ int srcX, int srcY);
+static int StringWriteDef(Tcl_Interp *interp,
+ Tcl_Obj *formatString,
+ Tk_PhotoImageBlock *blockPtr);
+static int ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj,
+ Display *display, Colormap colormap, unsigned char *redPtr,
+ unsigned char *greenPtr, unsigned char *bluePtr,
+ unsigned char *alphaPtr);
+static int ParseColorAsList(Tcl_Interp *interp, const char *colorString,
+ int colorStrLen, unsigned char *redPtr,
+ unsigned char *greenPtr, unsigned char *bluePtr,
+ unsigned char *alphaPtr);
+static int ParseColorAsHex(Tcl_Interp *interp, const char *colorString,
+ int colorStrLen, Display *display, Colormap colormap,
+ unsigned char *redPtr, unsigned char *greenPtr,
+ unsigned char *bluePtr, unsigned char *alphaPtr);
+static int ParseColorAsStandard(Tcl_Interp *interp,
+ const char *colorString, int colorStrLen,
+ Display *display, Colormap colormap,
+ unsigned char *redPtr, unsigned char *greenPtr,
+ unsigned char *bluePtr, unsigned char *alphaPtr);
+
+/*
+ * The format record for the default image handler
+ */
+
+Tk_PhotoImageFormat tkImgFmtDefault = {
+ "default", /* name */
+ NULL, /* fileMatchProc: format doesn't support file ops */
+ StringMatchDef, /* stringMatchProc */
+ NULL, /* fileReadProc: format doesn't support file read */
+ StringReadDef, /* stringReadProc */
+ NULL, /* fileWriteProc: format doesn't support file write */
+ StringWriteDef /* stringWriteProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseFormatOptions --
+ *
+ * Parse the options passed to the image format handler.
+ *
+ * Results:
+ * On success, the structure pointed to by optPtr is filled with the
+ * values passed or with the defaults and TCL_OK returned.
+ * If an error occurs, leaves an error message in interp and returns
+ * TCL_ERROR.
+ *
+ * Side effects:
+ * The value in *indexPtr is updated to the index of the fist
+ * element in argv[] that does not look like an option/value, or to
+ * argc if parsing reached the end of argv[].
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseFormatOptions(
+ Tcl_Interp *interp, /* For error messages */
+ int allowedOptions, /* Bitfield specifying which options are
+ * to be considered allowed */
+ int objc, /* Number of elements in argv[] */
+ Tcl_Obj *const objv[], /* The arguments to parse */
+ int *indexPtr, /* Index giving the first element to
+ * parse. The value is updated to the
+ * index where parsing ended */
+ struct FormatOptions *optPtr) /* Parsed option values are written to
+ * this struct */
+
+{
+ int index, optIndex, typeIndex, first;
+ const char *option;
+
+ first = 1;
+
+ /*
+ * Fill in default values
+ */
+ optPtr->options = 0;
+ optPtr->formatName = NULL;
+ optPtr->colorFormat = COLORFORMAT_RGB2;
+ for (index = *indexPtr; index < objc; *indexPtr = ++index) {
+ int optionExists;
+
+ /*
+ * The first value can be the format handler's name. It goes to
+ * optPtr->name.
+ */
+ option = Tcl_GetString(objv[index]);
+ if (option[0] != '-') {
+ if (first) {
+ optPtr->formatName = objv[index];
+ first = 0;
+ continue;
+ } else {
+ break;
+ }
+ }
+ first = 0;
+
+ /*
+ * Check if option is known and allowed
+ */
+
+ optionExists = 1;
+ if (Tcl_GetIndexFromObj(NULL, objv[index], formatOptionNames,
+ "format option", 0, &optIndex) != TCL_OK) {
+ optionExists = 0;
+ }
+ if (!optionExists || !((1 << optIndex) & allowedOptions)) {
+ Tcl_SetObjResult(interp, GetBadOptMsg(Tcl_GetString(objv[index]),
+ allowedOptions));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Option-specific checks
+ */
+
+ switch (1 << optIndex) {
+ case OPT_COLORFORMAT:
+ *indexPtr = ++index;
+ if (index >= objc) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option "
+ "requires a value", Tcl_GetString(objv[index - 1])));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "MISSING_VALUE", NULL);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "",
+ TCL_EXACT, &typeIndex) != TCL_OK
+ || (typeIndex != COLORFORMAT_LIST
+ && typeIndex != COLORFORMAT_RGB2
+ && typeIndex != COLORFORMAT_RGBA2) ) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format "
+ "\"%s\": must be rgb, rgba, or list",
+ Tcl_GetString(objv[index])));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "BAD_COLOR_FORMAT", NULL);
+ return TCL_ERROR;
+ }
+ optPtr->colorFormat = typeIndex;
+ break;
+ default:
+ Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough");
+ }
+
+ /*
+ * Add option to bitfield in optPtr
+ */
+ optPtr->options |= (1 << optIndex);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetBadOptMsg --
+ *
+ * Build a Tcl_Obj containing an error message in the form "bad option
+ * "xx": must be y, or z", based on the bits set in allowedOpts.
+ *
+ * Results:
+ * A Tcl Object containig the error message.
+ *
+ * Side effects:
+ * None
+ *----------------------------------------------------------------------
+ */
+static Tcl_Obj *
+GetBadOptMsg(
+ const char *badValue, /* the erroneous option */
+ int allowedOpts) /* bitfield specifying the allowed options */
+{
+ int i, bit;
+ Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue);
+
+ if (allowedOpts == 0) {
+ Tcl_AppendToObj(resObj, "no options allowed", -1);
+ } else {
+ Tcl_AppendToObj(resObj, "must be ", -1);
+ bit = 1;
+ for (i = 0; formatOptionNames[i] != NULL; i++) {
+ if (allowedOpts & bit) {
+ if (allowedOpts & (bit -1)) {
+ /*
+ * not the first option
+ */
+ if (allowedOpts & ~((bit << 1) - 1)) {
+ /*
+ * not the last option
+ */
+ Tcl_AppendToObj(resObj, ", ", -1);
+ } else {
+ Tcl_AppendToObj(resObj, ", or ", -1);
+ }
+ }
+ Tcl_AppendToObj(resObj, formatOptionNames[i], -1);
+ }
+ bit <<=1;
+ }
+ }
+ return resObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringMatchDef --
+ *
+ * Default string match function. Test if image data in string form
+ * appears to be in the default list-of-list-of-pixel-data format
+ * accepted by the "<img> put" command.
+ *
+ * Results:
+ * If thte data is in the default format, writes the size of the image
+ * to widthPtr and heightPtr and returns 1. Otherwise, leaves an error
+ * message in interp (if not NULL) and returns 0.
+ * Note that this function does not parse all data points. A return
+ * value of 1 does not guarantee that the data can be read without
+ * errors.
+ *
+ * Side effects:
+ * None
+ *----------------------------------------------------------------------
+ */
+static int
+StringMatchDef(
+ Tcl_Obj *data, /* The data to check */
+ Tcl_Obj *formatString, /* Value of the -format option, not used here */
+ int *widthPtr, /* Width of image is written to this location */
+ int *heightPtr, /* Height of image is written to this location */
+ Tcl_Interp *interp) /* Error messages are left in this interpreter */
+{
+ int y, rowCount, colCount, curColCount;
+ unsigned char dummy;
+ Tcl_Obj **rowListPtr, *pixelData;
+
+ /*
+ * See if data can be parsed as a list, if every element is itself a valid
+ * list and all sublists have the same length.
+ */
+
+ if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
+ != TCL_OK) {
+ return 0;
+ }
+ if (rowCount == 0) {
+ /*
+ * empty list is valid data
+ */
+
+ *widthPtr = 0;
+ *heightPtr = 0;
+ return 1;
+ }
+ colCount = -1;
+ for (y = 0; y < rowCount; y++) {
+ if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) {
+ return 0;
+ }
+ if (colCount < 0) {
+ colCount = curColCount;
+ } else if (curColCount != colCount) {
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %d: "
+ "all rows must have the same number of elements", y));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_DATA", NULL);
+ }
+ return 0;
+ }
+ }
+
+ /*
+ * Data in base64 encoding (or even binary data), might actually pass
+ * these tests. To avoid parsing it as list of lists format, check one
+ * pixel for validity.
+ */
+ if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) {
+ return 0;
+ }
+ if (Tcl_GetCharLength(pixelData) > TK_PHOTO_MAX_COLOR_CHARS) {
+ return 0;
+ }
+ if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)),
+ Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy)
+ != TCL_OK) {
+ return 0;
+ }
+
+ /*
+ * Looks like we have valid data for this format.
+ * We do not check any pixel values - that's the job of ImgStringRead()
+ */
+
+ *widthPtr = colCount;
+ *heightPtr = rowCount;
+
+ return 1;
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringReadDef --
+ *
+ * String read function for default format. (see manpage for details on
+ * the format).
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * If the data has valid format, write it to the image identified by
+ * imageHandle.
+ * If the image data cannot be parsed, an error message is left in
+ * interp.
+ *
+ *----------------------------------------------------------------------
+*/
+
+static int
+StringReadDef(
+ Tcl_Interp *interp, /* leave error messages here */
+ Tcl_Obj *data, /* the data to parse */
+ Tcl_Obj *formatString, /* value of the -format option */
+ Tk_PhotoHandle imageHandle, /* write data to this image */
+ int destX, int destY, /* start writing data at this point
+ * in destination image*/
+ int width, int height, /* dimensions of area to write to */
+ int srcX, int srcY) /* start reading source data at these
+ * coordinates */
+{
+ Tcl_Obj **rowListPtr, **colListPtr;
+ Tcl_Obj **objv;
+ int objc;
+ unsigned char *curPixelPtr;
+ int x, y, rowCount, colCount, curColCount;
+ Tk_PhotoImageBlock srcBlock;
+ Display *display;
+ Colormap colormap;
+ struct FormatOptions opts;
+ int optIndex;
+
+ /*
+ * Parse format suboptions
+ * We don't use any format suboptions, but we still need to provide useful
+ * error messages if suboptions were specified.
+ */
+
+ memset(&opts, 0, sizeof(opts));
+ if (formatString != NULL) {
+ if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ optIndex = 0;
+ if (ParseFormatOptions(interp, 0, objc, objv, &optIndex, &opts)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (optIndex < objc) {
+ Tcl_SetObjResult(interp,
+ GetBadOptMsg(Tcl_GetString(objv[optIndex]), 0));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ /*
+ * Check input data
+ */
+
+ if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
+ != TCL_OK ) {
+ return TCL_ERROR;
+ }
+ if ( rowCount > 0 && Tcl_ListObjLength(interp, rowListPtr[0], &colCount)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (width <= 0 || height <= 0 || rowCount == 0 || colCount == 0) {
+ /*
+ * No changes with zero sized input or zero sized output region
+ */
+
+ return TCL_OK;
+ }
+ if (srcX < 0 || srcY < 0 || srcX >= rowCount || srcY >= colCount) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("source coordinates out of range"));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Memory allocation overflow protection.
+ * May not be able to trigger/ demo / test this.
+ */
+
+ if (colCount > (int)(UINT_MAX / 4 / rowCount)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "photo image dimensions exceed Tcl memory limits"));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "OVERFLOW", NULL);
+ return TCL_OK;
+ }
+
+ /*
+ * Read data and put it to imageHandle
+ */
+
+ srcBlock.width = colCount - srcX;
+ srcBlock.height = rowCount - srcY;
+ srcBlock.pixelSize = 4;
+ srcBlock.pitch = srcBlock.width * 4;
+ srcBlock.offset[0] = 0;
+ srcBlock.offset[1] = 1;
+ srcBlock.offset[2] = 2;
+ srcBlock.offset[3] = 3;
+ srcBlock.pixelPtr = attemptckalloc(srcBlock.pitch * srcBlock.height);
+ if (srcBlock.pixelPtr == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(TK_PHOTO_ALLOC_FAILURE_MESSAGE));
+ Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
+ return TCL_ERROR;
+ }
+ curPixelPtr = srcBlock.pixelPtr;
+ display = Tk_Display(Tk_MainWindow(interp));
+ colormap = Tk_Colormap(Tk_MainWindow(interp));
+ for (y = srcY; y < rowCount; y++) {
+ /*
+ * We don't test the length of row, as that's been done in
+ * ImgStringMatch()
+ */
+
+ if (Tcl_ListObjGetElements(interp, rowListPtr[y], &curColCount,
+ &colListPtr) != TCL_OK) {
+ goto errorExit;
+ }
+ for (x = srcX; x < colCount; x++) {
+ if (ParseColor(interp, colListPtr[x], display, colormap,
+ curPixelPtr, curPixelPtr + 1, curPixelPtr + 2,
+ curPixelPtr + 3) != TCL_OK) {
+ goto errorExit;
+ }
+ curPixelPtr += 4;
+ }
+ }
+
+ /*
+ * Write image data to destHandle
+ */
+ if (Tk_PhotoPutBlock(interp, imageHandle, &srcBlock, destX, destY,
+ width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
+ goto errorExit;
+ }
+
+ ckfree(srcBlock.pixelPtr);
+
+ return TCL_OK;
+
+ errorExit:
+ ckfree(srcBlock.pixelPtr);
+
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringWriteDef --
+ *
+ * String write function for default image data format. See the user
+ * documentation for details.
+ *
+ * Results:
+ * The converted data is set as the result of interp. Returns a standard
+ * Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringWriteDef(
+ Tcl_Interp *interp, /* For the result and errors */
+ Tcl_Obj *formatString, /* The value of the -format option */
+ Tk_PhotoImageBlock *blockPtr) /* The image data to convert */
+{
+ int greenOffset, blueOffset, alphaOffset, hasAlpha;
+ Tcl_Obj *result, **objv = NULL;
+ int objc, allowedOpts, optIndex;
+ struct FormatOptions opts;
+
+ /*
+ * Parse format suboptions
+ */
+ if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ allowedOpts = OPT_COLORFORMAT;
+ optIndex = 0;
+ if (ParseFormatOptions(interp, allowedOpts, objc, objv, &optIndex, &opts)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (optIndex < objc) {
+ Tcl_SetObjResult(interp,
+ GetBadOptMsg(Tcl_GetString(objv[optIndex]), allowedOpts));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
+ return TCL_ERROR;
+ }
+
+ greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
+ blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
+
+ /*
+ * A negative alpha offset signals that the image is fully opaque.
+ * That's not really documented anywhere, but it's the way it is!
+ */
+
+ if (blockPtr->offset[3] < 0) {
+ hasAlpha = 0;
+ alphaOffset = 0;
+ } else {
+ hasAlpha = 1;
+ alphaOffset = blockPtr->offset[3] - blockPtr->offset[0];
+ }
+
+ if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
+ int row, col;
+ Tcl_DString data, line;
+ char colorBuf[11];
+ unsigned char *pixelPtr;
+ unsigned char alphaVal = 255;
+
+ Tcl_DStringInit(&data);
+ for (row=0; row<blockPtr->height; row++) {
+ pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
+ + row * blockPtr->pitch;
+ Tcl_DStringInit(&line);
+ for (col=0; col<blockPtr->width; col++) {
+ if (hasAlpha) {
+ alphaVal = pixelPtr[alphaOffset];
+ }
+
+ /*
+ * We don't build lines as a list for #RGBA and #RGB. Since
+ * these color formats look like comments, the first element
+ * of the list would get quoted with an additional {} .
+ * While this is not a problem if the data is used as
+ * a list, it would cause problems if someone decides to parse
+ * it as a string (and it looks kinda strange)
+ */
+
+ switch (opts.colorFormat) {
+ case COLORFORMAT_RGB2:
+ sprintf(colorBuf, "#%02x%02x%02x ", pixelPtr[0],
+ pixelPtr[greenOffset], pixelPtr[blueOffset]);
+ Tcl_DStringAppend(&line, colorBuf, -1);
+ break;
+ case COLORFORMAT_RGBA2:
+ sprintf(colorBuf, "#%02x%02x%02x%02x ",
+ pixelPtr[0], pixelPtr[greenOffset],
+ pixelPtr[blueOffset], alphaVal);
+ Tcl_DStringAppend(&line, colorBuf, -1);
+ break;
+ case COLORFORMAT_LIST:
+ Tcl_DStringStartSublist(&line);
+ sprintf(colorBuf, "%d", pixelPtr[0]);
+ Tcl_DStringAppendElement(&line, colorBuf);
+ sprintf(colorBuf, "%d", pixelPtr[greenOffset]);
+ Tcl_DStringAppendElement(&line, colorBuf);
+ sprintf(colorBuf, "%d", pixelPtr[blueOffset]);
+ Tcl_DStringAppendElement(&line, colorBuf);
+ sprintf(colorBuf, "%d", alphaVal);
+ Tcl_DStringAppendElement(&line, colorBuf);
+ Tcl_DStringEndSublist(&line);
+ break;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
+ }
+ pixelPtr += blockPtr->pixelSize;
+ }
+ if (opts.colorFormat != COLORFORMAT_LIST) {
+ /*
+ * For the #XXX formats, we need to remove the last
+ * whitespace.
+ */
+
+ *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1)
+ = '\0';
+ }
+ Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line));
+ Tcl_DStringFree(&line);
+ }
+ result = Tcl_NewStringObj(Tcl_DStringValue(&data), -1);
+ Tcl_DStringFree(&data);
+ } else {
+ result = Tcl_NewObj();
+ }
+
+ Tcl_SetObjResult(interp, result);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseColor --
+ *
+ * This function extracts color and alpha values from a string. It
+ * understands standard Tk color formats, alpha suffixes and the color
+ * formats specific to photo images, which include alpha data.
+ *
+ * Results:
+ * On success, writes red, green, blue and alpha values to the
+ * corresponding pointers. If the color spec contains no alpha
+ * information, 255 is taken as transparency value.
+ * If the input cannot be parsed, leaves an error message in
+ * interp. Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseColor(
+ Tcl_Interp *interp, /* error messages go there */
+ Tcl_Obj *specObj, /* the color data to parse */
+ Display *display, /* display of main window, needed to parse
+ * standard Tk colors */
+ Colormap colormap, /* colormap of current display */
+ unsigned char *redPtr, /* the result is written to these pointers */
+ unsigned char *greenPtr,
+ unsigned char *bluePtr,
+ unsigned char *alphaPtr)
+{
+ const char *specString;
+ size_t charCount;
+
+ /*
+ * Find out which color format we have
+ */
+
+ specString = TkGetStringFromObj(specObj, &charCount);
+
+ if (charCount == 0) {
+ /* Empty string */
+ *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
+ return TCL_OK;
+ }
+ if (charCount > TK_PHOTO_MAX_COLOR_CHARS) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color"));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_COLOR", NULL);
+ return TCL_ERROR;
+ }
+ if (specString[0] == '#') {
+ return ParseColorAsHex(interp, specString, charCount, display,
+ colormap, redPtr, greenPtr, bluePtr, alphaPtr);
+ }
+ if (ParseColorAsList(interp, specString, charCount,
+ redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) {
+ return TCL_OK;
+ }
+
+ /*
+ * Parsing the color as standard Tk color always is the last option tried
+ * because TkParseColor() is very slow with values it cannot parse.
+ */
+
+ Tcl_ResetResult(interp);
+ return ParseColorAsStandard(interp, specString, charCount, display,
+ colormap, redPtr, greenPtr, bluePtr, alphaPtr);
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseColorAsList --
+ *
+ * This function extracts color and alpha values from a list of 3 or 4
+ * integers (the list color format).
+ *
+ * Results:
+ * On success, writes red, green, blue and alpha values to the
+ * corresponding pointers. If the color spec contains no alpha
+ * information, 255 is taken as transparency value.
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * Does *not* leave error messages in interp. The reason is that
+ * it is not always possible to tell if the list format was even
+ * intended and thus it is hard to return meaningful messages.
+ * A general error message from the caller is probably the best
+ * alternative.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseColorAsList(
+ Tcl_Interp *interp, /* not used */
+ const char *colorString, /* the color data to parse */
+ int colorStrLen, /* length of the color string */
+ unsigned char *redPtr, /* the result is written to these pointers */
+ unsigned char *greenPtr,
+ unsigned char *bluePtr,
+ unsigned char *alphaPtr)
+{
+
+ /*
+ * This is kinda ugly. The code would be certainly nicer if it
+ * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with
+ * strtol() it's *much* faster.
+ */
+
+ const char *curPos;
+ int values[4];
+ int i;
+
+ curPos = colorString;
+ i = 0;
+
+ /*
+ * strtol can give false positives with a sequence of space chars.
+ * To avoid that, avance the pointer to the next non-blank char.
+ */
+
+ while(isspace(*curPos)) {
+ ++curPos;
+ }
+ while (i < 4 && *curPos != '\0') {
+ values[i] = strtol(curPos, (char **)&curPos, 0);
+ if (values[i] < 0 || values[i] > 255) {
+ return TCL_ERROR;
+ }
+ while(isspace(*curPos)) {
+ ++curPos;
+ }
+ ++i;
+ }
+
+ if (i < 3 || *curPos != '\0') {
+ return TCL_ERROR;
+ }
+ if (i < 4) {
+ values[3] = 255;
+ }
+
+ *redPtr = (unsigned char) values[0];
+ *greenPtr = (unsigned char) values[1];
+ *bluePtr = (unsigned char) values[2];
+ *alphaPtr = (unsigned char) values[3];
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseColorAsHex --
+ *
+ * This function extracts color and alpha values from a string
+ * starting with '#', followed by hex digits. It undestands both
+ * the #RGBA form and the #RBG (with optional suffix)
+ *
+ * Results:
+ * On success, writes red, green, blue and alpha values to the
+ * corresponding pointers. If the color spec contains no alpha
+ * information, 255 is taken as transparency value.
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseColorAsHex(
+ Tcl_Interp *interp, /* error messages are left here */
+ const char *colorString, /* the color data to parse */
+ int colorStrLen, /* length of the color string */
+ Display *display, /* display of main window */
+ Colormap colormap, /* colormap of current display */
+ unsigned char *redPtr, /* the result is written to these pointers */
+ unsigned char *greenPtr,
+ unsigned char *bluePtr,
+ unsigned char *alphaPtr)
+{
+ int i;
+ unsigned long int colorValue = 0;
+
+ if (colorStrLen - 1 != 4 && colorStrLen - 1 != 8) {
+ return ParseColorAsStandard(interp, colorString, colorStrLen,
+ display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
+ }
+ for (i = 1; i < colorStrLen; i++) {
+ if (!isxdigit(UCHAR(colorString[i]))) {
+ /*
+ * There still is a chance that this is a Tk color with
+ * an alpha suffix
+ */
+
+ return ParseColorAsStandard(interp, colorString, colorStrLen,
+ display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
+ }
+ }
+
+ colorValue = strtoul(colorString + 1, NULL, 16);
+ switch (colorStrLen - 1) {
+ case 4:
+ /* #RGBA format */
+ *redPtr = (unsigned char) ((colorValue >> 12) * 0x11);
+ *greenPtr = (unsigned char) (((colorValue >> 8) & 0xf) * 0x11);
+ *bluePtr = (unsigned char) (((colorValue >> 4) & 0xf) * 0x11);
+ *alphaPtr = (unsigned char) ((colorValue & 0xf) * 0x11);
+ return TCL_OK;
+ case 8:
+ /* #RRGGBBAA format */
+ *redPtr = (unsigned char) (colorValue >> 24);
+ *greenPtr = (unsigned char) ((colorValue >> 16) & 0xff);
+ *bluePtr = (unsigned char) ((colorValue >> 8) & 0xff);
+ *alphaPtr = (unsigned char) (colorValue & 0xff);
+ return TCL_OK;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
+ }
+
+ /* Shouldn't get here */
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseColorAsStandard --
+ *
+ * This function tries to split a color stirng in a color and a
+ * suffix part and to extract color and alpha values from them. The
+ * color part is treated as regular Tk color.
+ *
+ * Results:
+ * On success, writes red, green, blue and alpha values to the
+ * corresponding pointers. If the color spec contains no alpha
+ * information, 255 is taken as transparency value.
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseColorAsStandard(
+ Tcl_Interp *interp, /* error messages are left here */
+ const char *specString, /* the color data to parse */
+ int specStrLen, /* length of the color string */
+ Display *display, /* display of main window */
+ Colormap colormap, /* colormap of current display */
+ unsigned char *redPtr, /* the result is written to these pointers */
+ unsigned char *greenPtr,
+ unsigned char *bluePtr,
+ unsigned char *alphaPtr)
+{
+ XColor parsedColor;
+ const char *suffixString, *colorString;
+ char colorBuffer[TK_PHOTO_MAX_COLOR_CHARS + 1];
+ char *tmpString;
+ double fracAlpha;
+ unsigned int suffixAlpha;
+ int i;
+
+ /*
+ * Split color data string in color and suffix parts
+ */
+
+ if ((suffixString = strrchr(specString, '@')) == NULL
+ && ((suffixString = strrchr(specString, '#')) == NULL
+ || suffixString == specString)) {
+ suffixString = specString + specStrLen;
+ colorString = specString;
+ } else {
+ strncpy(colorBuffer, specString, suffixString - specString);
+ colorBuffer[suffixString - specString] = '\0';
+ colorString = (const char*)colorBuffer;
+ }
+
+ /*
+ * Try to parse as standard Tk color.
+ *
+ * We don't use Tk_GetColor() et al. here, as those functions
+ * migth return a color that does not exaxtly match the given name
+ * if the colormap is full. Also, we don't really want the color to be
+ * added to the colormap.
+ */
+
+ if ( ! TkParseColor(display, colormap, colorString, &parsedColor)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid color name \"%s\"", specString));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_COLOR", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * parse the Suffix
+ */
+
+ switch (suffixString[0]) {
+ case '\0':
+ suffixAlpha = 255;
+ break;
+ case '@':
+ fracAlpha = strtod(suffixString + 1, &tmpString);
+ if (*tmpString != '\0') {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha "
+ "suffix \"%s\": expected floating-point value",
+ suffixString));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID COLOR", NULL);
+ return TCL_ERROR;
+ }
+ if (fracAlpha < 0 || fracAlpha > 1) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha suffix"
+ " \"%s\": value must be in the range from 0 to 1",
+ suffixString));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_COLOR", NULL);
+ return TCL_ERROR;
+ }
+ suffixAlpha = (unsigned int) floor(fracAlpha * 255 + 0.5);
+ break;
+ case '#':
+ if (strlen(suffixString + 1) < 1 || strlen(suffixString + 1)> 2) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid alpha suffix \"%s\"", suffixString));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_COLOR", NULL);
+ return TCL_ERROR;
+ }
+ for (i = 1; i <= (int)strlen(suffixString + 1); i++) {
+ if ( ! isxdigit(UCHAR(suffixString[i]))) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid alpha suffix \"%s\": expected hex digit",
+ suffixString));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "INVALID_COLOR", NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (strlen(suffixString + 1) == 1) {
+ sscanf(suffixString, "#%1x", &suffixAlpha);
+ suffixAlpha *= 0x11;
+ } else {
+ sscanf(suffixString, "#%2x", &suffixAlpha);
+ }
+ break;
+ default:
+ Tcl_Panic("unexpected switch fallthrough");
+ }
+
+ *redPtr = (unsigned char) (parsedColor.red >> 8);
+ *greenPtr = (unsigned char) (parsedColor.green >> 8);
+ *bluePtr = (unsigned char) (parsedColor.blue >> 8);
+ *alphaPtr = (unsigned char) suffixAlpha;
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkDebugStringMatchDef --
+ *
+ * Debugging function for StringMatchDef. Basically just an alias for
+ * that function, intended to expose it directly to tests, as
+ * StirngMatchDef cannot be sufficiently tested otherwise.
+ *
+ * Results:
+ * See StringMatchDef.
+ *
+ * Side effects:
+ * None
+ *----------------------------------------------------------------------
+ */
+int
+TkDebugPhotoStringMatchDef(
+ Tcl_Interp *interp, /* Error messages are left in this interpreter */
+ Tcl_Obj *data, /* The data to check */
+ Tcl_Obj *formatString, /* Value of the -format option, not used here */
+ int *widthPtr, /* Width of image is written to this location */
+ int *heightPtr) /* Height of image is written to this location */
+{
+ return StringMatchDef(data, formatString, widthPtr, heightPtr, interp);
+}
+
+
+/* Local Variables: */
+/* mode: c */
+/* fill-column: 78 */
+/* c-basic-offset: 4 */
+/* tab-width: 8 */
+/* indent-tabs-mode: nil */
+/* End: */
diff --git a/generic/tkImgPNG.c b/generic/tkImgPNG.c
index 2ee515b..a620515 100644
--- a/generic/tkImgPNG.c
+++ b/generic/tkImgPNG.c
@@ -35,7 +35,7 @@ static const int startLine[8] = {
* Chunk type flags.
*/
-#define PNG_CF_ANCILLARY 0x10000000L /* Non-critical chunk (can ignore). */
+#define PNG_CF_ANCILLARY 0x20000000L /* Non-critical chunk (can ignore). */
#define PNG_CF_PRIVATE 0x00100000L /* Application-specific chunk. */
#define PNG_CF_RESERVED 0x00001000L /* Not used. */
#define PNG_CF_COPYSAFE 0x00000010L /* Opaque data safe for copying. */
@@ -127,7 +127,7 @@ typedef struct {
Tcl_Channel channel; /* Channel for from-file reads. */
Tcl_Obj *objDataPtr;
unsigned char *strDataBuf; /* Raw source data for from-string reads. */
- int strDataLen; /* Length of source data. */
+ size_t strDataLen; /* Length of source data. */
unsigned char *base64Data; /* base64 encoded string data. */
unsigned char base64Bits; /* Remaining bits from last base64 read. */
unsigned char base64State; /* Current state of base64 decoder. */
@@ -215,16 +215,16 @@ static inline unsigned char Paeth(int a, int b, int c);
static int ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
PNGImage *pngPtr);
static int ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
- unsigned char *destPtr, int destSz,
+ unsigned char *destPtr, size_t destSz,
unsigned long *crcPtr);
static int ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
- unsigned char *destPtr, int destSz,
+ unsigned char *destPtr, size_t destSz,
unsigned long *crcPtr);
static int ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
- unsigned char *destPtr, int destSz,
+ unsigned char *destPtr, size_t destSz,
unsigned long *crcPtr);
static int ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
- int *sizePtr, unsigned long *typePtr,
+ size_t *sizePtr, unsigned long *typePtr,
unsigned long *crcPtr);
static int ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
int chunkSz, unsigned long crc);
@@ -251,9 +251,9 @@ static inline int WriteByte(Tcl_Interp *interp, PNGImage *pngPtr,
unsigned char c, unsigned long *crcPtr);
static inline int WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr,
unsigned long chunkType,
- const unsigned char *dataPtr, int dataSize);
+ const unsigned char *dataPtr, size_t dataSize);
static int WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
- const unsigned char *srcPtr, int srcSz,
+ const unsigned char *srcPtr, size_t srcSz,
unsigned long *crcPtr);
static int WriteExtraChunks(Tcl_Interp *interp,
PNGImage *pngPtr);
@@ -320,7 +320,7 @@ InitPNGImage(
Tcl_IncrRefCount(objPtr);
pngPtr->objDataPtr = objPtr;
pngPtr->strDataBuf =
- Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
+ TkGetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
}
/*
@@ -335,7 +335,7 @@ InitPNGImage(
if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB,
TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) {
- if (interp) {
+ if (interp) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"zlib initialization failed", -1));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
@@ -431,7 +431,7 @@ ReadBase64(
Tcl_Interp *interp,
PNGImage *pngPtr,
unsigned char *destPtr,
- int destSz,
+ size_t destSz,
unsigned long *crcPtr)
{
static const unsigned char from64[] = {
@@ -556,14 +556,14 @@ ReadByteArray(
Tcl_Interp *interp,
PNGImage *pngPtr,
unsigned char *destPtr,
- int destSz,
+ size_t destSz,
unsigned long *crcPtr)
{
/*
* Check to make sure the number of requested bytes are available.
*/
- if (pngPtr->strDataLen < destSz) {
+ if ((size_t)pngPtr->strDataLen < destSz) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"unexpected end of image data", -1));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
@@ -571,7 +571,7 @@ ReadByteArray(
}
while (destSz) {
- int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);
+ size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);
memcpy(destPtr, pngPtr->strDataBuf, blockSz);
@@ -614,7 +614,7 @@ ReadData(
Tcl_Interp *interp,
PNGImage *pngPtr,
unsigned char *destPtr,
- int destSz,
+ size_t destSz,
unsigned long *crcPtr)
{
if (pngPtr->base64Data) {
@@ -624,10 +624,10 @@ ReadData(
}
while (destSz) {
- int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);
+ size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);
- blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
- if (blockSz < 0) {
+ blockSz = (size_t)Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
+ if (blockSz == (size_t)-1) {
/* TODO: failure info... */
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"channel read failed: %s", Tcl_PosixError(interp)));
@@ -859,7 +859,7 @@ static int
ReadChunkHeader(
Tcl_Interp *interp,
PNGImage *pngPtr,
- int *sizePtr,
+ size_t *sizePtr,
unsigned long *typePtr,
unsigned long *crcPtr)
{
@@ -984,7 +984,7 @@ ReadChunkHeader(
*/
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "encountered an unsupported criticial chunk type",
+ "encountered an unsupported critical chunk type",
-1));
} else {
char typeString[5];
@@ -995,7 +995,7 @@ ReadChunkHeader(
typeString[3] = (char) (chunkType & 255);
typeString[4] = '\0';
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "encountered an unsupported criticial chunk type"
+ "encountered an unsupported critical chunk type"
" \"%s\"", typeString));
}
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
@@ -1240,7 +1240,7 @@ ReadIHDR(
{
unsigned char sigBuf[PNG_SIG_SZ];
unsigned long chunkType;
- int chunkSz;
+ size_t chunkSz;
unsigned long crc;
unsigned long width, height;
int mismatch;
@@ -1264,7 +1264,7 @@ ReadIHDR(
*/
if (mismatch && pngPtr->strDataBuf) {
- pngPtr->strDataBuf = Tcl_GetByteArrayFromObj(pngPtr->objDataPtr,
+ pngPtr->strDataBuf = TkGetByteArrayFromObj(pngPtr->objDataPtr,
&pngPtr->strDataLen);
pngPtr->base64Data = pngPtr->strDataBuf;
@@ -2098,7 +2098,7 @@ ReadIDAT(
*/
while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
- int len1, len2;
+ size_t len1, len2;
/*
* Read another block of input into the zlib stream if data remains.
@@ -2147,14 +2147,14 @@ ReadIDAT(
*/
getNextLine:
- Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len1);
+ TkGetByteArrayFromObj(pngPtr->thisLineObj, &len1);
if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj,
pngPtr->phaseSize - len1) == TCL_ERROR) {
return TCL_ERROR;
}
- Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len2);
+ TkGetByteArrayFromObj(pngPtr->thisLineObj, &len2);
- if (len2 == pngPtr->phaseSize) {
+ if (len2 == (size_t)pngPtr->phaseSize) {
if (pngPtr->phase > 7) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"extra data after final scan line of final phase",
@@ -2245,10 +2245,10 @@ ApplyAlpha(
p += offset;
if (16 == pngPtr->bitDepth) {
- register int channel;
+ register unsigned int channel;
while (p < endPtr) {
- channel = (unsigned char)
+ channel = (unsigned int)
(((p[0] << 8) | p[1]) * pngPtr->alpha);
*p++ = (unsigned char) (channel >> 8);
@@ -2383,7 +2383,7 @@ DecodePNG(
int destY)
{
unsigned long chunkType;
- int chunkSz;
+ size_t chunkSz;
unsigned long crc;
/*
@@ -2768,7 +2768,7 @@ StringMatchPNG(
InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE);
- png.strDataBuf = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen);
+ png.strDataBuf = TkGetByteArrayFromObj(pObjData, &png.strDataLen);
if (ReadIHDR(interp, &png) == TCL_OK) {
*widthPtr = png.block.width;
@@ -2846,7 +2846,7 @@ WriteData(
Tcl_Interp *interp,
PNGImage *pngPtr,
const unsigned char *srcPtr,
- int srcSz,
+ size_t srcSz,
unsigned long *crcPtr)
{
if (!srcPtr || !srcSz) {
@@ -2863,12 +2863,12 @@ WriteData(
*/
if (pngPtr->objDataPtr) {
- int objSz;
+ size_t objSz;
unsigned char *destPtr;
- Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz);
+ TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);
- if (objSz > INT_MAX - srcSz) {
+ if (objSz + srcSz > INT_MAX) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"image too large to store completely in byte array", -1));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
@@ -2885,7 +2885,7 @@ WriteData(
}
memcpy(destPtr+objSz, srcPtr, srcSz);
- } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) < 0) {
+ } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"write to channel failed: %s", Tcl_PosixError(interp)));
return TCL_ERROR;
@@ -2961,7 +2961,7 @@ WriteChunk(
PNGImage *pngPtr,
unsigned long chunkType,
const unsigned char *dataPtr,
- int dataSize)
+ size_t dataSize)
{
unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
int result = TCL_OK;
@@ -3132,9 +3132,10 @@ WriteIDAT(
PNGImage *pngPtr,
Tk_PhotoImageBlock *blockPtr)
{
- int rowNum, flush = TCL_ZLIB_NO_FLUSH, outputSize, result;
+ int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
Tcl_Obj *outputObj;
unsigned char *outputBytes;
+ size_t outputSize;
/*
* Filter and compress each row one at a time.
@@ -3226,7 +3227,7 @@ WriteIDAT(
outputObj = Tcl_NewObj();
(void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1);
- outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize);
+ outputBytes = TkGetByteArrayFromObj(outputObj, &outputSize);
result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
Tcl_DecrRefCount(outputObj);
return result;
diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c
index 6f084f0..d6ec63c 100644
--- a/generic/tkImgPPM.c
+++ b/generic/tkImgPPM.c
@@ -141,7 +141,8 @@ FileReadPPM(
* image being read. */
{
int fileWidth, fileHeight, maxIntensity;
- int nLines, nBytes, h, type, count, bytesPerChannel = 1;
+ int nLines, h, type, bytesPerChannel = 1;
+ size_t nBytes, count;
unsigned char *pixelPtr;
Tk_PhotoImageBlock block;
@@ -285,7 +286,8 @@ FileWritePPM(
Tk_PhotoImageBlock *blockPtr)
{
Tcl_Channel chan;
- int w, h, greenOffset, blueOffset, nBytes;
+ int w, h, greenOffset, blueOffset;
+ size_t nBytes;
unsigned char *pixelPtr, *pixLinePtr;
char header[16 + TCL_INTEGER_SPACE * 2];
@@ -315,16 +317,16 @@ FileWritePPM(
if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
&& (blockPtr->pitch == (blockPtr->width * 3))) {
nBytes = blockPtr->height * blockPtr->pitch;
- if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
+ if ((size_t)Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
goto writeerror;
}
} else {
for (h = blockPtr->height; h > 0; h--) {
pixelPtr = pixLinePtr;
for (w = blockPtr->width; w > 0; w--) {
- if ( Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 ||
- Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1)==-1 ||
- Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) ==-1) {
+ if (Tcl_Write(chan,(char *)&pixelPtr[0], 1) == TCL_IO_FAILURE ||
+ Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == TCL_IO_FAILURE ||
+ Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == TCL_IO_FAILURE) {
goto writeerror;
}
pixelPtr += blockPtr->pixelSize;
@@ -762,10 +764,11 @@ ReadPPMStringHeader(
{
#define BUFFER_SIZE 1000
char buffer[BUFFER_SIZE], c;
- int i, numFields, dataSize, type = 0;
+ int i, numFields, type = 0;
+ size_t dataSize;
unsigned char *dataBuffer;
- dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize);
+ dataBuffer = TkGetByteArrayFromObj(dataPtr, &dataSize);
/*
* Read 4 space-separated fields from the string, ignoring comments (any
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index 666a9b0..13e6bbf 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -110,7 +110,7 @@ TkImgPhotoConfigureInstance(
*/
if (colorTablePtr != NULL) {
- colorTablePtr->liveRefCount -= 1;
+ colorTablePtr->liveRefCount--;
FreeColorTable(colorTablePtr, 0);
}
GetColorTable(instancePtr);
@@ -404,6 +404,9 @@ TkImgPhotoGet(
*
* Note that Win32 pre-defines those operations that we really need.
*
+ * Note that on MacOS, if the background comes from a Retina display
+ * then it will be twice as wide and twice as high as the photoimage.
+ *
*----------------------------------------------------------------------
*/
@@ -415,6 +418,13 @@ TkImgPhotoGet(
(UCHAR(r) << red_shift) | \
(UCHAR(g) << green_shift) | \
(UCHAR(b) << blue_shift) ))
+#ifdef MAC_OSX_TK
+#define RGBA(r, g, b, a) ((unsigned)( \
+ (UCHAR(r) << red_shift) | \
+ (UCHAR(g) << green_shift) | \
+ (UCHAR(b) << blue_shift) | \
+ (UCHAR(a) << alpha_shift) ))
+#endif
#define RGB15(r, g, b) ((unsigned)( \
(((r) * red_mask / 255) & red_mask) | \
(((g) * green_mask / 255) & green_mask) | \
@@ -433,7 +443,16 @@ BlendComplexAlpha(
unsigned long pixel;
unsigned char r, g, b, alpha, unalpha, *masterPtr;
unsigned char *alphaAr = iPtr->masterPtr->pix32;
-
+#if defined(MAC_OSX_TK)
+ /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels. Each
+ * block gets blended with the color of one image pixel. Since we iterate
+ * over the background subpixels, we reset the width and height to the
+ * subpixel dimensions of the background image we are using.
+ */
+ int pp = bgImg->pixelpower;
+ width = width << pp;
+ height = height << pp;
+#endif
/*
* This blending is an integer version of the Source-Over compositing rule
* (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
@@ -473,6 +492,13 @@ BlendComplexAlpha(
while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
blue_shift++;
}
+#ifdef MAC_OSX_TK
+ unsigned long alpha_mask = visual->alpha_mask;
+ unsigned long alpha_shift = 0;
+ while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
+ alpha_shift++;
+ }
+#endif
#endif /* !_WIN32 */
/*
@@ -532,9 +558,16 @@ BlendComplexAlpha(
#endif /* !_WIN32 && !MAC_OSX_TK */
for (y = 0; y < height; y++) {
+# if !defined(MAC_OSX_TK)
line = (y + yOffset) * iPtr->masterPtr->width;
for (x = 0; x < width; x++) {
masterPtr = alphaAr + ((line + x + xOffset) * 4);
+#else
+ /* Repeat each image row and column 2^pp times. */
+ line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
+ for (x = 0; x < width; x++) {
+ masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
+#endif
alpha = masterPtr[3];
/*
@@ -566,7 +599,11 @@ BlendComplexAlpha(
g = ALPHA_BLEND(ga, g, alpha, unalpha);
b = ALPHA_BLEND(ba, b, alpha, unalpha);
}
+#ifndef MAC_OSX_TK
XPutPixel(bgImg, x, y, RGB(r, g, b));
+#else
+ XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
+#endif
}
}
}
@@ -635,7 +672,9 @@ TkImgPhotoDisplay(
(unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap);
if (bgImg == NULL) {
Tk_DeleteErrorHandler(handler);
- /* We failed to get the image so draw without blending alpha. It's the best we can do */
+ /* We failed to get the image, so draw without blending alpha.
+ * It's the best we can do.
+ */
goto fallBack;
}
@@ -700,8 +739,7 @@ TkImgPhotoFree(
PhotoInstance *instancePtr = clientData;
ColorTable *colorPtr;
- instancePtr->refCount -= 1;
- if (instancePtr->refCount > 0) {
+ if (instancePtr->refCount-- > 1) {
return;
}
@@ -714,7 +752,7 @@ TkImgPhotoFree(
colorPtr = instancePtr->colorTablePtr;
if (colorPtr != NULL) {
- colorPtr->liveRefCount -= 1;
+ colorPtr->liveRefCount--;
}
Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
@@ -1097,8 +1135,7 @@ FreeColorTable(
* longer required by an instance. */
int force) /* Force free to happen immediately. */
{
- colorPtr->refCount--;
- if (colorPtr->refCount > 0) {
+ if (colorPtr->refCount-- > 1) {
return;
}
@@ -1241,7 +1278,7 @@ AllocateColors(
}
} else {
/*
- * Monochrome display - allocate the shades of grey we want.
+ * Monochrome display - allocate the shades of gray we want.
*/
for (i = 0; i < numColors; ++i) {
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index 3e03f3d..e1d54dd 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -48,6 +48,7 @@ struct SubcommandOptions {
* set in the options field of the SubcommandOptions structure if that option
* was specified.
*
+ * OPT_ALPHA: Set if -alpha option allowed/specified.
* OPT_BACKGROUND: Set if -format option allowed/specified.
* OPT_COMPOSITE: Set if -compositingrule option allowed/spec'd.
* OPT_FORMAT: Set if -format option allowed/specified.
@@ -56,18 +57,21 @@ struct SubcommandOptions {
* OPT_SHRINK: Set if -shrink option allowed/specified.
* OPT_SUBSAMPLE: Set if -subsample option allowed/spec'd.
* OPT_TO: Set if -to option allowed/specified.
+ * OPT_WITHALPHA: Set if -withalpha option allowed/specified.
* OPT_ZOOM: Set if -zoom option allowed/specified.
*/
-#define OPT_BACKGROUND 1
-#define OPT_COMPOSITE 2
-#define OPT_FORMAT 4
-#define OPT_FROM 8
-#define OPT_GRAYSCALE 0x10
-#define OPT_SHRINK 0x20
-#define OPT_SUBSAMPLE 0x40
-#define OPT_TO 0x80
-#define OPT_ZOOM 0x100
+#define OPT_ALPHA 1
+#define OPT_BACKGROUND 2
+#define OPT_COMPOSITE 4
+#define OPT_FORMAT 8
+#define OPT_FROM 0x10
+#define OPT_GRAYSCALE 0x20
+#define OPT_SHRINK 0x40
+#define OPT_SUBSAMPLE 0x80
+#define OPT_TO 0x100
+#define OPT_WITHALPHA 0x200
+#define OPT_ZOOM 0x400
/*
* List of option names. The order here must match the order of declarations
@@ -75,6 +79,7 @@ struct SubcommandOptions {
*/
static const char *const optionNames[] = {
+ "-alpha",
"-background",
"-compositingrule",
"-format",
@@ -83,6 +88,7 @@ static const char *const optionNames[] = {
"-shrink",
"-subsample",
"-to",
+ "-withalpha",
"-zoom",
NULL
};
@@ -182,9 +188,6 @@ static int ImgPhotoConfigureMaster(Tcl_Interp *interp,
static int ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr);
static int ImgPhotoSetSize(PhotoMaster *masterPtr, int width,
int height);
-static int ImgStringWrite(Tcl_Interp *interp,
- Tcl_Obj *formatString,
- Tk_PhotoImageBlock *blockPtr);
static char * ImgGetPhoto(PhotoMaster *masterPtr,
Tk_PhotoImageBlock *blockPtr,
struct SubcommandOptions *optPtr);
@@ -402,14 +405,13 @@ ImgPhotoCmd(
};
PhotoMaster *masterPtr = clientData;
- int result, index, x, y, width, height, dataWidth, dataHeight, listObjc;
+ int result, index, x, y, width, height;
struct SubcommandOptions options;
- Tcl_Obj **listObjv, **srcObjv;
unsigned char *pixelPtr;
Tk_PhotoImageBlock block;
- Tk_Window tkwin;
Tk_PhotoImageFormat *imageFormat;
- int imageWidth, imageHeight, matched, length, oldformat = 0;
+ size_t length;
+ int imageWidth, imageHeight, matched, oldformat = 0;
Tcl_Channel chan;
Tk_PhotoHandle srcHandle;
ThreadSpecificData *tsdPtr =
@@ -446,12 +448,12 @@ ImgPhotoCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option");
return TCL_ERROR;
}
- arg = Tcl_GetStringFromObj(objv[2], &length);
- if (strncmp(arg,"-data", (unsigned) length) == 0) {
+ arg = TkGetStringFromObj(objv[2], &length);
+ if (strncmp(arg,"-data", length) == 0) {
if (masterPtr->dataString) {
Tcl_SetObjResult(interp, masterPtr->dataString);
}
- } else if (strncmp(arg,"-format", (unsigned) length) == 0) {
+ } else if (strncmp(arg,"-format", length) == 0) {
if (masterPtr->format) {
Tcl_SetObjResult(interp, masterPtr->format);
}
@@ -495,9 +497,9 @@ ImgPhotoCmd(
return TCL_OK;
} else if (objc == 3) {
- const char *arg = Tcl_GetStringFromObj(objv[2], &length);
+ const char *arg = TkGetStringFromObj(objv[2], &length);
- if (length > 1 && !strncmp(arg, "-data", (unsigned) length)) {
+ if (length > 1 && !strncmp(arg, "-data", length)) {
Tcl_AppendResult(interp, "-data {} {} {}", NULL);
if (masterPtr->dataString) {
/*
@@ -511,7 +513,7 @@ ImgPhotoCmd(
}
return TCL_OK;
} else if (length > 1 &&
- !strncmp(arg, "-format", (unsigned) length)) {
+ !strncmp(arg, "-format", length)) {
Tcl_AppendResult(interp, "-format {} {} {}", NULL);
if (masterPtr->format) {
/*
@@ -573,6 +575,9 @@ ImgPhotoCmd(
if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
|| (options.fromX2 > block.width)
|| (options.fromY2 > block.height)) {
+ if (options.background) {
+ Tk_FreeColor(options.background);
+ }
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"coordinates for -from option extend outside source image",
-1));
@@ -622,35 +627,48 @@ ImgPhotoCmd(
}
/*
+ * Copy the image data over using Tk_PhotoPutZoomedBlock.
+ */
+
+ block.pixelPtr += options.fromX * block.pixelSize
+ + options.fromY * block.pitch;
+ block.width = options.fromX2 - options.fromX;
+ block.height = options.fromY2 - options.fromY;
+ result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
+ &block, options.toX, options.toY, options.toX2 - options.toX,
+ options.toY2 - options.toY, options.zoomX, options.zoomY,
+ options.subsampleX, options.subsampleY,
+ options.compositingRule);
+
+ /*
* Set the destination image size if the -shrink option was specified.
+ * This has to be done _after_ copying the data. Otherwise, if source
+ * and destination are the same image, block.pixelPtr would point to
+ * an invalid memory block (bug [5239fd749b]).
*/
if (options.options & OPT_SHRINK) {
if (ImgPhotoSetSize(masterPtr, options.toX2,
options.toY2) != TCL_OK) {
+ if (options.background) {
+ Tk_FreeColor(options.background);
+ }
Tcl_SetObjResult(interp, Tcl_NewStringObj(
TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
return TCL_ERROR;
}
}
-
- /*
- * Copy the image data over using Tk_PhotoPutZoomedBlock.
- */
-
- block.pixelPtr += options.fromX * block.pixelSize
- + options.fromY * block.pitch;
- block.width = options.fromX2 - options.fromX;
- block.height = options.fromY2 - options.fromY;
- return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
- &block, options.toX, options.toY, options.toX2 - options.toX,
- options.toY2 - options.toY, options.zoomX, options.zoomY,
- options.subsampleX, options.subsampleY,
- options.compositingRule);
+ Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
+ masterPtr->width, masterPtr->height);
+ if (options.background) {
+ Tk_FreeColor(options.background);
+ }
+ return result;
case PHOTO_DATA: {
- char *data;
+ char *data = NULL;
+ Tcl_Obj *freeObj = NULL;
/*
* photo data command - first parse and check any options given.
@@ -658,7 +676,7 @@ ImgPhotoCmd(
Tk_ImageStringWriteProc *stringWriteProc = NULL;
- index = 2;
+ index = 1;
memset(&options, 0, sizeof(options));
options.name = NULL;
options.format = NULL;
@@ -669,7 +687,7 @@ ImgPhotoCmd(
&index, objc, objv) != TCL_OK) {
return TCL_ERROR;
}
- if ((options.name != NULL) || (index < objc)) {
+ if ((options.name == NULL) || (index < objc)) {
Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
return TCL_ERROR;
}
@@ -691,50 +709,50 @@ ImgPhotoCmd(
options.fromX2 = masterPtr->width;
options.fromY2 = masterPtr->height;
}
+ if (!(options.options & OPT_FORMAT)) {
+ options.format = Tcl_NewStringObj("default", -1);
+ freeObj = options.format;
+ }
/*
* Search for an appropriate image string format handler.
*/
- if (options.options & OPT_FORMAT) {
- matched = 0;
- for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
- imageFormat = imageFormat->nextPtr) {
- if ((strncasecmp(Tcl_GetString(options.format),
- imageFormat->name, strlen(imageFormat->name)) == 0)) {
- matched = 1;
- if (imageFormat->stringWriteProc != NULL) {
- stringWriteProc = imageFormat->stringWriteProc;
- break;
- }
- }
- }
- if (stringWriteProc == NULL) {
- oldformat = 1;
- for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
- imageFormat = imageFormat->nextPtr) {
- if ((strncasecmp(Tcl_GetString(options.format),
- imageFormat->name,
- strlen(imageFormat->name)) == 0)) {
- matched = 1;
- if (imageFormat->stringWriteProc != NULL) {
- stringWriteProc = imageFormat->stringWriteProc;
- break;
- }
- }
- }
+ matched = 0;
+ for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
+ imageFormat = imageFormat->nextPtr) {
+ if ((strncasecmp(Tcl_GetString(options.format),
+ imageFormat->name, strlen(imageFormat->name)) == 0)) {
+ matched = 1;
+ if (imageFormat->stringWriteProc != NULL) {
+ stringWriteProc = imageFormat->stringWriteProc;
+ break;
+ }
}
- if (stringWriteProc == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "image string format \"%s\" is %s",
- Tcl_GetString(options.format),
- (matched ? "not supported" : "unknown")));
- Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
- Tcl_GetString(options.format), NULL);
- return TCL_ERROR;
+ }
+ if (stringWriteProc == NULL) {
+ oldformat = 1;
+ for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
+ imageFormat = imageFormat->nextPtr) {
+ if ((strncasecmp(Tcl_GetString(options.format),
+ imageFormat->name,
+ strlen(imageFormat->name)) == 0)) {
+ matched = 1;
+ if (imageFormat->stringWriteProc != NULL) {
+ stringWriteProc = imageFormat->stringWriteProc;
+ break;
+ }
+ }
}
- } else {
- stringWriteProc = ImgStringWrite;
+ }
+ if (stringWriteProc == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "image string format \"%s\" is %s",
+ Tcl_GetString(options.format),
+ (matched ? "not supported" : "unknown")));
+ Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
+ Tcl_GetString(options.format), NULL);
+ goto dataErrorExit;
}
/*
@@ -771,7 +789,22 @@ ImgPhotoCmd(
if (data) {
ckfree(data);
}
+ if (freeObj != NULL) {
+ Tcl_DecrRefCount(freeObj);
+ }
return result;
+
+ dataErrorExit:
+ if (options.background) {
+ Tk_FreeColor(options.background);
+ }
+ if (data) {
+ ckfree(data);
+ }
+ if (freeObj != NULL) {
+ Tcl_DecrRefCount(freeObj);
+ }
+ return TCL_ERROR;
}
case PHOTO_GET: {
@@ -779,12 +812,24 @@ ImgPhotoCmd(
* photo get command - first parse and check parameters.
*/
- Tcl_Obj *channels[3];
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ Tcl_Obj *channels[4];
+ int channelCount = 3;
+
+ index = 3;
+ memset(&options, 0, sizeof(options));
+ options.name = NULL;
+ if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA,
+ &index, objc, objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (options.name == NULL || index < objc) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?");
return TCL_ERROR;
}
+ if (options.options & OPT_WITHALPHA) {
+ channelCount = 4;
+ }
+
if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
return TCL_ERROR;
@@ -800,25 +845,29 @@ ImgPhotoCmd(
}
/*
- * Extract the value of the desired pixel and format it as a string.
+ * Extract the value of the desired pixel and format it as a list.
*/
pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
channels[0] = Tcl_NewIntObj(pixelPtr[0]);
channels[1] = Tcl_NewIntObj(pixelPtr[1]);
channels[2] = Tcl_NewIntObj(pixelPtr[2]);
- Tcl_SetObjResult(interp, Tcl_NewListObj(3, channels));
+ channels[3] = Tcl_NewIntObj(pixelPtr[3]);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
return TCL_OK;
}
- case PHOTO_PUT:
+ case PHOTO_PUT: {
+ Tcl_Obj *format, *data;
+
/*
- * photo put command - first parse the options and colors specified.
+ * photo put command - first parse the options.
*/
index = 2;
memset(&options, 0, sizeof(options));
options.name = NULL;
+ options.format = NULL;
if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
&index, objc, objv) != TCL_OK) {
return TCL_ERROR;
@@ -828,174 +877,50 @@ ImgPhotoCmd(
return TCL_ERROR;
}
- if (MatchStringFormat(interp, options.name ? objv[2]:NULL,
- options.format, &imageFormat, &imageWidth,
- &imageHeight, &oldformat) == TCL_OK) {
- Tcl_Obj *format, *data;
+ /*
+ * See if there's a format that can read the data
+ */
- if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
- options.toX2 = options.toX + imageWidth;
- options.toY2 = options.toY + imageHeight;
- }
- if (imageWidth > options.toX2 - options.toX) {
- imageWidth = options.toX2 - options.toX;
- }
- if (imageHeight > options.toY2 - options.toY) {
- imageHeight = options.toY2 - options.toY;
- }
- format = options.format;
- data = objv[2];
- if (oldformat) {
- if (format) {
- format = (Tcl_Obj *) Tcl_GetString(format);
- }
- data = (Tcl_Obj *) Tcl_GetString(data);
- }
- if (imageFormat->stringReadProc(interp, data, format,
- (Tk_PhotoHandle) masterPtr, options.toX, options.toY,
- imageWidth, imageHeight, 0, 0) != TCL_OK) {
- return TCL_ERROR;
- }
- masterPtr->flags |= IMAGE_CHANGED;
- return TCL_OK;
- }
- if (options.options & OPT_FORMAT) {
- return TCL_ERROR;
- }
- Tcl_ResetResult(interp);
- if (Tcl_ListObjGetElements(interp, options.name,
- &dataHeight, &srcObjv) != TCL_OK) {
+ if (MatchStringFormat(interp, objv[2], options.format, &imageFormat,
+ &imageWidth, &imageHeight, &oldformat) != TCL_OK) {
return TCL_ERROR;
}
- tkwin = Tk_MainWindow(interp);
- block.pixelPtr = NULL;
- dataWidth = 0;
- pixelPtr = NULL;
- for (y = 0; y < dataHeight; ++y) {
- if (Tcl_ListObjGetElements(interp, srcObjv[y],
- &listObjc, &listObjv) != TCL_OK) {
- break;
- }
-
- if (y == 0) {
- if (listObjc == 0) {
- /*
- * Lines must be non-empty...
- */
-
- break;
- }
- dataWidth = listObjc;
- /*
- * Memory allocation overflow protection.
- * May not be able to trigger/ demo / test this.
- */
-
- if (dataWidth > (int)((UINT_MAX/3) / dataHeight)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "photo image dimensions exceed Tcl memory limits", -1));
- Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
- "OVERFLOW", NULL);
- break;
- }
-
- pixelPtr = ckalloc(dataWidth * dataHeight * 3);
- block.pixelPtr = pixelPtr;
- } else if (listObjc != dataWidth) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "all elements of color list must have the same"
- " number of elements", -1));
- Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
- "NON_RECTANGULAR", NULL);
- break;
- }
-
- for (x = 0; x < dataWidth; ++x) {
- const char *colorString = Tcl_GetString(listObjv[x]);
- XColor color;
- int tmpr, tmpg, tmpb;
-
- /*
- * We do not use Tk_GetColorFromObj() because we absolutely do
- * not want to invoke the fallback code.
- */
- if (colorString[0] == '#') {
- if (isxdigit(UCHAR(colorString[1])) &&
- isxdigit(UCHAR(colorString[2])) &&
- isxdigit(UCHAR(colorString[3]))) {
- if (colorString[4] == '\0') {
- /* Got #rgb */
- sscanf(colorString+1, "%1x%1x%1x",
- &tmpr, &tmpg, &tmpb);
- *pixelPtr++ = tmpr * 0x11;
- *pixelPtr++ = tmpg * 0x11;
- *pixelPtr++ = tmpb * 0x11;
- continue;
- } else if (isxdigit(UCHAR(colorString[4])) &&
- isxdigit(UCHAR(colorString[5])) &&
- isxdigit(UCHAR(colorString[6])) &&
- colorString[7] == '\0') {
- /* Got #rrggbb */
- sscanf(colorString+1, "%2x%2x%2x",
- &tmpr, &tmpg, &tmpb);
- *pixelPtr++ = tmpr;
- *pixelPtr++ = tmpg;
- *pixelPtr++ = tmpb;
- continue;
- }
- }
- }
-
- if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
- colorString, &color)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't parse color \"%s\"", colorString));
- Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL);
- break;
- }
- *pixelPtr++ = color.red >> 8;
- *pixelPtr++ = color.green >> 8;
- *pixelPtr++ = color.blue >> 8;
- }
- if (x < dataWidth) {
- break;
- }
+ if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
+ options.toX2 = options.toX + imageWidth;
+ options.toY2 = options.toY + imageHeight;
}
- if (y < dataHeight || dataHeight == 0 || dataWidth == 0) {
- if (block.pixelPtr != NULL) {
- ckfree(block.pixelPtr);
- }
- if (y < dataHeight) {
- return TCL_ERROR;
+ if (imageWidth > options.toX2 - options.toX) {
+ imageWidth = options.toX2 - options.toX;
+ }
+ if (imageHeight > options.toY2 - options.toY) {
+ imageHeight = options.toY2 - options.toY;
+ }
+ format = options.format;
+ data = objv[2];
+ if (oldformat) {
+ if (format) {
+ format = (Tcl_Obj *) Tcl_GetString(format);
}
- return TCL_OK;
+ data = (Tcl_Obj *) Tcl_GetString(data);
}
+ if (imageFormat->stringReadProc(interp, data, format,
+ (Tk_PhotoHandle) masterPtr, options.toX, options.toY,
+ options.toX2 - options.toX,
+ options.toY2 - options.toY, 0, 0) != TCL_OK) {
+ return TCL_ERROR;
+ }
/*
- * Fill in default values for the -to option, then copy the block in
- * using Tk_PhotoPutBlock.
+ * SB: is the next line really needed? The stringReadProc
+ * writes image data with Tk_PhotoPutBlock(), which in turn
+ * takes care to notify the changed image and to set/unset the
+ * IMAGE_CHANGED bit.
*/
+ masterPtr->flags |= IMAGE_CHANGED;
- if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
- options.toX2 = options.toX + dataWidth;
- options.toY2 = options.toY + dataHeight;
- }
- block.width = dataWidth;
- block.height = dataHeight;
- block.pitch = dataWidth * 3;
- block.pixelSize = 3;
- block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
- block.offset[3] = 0;
- result = Tk_PhotoPutBlock(interp, masterPtr, &block,
- options.toX, options.toY, options.toX2 - options.toX,
- options.toY2 - options.toY,
- TK_PHOTO_COMPOSITE_SET);
- ckfree(block.pixelPtr);
- return result;
-
+ return TCL_OK;
+ }
case PHOTO_READ: {
Tcl_Obj *format;
@@ -1165,17 +1090,40 @@ ImgPhotoCmd(
switch ((enum transOptions) index) {
case PHOTO_TRANS_GET: {
- XRectangle testBox;
- TkRegion testRegion;
+ int boolMode;
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 3, objv, "x y");
+ /*
+ * parse fixed args and option
+ */
+
+ if (objc > 6 || objc < 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "x y ?-option?");
return TCL_ERROR;
}
if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
return TCL_ERROR;
}
+
+ index = 4;
+ memset(&options, 0, sizeof(options));
+ if (ParseSubcommandOptions(&options, interp,
+ OPT_ALPHA, &index, objc, objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index < objc) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown option \"%s\": must be -alpha",
+ Tcl_GetString(objv[index])));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
+ NULL);
+ return TCL_ERROR;
+ }
+ boolMode = 1;
+ if (options.options & OPT_ALPHA) {
+ boolMode = 0;
+ }
+
if ((x < 0) || (x >= masterPtr->width)
|| (y < 0) || (y >= masterPtr->height)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -1186,36 +1134,55 @@ ImgPhotoCmd(
return TCL_ERROR;
}
- testBox.x = x;
- testBox.y = y;
- testBox.width = 1;
- testBox.height = 1;
- /* What a way to do a test! */
- testRegion = TkCreateRegion();
- TkUnionRectWithRegion(&testBox, testRegion, testRegion);
- TkIntersectRegion(testRegion, masterPtr->validRegion, testRegion);
- TkClipBox(testRegion, &testBox);
- TkDestroyRegion(testRegion);
-
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
- testBox.width==0 && testBox.height==0));
+ /*
+ * Extract and return the desired value
+ */
+ pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
+ if (boolMode) {
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3]));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(pixelPtr[3]));
+ }
return TCL_OK;
}
case PHOTO_TRANS_SET: {
- int transFlag;
+ int newVal, boolMode;
XRectangle setBox;
+ TkRegion modRegion;
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "x y boolean");
+ /*
+ * Parse args and option, check for valid values
+ */
+
+ if (objc < 6 || objc > 7) {
+ Tcl_WrongNumArgs(interp, 3, objv, "x y newVal ?-option?");
return TCL_ERROR;
}
if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)
- || (Tcl_GetBooleanFromObj(interp, objv[5],
- &transFlag) != TCL_OK)) {
+ || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+
+ index = 5;
+ memset(&options, 0, sizeof(options));
+ if (ParseSubcommandOptions(&options, interp,
+ OPT_ALPHA, &index, objc, objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (index < objc) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown option \"%s\": must be -alpha",
+ Tcl_GetString(objv[index])));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
+ NULL);
return TCL_ERROR;
}
+ boolMode = 1;
+ if (options.options & OPT_ALPHA) {
+ boolMode = 0;
+ }
+
if ((x < 0) || (x >= masterPtr->width)
|| (y < 0) || (y >= masterPtr->height)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -1226,38 +1193,53 @@ ImgPhotoCmd(
return TCL_ERROR;
}
+ if (boolMode) {
+ if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (newVal < 0 || newVal > 255) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid alpha value \"%d\": "
+ "must be integer between 0 and 255", newVal));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
+ "BAD_VALUE", NULL);
+ return TCL_ERROR;
+ }
+ }
+
+ /*
+ * Set new alpha value for the pixel
+ */
+
+ pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
+ if (boolMode) {
+ pixelPtr[3] = newVal ? 0 : 255;
+ } else {
+ pixelPtr[3] = newVal;
+ }
+
+ /*
+ * Update the validRegion of the image
+ */
+
setBox.x = x;
setBox.y = y;
setBox.width = 1;
setBox.height = 1;
- pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
-
- if (transFlag) {
- /*
- * Make pixel transparent.
- */
-
- TkRegion clearRegion = TkCreateRegion();
-
- TkUnionRectWithRegion(&setBox, clearRegion, clearRegion);
- TkSubtractRegion(masterPtr->validRegion, clearRegion,
+ modRegion = TkCreateRegion();
+ TkUnionRectWithRegion(&setBox, modRegion, modRegion);
+ if (pixelPtr[3]) {
+ TkUnionRectWithRegion(&setBox, masterPtr->validRegion,
masterPtr->validRegion);
- TkDestroyRegion(clearRegion);
-
- /*
- * Set the alpha value correctly.
- */
-
- pixelPtr[3] = 0;
} else {
- /*
- * Make pixel opaque.
- */
-
- TkUnionRectWithRegion(&setBox, masterPtr->validRegion,
+ TkSubtractRegion(masterPtr->validRegion, modRegion,
masterPtr->validRegion);
- pixelPtr[3] = 255;
}
+ TkDestroyRegion(modRegion);
/*
* Inform the generic image code that the image
@@ -1459,13 +1441,18 @@ GetExtension(
*
* This function is invoked to process one of the options which may be
* specified for the photo image subcommands, namely, -from, -to, -zoom,
- * -subsample, -format, -shrink, and -compositingrule.
+ * -subsample, -format, -shrink, -compositingrule, -alpha, -boolean and
+ * -withalpha.
+ * Parsing starts at the index in *optIndexPtr and stops at the end of
+ * objv[] or at the first value that does not belong to an option.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * Fields in *optPtr get filled in.
+ * Fields in *optPtr get filled in. The value of optIndexPtr is updated
+ * to contain the index of the first element in argv[] that was not
+ * parsed, or argc if the end of objv[] was reached.
*
*----------------------------------------------------------------------
*/
@@ -1489,7 +1476,8 @@ ParseSubcommandOptions(
* TK_PHOTO_COMPOSITE_* constants. */
NULL
};
- int index, c, bit, currentBit, length;
+ size_t length;
+ int index, c, bit, currentBit;
int values[4], numValues, maxValues, argIndex;
const char *option, *expandedOption, *needed;
const char *const *listPtr;
@@ -1501,7 +1489,7 @@ ParseSubcommandOptions(
* optPtr->name.
*/
- expandedOption = option = Tcl_GetStringFromObj(objv[index], &length);
+ expandedOption = option = TkGetStringFromObj(objv[index], &length);
if (option[0] != '-') {
if (optPtr->name == NULL) {
optPtr->name = objv[index];
@@ -1519,7 +1507,7 @@ ParseSubcommandOptions(
currentBit = 1;
for (listPtr = optionNames; *listPtr != NULL; ++listPtr) {
if ((c == *listPtr[0])
- && (strncmp(option, *listPtr, (size_t) length) == 0)) {
+ && (strncmp(option, *listPtr, length) == 0)) {
expandedOption = *listPtr;
if (bit != 0) {
goto unknownOrAmbiguousOption;
@@ -1535,7 +1523,11 @@ ParseSubcommandOptions(
*/
if (!(allowedOptions & bit)) {
- goto unknownOrAmbiguousOption;
+ if (optPtr->name != NULL) {
+ goto unknownOrAmbiguousOption;
+ }
+ optPtr->name = objv[index];
+ continue;
}
/*
@@ -1584,7 +1576,8 @@ ParseSubcommandOptions(
return TCL_ERROR;
}
*optIndexPtr = index;
- } else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) {
+ } else if (bit == OPT_TO || bit == OPT_FROM
+ || bit == OPT_SUBSAMPLE || bit == OPT_ZOOM) {
const char *val;
maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2;
@@ -1765,7 +1758,8 @@ ImgPhotoConfigureMaster(
const char *oldFileString, *oldPaletteString;
Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;
Tcl_Obj *tempdata, *tempformat;
- int length, i, j, result, imageWidth, imageHeight, oldformat;
+ size_t length;
+ int i, j, result, imageWidth, imageHeight, oldformat;
double oldGamma;
Tcl_Channel chan;
Tk_PhotoImageFormat *imageFormat;
@@ -1773,10 +1767,10 @@ ImgPhotoConfigureMaster(
args = ckalloc((objc + 1) * sizeof(char *));
for (i = 0, j = 0; i < objc; i++,j++) {
- args[j] = Tcl_GetStringFromObj(objv[i], &length);
+ args[j] = TkGetStringFromObj(objv[i], &length);
if ((length > 1) && (args[j][0] == '-')) {
if ((args[j][1] == 'd') &&
- !strncmp(args[j], "-data", (size_t) length)) {
+ !strncmp(args[j], "-data", length)) {
if (++i < objc) {
data = objv[i];
j--;
@@ -1789,7 +1783,7 @@ ImgPhotoConfigureMaster(
return TCL_ERROR;
}
} else if ((args[j][1] == 'f') &&
- !strncmp(args[j], "-format", (size_t) length)) {
+ !strncmp(args[j], "-format", length)) {
if (++i < objc) {
format = objv[i];
j--;
@@ -1852,9 +1846,10 @@ ImgPhotoConfigureMaster(
* Force into ByteArray format, which most (all) image handlers will
* use anyway. Empty length means ignore the -data option.
*/
+ size_t bytesize;
- (void) Tcl_GetByteArrayFromObj(data, &length);
- if (length) {
+ (void) TkGetByteArrayFromObj(data, &bytesize);
+ if (bytesize) {
Tcl_IncrRefCount(data);
} else {
data = NULL;
@@ -1870,8 +1865,8 @@ ImgPhotoConfigureMaster(
* object.
*/
- (void) Tcl_GetStringFromObj(format, &length);
- if (length) {
+ (void) Tcl_GetString(format);
+ if (format->length) {
Tcl_IncrRefCount(format);
} else {
format = NULL;
@@ -2537,7 +2532,7 @@ MatchStringFormat(
int *oldformat) /* Returns 1 if the old image API is used. */
{
int matched = 0, useoldformat = 0;
- Tk_PhotoImageFormat *formatPtr;
+ Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL;
ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
const char *formatString = NULL;
@@ -2553,6 +2548,16 @@ MatchStringFormat(
for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
formatPtr = formatPtr->nextPtr) {
+ /*
+ * To keep the behaviour of older versions (Tk <= 8.6), the default
+ * list-of-lists string format is checked last. Remember its position.
+ */
+
+ if (strncasecmp("default", formatPtr->name, strlen(formatPtr->name))
+ == 0) {
+ defaultFormatPtr = formatPtr;
+ }
+
if (formatObj != NULL) {
if (strncasecmp(formatString,
formatPtr->name, strlen(formatPtr->name)) != 0) {
@@ -2568,6 +2573,16 @@ MatchStringFormat(
return TCL_ERROR;
}
}
+
+ /*
+ * If this is the default format, and it was not passed as -format
+ * option, skip the stringMatchProc test. It'll be done later
+ */
+
+ if (formatObj == NULL && formatPtr == defaultFormatPtr) {
+ continue;
+ }
+
if ((formatPtr->stringMatchProc != NULL)
&& (formatPtr->stringReadProc != NULL)
&& formatPtr->stringMatchProc(data, formatObj,
@@ -2605,23 +2620,46 @@ MatchStringFormat(
}
}
}
+
if (formatPtr == NULL) {
- if ((formatObj != NULL) && !matched) {
+ /*
+ * Try the default format as last resort (only if no -format option
+ * was passed).
+ */
+
+ if ( formatObj == NULL && defaultFormatPtr == NULL) {
+ Tcl_Panic("default image format handler not registered");
+ }
+ if ( formatObj == NULL
+ && defaultFormatPtr->stringMatchProc != NULL
+ && defaultFormatPtr->stringReadProc != NULL
+ && defaultFormatPtr->stringMatchProc(data, formatObj,
+ widthPtr, heightPtr, interp) != 0) {
+ useoldformat = 0;
+ formatPtr = defaultFormatPtr;
+ } else if ((formatObj != NULL) && !matched) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"image format \"%s\" is not supported", formatString));
Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
formatString, NULL);
+ return TCL_ERROR;
} else {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"couldn't recognize image data", -1));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
"UNRECOGNIZED_DATA", NULL);
+ return TCL_ERROR;
}
- return TCL_ERROR;
}
*imageFormatPtr = formatPtr;
*oldformat = useoldformat;
+
+ /*
+ * Some stringMatchProc might have left error messages and error codes in
+ * interp. Clear them before return.
+ */
+ Tcl_ResetResult(interp);
return TCL_OK;
}
@@ -2686,7 +2724,7 @@ Tk_PhotoPutBlock(
* messages, or NULL. */
Tk_PhotoHandle handle, /* Opaque handle for the photo image to be
* updated. */
- register Tk_PhotoImageBlock *blockPtr,
+ Tk_PhotoImageBlock *blockPtr,
/* Pointer to a structure describing the pixel
* data to be copied into the image. */
int x, int y, /* Coordinates of the top-left pixel to be
@@ -2697,6 +2735,8 @@ Tk_PhotoPutBlock(
* transparent pixels. */
{
register PhotoMaster *masterPtr = (PhotoMaster *) handle;
+ Tk_PhotoImageBlock sourceBlock;
+ unsigned char *memToFree;
int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
int wLeft, hLeft, wCopy, hCopy, pitch;
unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr;
@@ -2724,11 +2764,43 @@ Tk_PhotoPutBlock(
return TCL_OK;
}
+ /*
+ * Fix for bug e4336bef5d:
+ *
+ * Make a local copy of *blockPtr, as we might have to change some
+ * of its fields and don't want to interfere with the caller's data.
+ *
+ * If source and destination are the same image, create a copy of the
+ * source data in our local sourceBlock.
+ *
+ * To find out, just comparing the pointers is not enough - they might have
+ * different values and still point to the same block of memory. (e.g.
+ * if the -from option was passed to [imageName copy])
+ */
+ sourceBlock = *blockPtr;
+ memToFree = NULL;
+ if (sourceBlock.pixelPtr >= masterPtr->pix32
+ && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width
+ * masterPtr->height * 4) {
+ sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height
+ * sourceBlock.pitch);
+ if (sourceBlock.pixelPtr == NULL) {
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
+ Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
+ }
+ return TCL_ERROR;
+ }
+ memToFree = sourceBlock.pixelPtr;
+ memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height
+ * sourceBlock.pitch);
+ }
+
+
xEnd = x + width;
yEnd = y + height;
if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) {
- int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32);
-
if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
if (interp != NULL) {
@@ -2736,11 +2808,7 @@ Tk_PhotoPutBlock(
TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
}
- return TCL_ERROR;
- }
- if (sameSrc) {
- blockPtr->pixelPtr = masterPtr->pix32;
- blockPtr->pitch = masterPtr->width * 4;
+ goto errorExit;
}
}
@@ -2759,14 +2827,14 @@ Tk_PhotoPutBlock(
* components, mark it as a color image.
*/
- greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
- blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
- alphaOffset = blockPtr->offset[3];
- if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) {
+ greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
+ blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
+ alphaOffset = sourceBlock.offset[3];
+ if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
alphaOffset = 0;
sourceIsSimplePhoto = 1;
} else {
- alphaOffset -= blockPtr->offset[0];
+ alphaOffset -= sourceBlock.offset[0];
}
if ((greenOffset != 0) || (blueOffset != 0)) {
masterPtr->flags |= COLOR_IMAGE;
@@ -2786,13 +2854,13 @@ Tk_PhotoPutBlock(
* pixelSize == 3 and alphaOffset == 0. Maybe other cases too.
*/
- if ((blockPtr->pixelSize == 4)
+ if ((sourceBlock.pixelSize == 4)
&& (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3)
- && (width <= blockPtr->width) && (height <= blockPtr->height)
+ && (width <= sourceBlock.width) && (height <= sourceBlock.height)
&& ((height == 1) || ((x == 0) && (width == masterPtr->width)
- && (blockPtr->pitch == pitch)))
+ && (sourceBlock.pitch == pitch)))
&& (compRule == TK_PHOTO_COMPOSITE_SET)) {
- memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0],
+ memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0],
((size_t)height * width * 4));
/*
@@ -2808,11 +2876,11 @@ Tk_PhotoPutBlock(
*/
for (hLeft = height; hLeft > 0;) {
- int pixelSize = blockPtr->pixelSize;
+ int pixelSize = sourceBlock.pixelSize;
int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET);
- srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
- hCopy = MIN(hLeft, blockPtr->height);
+ srcLinePtr = sourceBlock.pixelPtr + sourceBlock.offset[0];
+ hCopy = MIN(hLeft, sourceBlock.height);
hLeft -= hCopy;
for (; hCopy > 0; --hCopy) {
/*
@@ -2823,10 +2891,10 @@ Tk_PhotoPutBlock(
if ((pixelSize == 4) && (greenOffset == 1)
&& (blueOffset == 2) && (alphaOffset == 3)
- && (width <= blockPtr->width)
+ && (width <= sourceBlock.width)
&& compRuleSet) {
memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4));
- srcLinePtr += blockPtr->pitch;
+ srcLinePtr += sourceBlock.pitch;
destLinePtr += pitch;
continue;
}
@@ -2837,7 +2905,7 @@ Tk_PhotoPutBlock(
destPtr = destLinePtr;
for (wLeft = width; wLeft > 0;) {
- wCopy = MIN(wLeft, blockPtr->width);
+ wCopy = MIN(wLeft, sourceBlock.width);
wLeft -= wCopy;
srcPtr = srcLinePtr;
@@ -2927,7 +2995,7 @@ Tk_PhotoPutBlock(
destPtr += 4;
}
}
- srcLinePtr += blockPtr->pitch;
+ srcLinePtr += sourceBlock.pitch;
destLinePtr += pitch;
}
}
@@ -3043,7 +3111,15 @@ Tk_PhotoPutBlock(
Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height,
masterPtr->width, masterPtr->height);
+
+ if (memToFree) ckfree(memToFree);
+
return TCL_OK;
+
+ errorExit:
+ if (memToFree) ckfree(memToFree);
+
+ return TCL_ERROR;
}
/*
@@ -3070,7 +3146,7 @@ Tk_PhotoPutZoomedBlock(
* messages, or NULL. */
Tk_PhotoHandle handle, /* Opaque handle for the photo image to be
* updated. */
- register Tk_PhotoImageBlock *blockPtr,
+ Tk_PhotoImageBlock *blockPtr,
/* Pointer to a structure describing the pixel
* data to be copied into the image. */
int x, int y, /* Coordinates of the top-left pixel to be
@@ -3085,6 +3161,8 @@ Tk_PhotoPutZoomedBlock(
* transparent pixels. */
{
register PhotoMaster *masterPtr = (PhotoMaster *) handle;
+ register Tk_PhotoImageBlock sourceBlock;
+ unsigned char *memToFree;
int xEnd, yEnd, greenOffset, blueOffset, alphaOffset;
int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt;
unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr;
@@ -3121,11 +3199,41 @@ Tk_PhotoPutZoomedBlock(
return TCL_OK;
}
+ /*
+ * Fix for Bug e4336bef5d:
+ * Make a local copy of *blockPtr, as we might have to change some
+ * of its fields and don't want to interfere with the caller's data.
+ *
+ * If source and destination are the same image, create a copy of the
+ * source data in our local sourceBlock.
+ *
+ * To find out, just comparing the pointers is not enough - they might have
+ * different values and still point to the same block of memory. (e.g.
+ * if the -from option was passed to [imageName copy])
+ */
+ sourceBlock = *blockPtr;
+ memToFree = NULL;
+ if (sourceBlock.pixelPtr >= masterPtr->pix32
+ && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width
+ * masterPtr->height * 4) {
+ sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height
+ * sourceBlock.pitch);
+ if (sourceBlock.pixelPtr == NULL) {
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
+ Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
+ }
+ return TCL_ERROR;
+ }
+ memToFree = sourceBlock.pixelPtr;
+ memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height
+ * sourceBlock.pitch);
+ }
+
xEnd = x + width;
yEnd = y + height;
if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) {
- int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32);
-
if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width),
MAX(yEnd, masterPtr->height)) == TCL_ERROR) {
if (interp != NULL) {
@@ -3133,11 +3241,7 @@ Tk_PhotoPutZoomedBlock(
TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
}
- return TCL_ERROR;
- }
- if (sameSrc) {
- blockPtr->pixelPtr = masterPtr->pix32;
- blockPtr->pitch = masterPtr->width * 4;
+ goto errorExit;
}
}
@@ -3156,14 +3260,14 @@ Tk_PhotoPutZoomedBlock(
* components, mark it as a color image.
*/
- greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
- blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
- alphaOffset = blockPtr->offset[3];
- if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) {
+ greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0];
+ blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0];
+ alphaOffset = sourceBlock.offset[3];
+ if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) {
alphaOffset = 0;
sourceIsSimplePhoto = 1;
} else {
- alphaOffset -= blockPtr->offset[0];
+ alphaOffset -= sourceBlock.offset[0];
}
if ((greenOffset != 0) || (blueOffset != 0)) {
masterPtr->flags |= COLOR_IMAGE;
@@ -3174,21 +3278,21 @@ Tk_PhotoPutZoomedBlock(
* subsampling and zooming.
*/
- blockXSkip = subsampleX * blockPtr->pixelSize;
- blockYSkip = subsampleY * blockPtr->pitch;
+ blockXSkip = subsampleX * sourceBlock.pixelSize;
+ blockYSkip = subsampleY * sourceBlock.pitch;
if (subsampleX > 0) {
- blockWid = ((blockPtr->width + subsampleX - 1) / subsampleX) * zoomX;
+ blockWid = ((sourceBlock.width + subsampleX - 1) / subsampleX) * zoomX;
} else if (subsampleX == 0) {
blockWid = width;
} else {
- blockWid = ((blockPtr->width - subsampleX - 1) / -subsampleX) * zoomX;
+ blockWid = ((sourceBlock.width - subsampleX - 1) / -subsampleX) * zoomX;
}
if (subsampleY > 0) {
- blockHt = ((blockPtr->height + subsampleY - 1) / subsampleY) * zoomY;
+ blockHt = ((sourceBlock.height + subsampleY - 1) / subsampleY) * zoomY;
} else if (subsampleY == 0) {
blockHt = height;
} else {
- blockHt = ((blockPtr->height - subsampleY - 1) / -subsampleY) * zoomY;
+ blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY;
}
/*
@@ -3196,12 +3300,12 @@ Tk_PhotoPutZoomedBlock(
*/
destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4;
- srcOrigPtr = blockPtr->pixelPtr + blockPtr->offset[0];
+ srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0];
if (subsampleX < 0) {
- srcOrigPtr += (blockPtr->width - 1) * blockPtr->pixelSize;
+ srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize;
}
if (subsampleY < 0) {
- srcOrigPtr += (blockPtr->height - 1) * blockPtr->pitch;
+ srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch;
}
pitch = masterPtr->width * 4;
@@ -3351,7 +3455,15 @@ Tk_PhotoPutZoomedBlock(
Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width,
masterPtr->height);
+
+ if (memToFree) ckfree(memToFree);
+
return TCL_OK;
+
+ errorExit:
+ if (memToFree) ckfree(memToFree);
+
+ return TCL_ERROR;
}
/*
@@ -3839,57 +3951,6 @@ ImgGetPhoto(
/*
*----------------------------------------------------------------------
*
- * ImgStringWrite --
- *
- * Default string write function. The data is formatted in the default
- * format as accepted by the "<img> put" command.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-ImgStringWrite(
- Tcl_Interp *interp,
- Tcl_Obj *formatString,
- Tk_PhotoImageBlock *blockPtr)
-{
- int greenOffset, blueOffset;
- Tcl_Obj *data;
-
- greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
- blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
-
- data = Tcl_NewObj();
- if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
- int row, col;
-
- for (row=0; row<blockPtr->height; row++) {
- Tcl_Obj *line = Tcl_NewObj();
- unsigned char *pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
- + row * blockPtr->pitch;
-
- for (col=0; col<blockPtr->width; col++) {
- Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x",
- col ? " " : "", *pixelPtr,
- pixelPtr[greenOffset], pixelPtr[blueOffset]);
- pixelPtr += blockPtr->pixelSize;
- }
- Tcl_ListObjAppendElement(NULL, data, line);
- }
- }
- Tcl_SetObjResult(interp, data);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tk_PhotoGetImage --
*
* This function is called to obtain image data from a photo image. This
@@ -3932,7 +3993,7 @@ Tk_PhotoGetImage(
/*
*--------------------------------------------------------------
*
- * TkPostscriptPhoto --
+ * ImgPostscriptPhoto --
*
* This function is called to output the contents of a photo image in
* Postscript by calling the Tk_PostscriptPhoto function.
@@ -3977,7 +4038,7 @@ ImgPhotoPostscript(
*
*----------------------------------------------------------------------
*/
-
+#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
void
Tk_PhotoPutBlock_NoComposite(
Tk_PhotoHandle handle,
@@ -4063,11 +4124,13 @@ Tk_PhotoSetSize_Panic(
Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
}
}
+#endif /* TK_NO_DEPRECATED */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
+ * tab-width: 8
* End:
*/
diff --git a/generic/tkImgPhoto.h b/generic/tkImgPhoto.h
index 36bc6cb..a84ebb3 100644
--- a/generic/tkImgPhoto.h
+++ b/generic/tkImgPhoto.h
@@ -93,10 +93,17 @@ struct ColorTableId {
struct ColorTable {
ColorTableId id; /* Information used in selecting this color
* table. */
+#if TCL_MAJOR_VERSION > 8
+ size_t refCount; /* Number of instances using this map. */
+ size_t liveRefCount; /* Number of instances which are actually in
+ * use, using this map. */
+ int flags; /* See below. */
+#else
int flags; /* See below. */
- int refCount; /* Number of instances using this map. */
- int liveRefCount; /* Number of instances which are actually in
+ unsigned int refCount; /* Number of instances using this map. */
+ unsigned int liveRefCount; /* Number of instances which are actually in
* use, using this map. */
+#endif
int numColors; /* Number of colors allocated for this map. */
XVisualInfo visualInfo; /* Information about the visual for windows
@@ -201,7 +208,11 @@ struct PhotoInstance {
* this particular colormap. */
PhotoInstance *nextPtr; /* Pointer to the next instance in the list of
* instances associated with this master. */
- int refCount; /* Number of instances using this structure. */
+#if TCL_MAJOR_VERSION > 8
+ size_t refCount; /* Number of instances using this structure. */
+#else
+ unsigned int refCount; /* Number of instances using this structure. */
+#endif
Tk_Uid palette; /* Palette for these particular instances. */
double gamma; /* Gamma value for these instances. */
Tk_Uid defaultPalette; /* Default palette to use if a palette is not
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index 586b407..04eecf6 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -99,7 +99,7 @@ declare 21 {
const TkStateMap *mapPtr, const char *strKey)
}
declare 22 {
- CONST86 char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
+ const char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
void TkFocusDeadWindow(TkWindow *winPtr)
@@ -182,7 +182,7 @@ declare 45 {
void TkInstallFrameMenu(Tk_Window tkwin)
}
declare 46 {
- CONST86 char *TkKeysymToString(KeySym keysym)
+ const char *TkKeysymToString(KeySym keysym)
}
declare 47 {
int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
@@ -389,7 +389,7 @@ declare 108 {
Tcl_Obj *objPtr, Tk_Window *windowPtr)
}
declare 109 {
- CONST86 char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
+ const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
@@ -570,7 +570,7 @@ declare 169 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 170 {
- CONST86 char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 171 {
@@ -578,7 +578,7 @@ declare 171 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 172 {
- CONST86 char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 173 {
@@ -586,7 +586,7 @@ declare 173 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 174 {
- CONST86 char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 175 {
@@ -594,7 +594,7 @@ declare 175 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 176 {
- CONST86 char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 177 {
@@ -602,7 +602,7 @@ declare 177 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 178 {
- CONST86 char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 179 {
@@ -610,7 +610,7 @@ declare 179 {
Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 180 {
- CONST86 char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
+ const char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
@@ -634,6 +634,13 @@ declare 184 {
Tk_Font tkfont, const char *source, int numBytes, double x,
double y, double angle)
}
+
+# Debugging / testing functions for photo images
+declare 185 {
+ int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
+ Tcl_Obj *formatString, int *widthPtr, int *heightPtr)
+}
+
##############################################################################
@@ -983,9 +990,9 @@ declare 38 aqua {
declare 39 aqua {
void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
}
-declare 40 aqua {
- void TkSuspendClipboard(void)
-}
+#
+# Slot 40 unused (WAS: TkSuspendClipboard)
+#
declare 41 aqua {
int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
@@ -1422,28 +1429,82 @@ declare 106 win {
# New in Tk 8.6
declare 107 win {
- int XFlush(Display *display)
+ int XFlush(Display *display)
}
declare 108 win {
- int XGrabServer(Display *display)
+ int XGrabServer(Display *display)
}
declare 109 win {
- int XUngrabServer(Display *display)
+ int XUngrabServer(Display *display)
}
declare 110 win {
- int XFree(void *data)
+ int XFree(void *data)
}
declare 111 win {
- int XNoOp(Display *display)
+ int XNoOp(Display *display)
}
declare 112 win {
- XAfterFunction XSynchronize(Display *display, Bool onoff)
+ XAfterFunction XSynchronize(Display *display, Bool onoff)
}
declare 113 win {
- int XSync(Display *display, Bool discard)
+ int XSync(Display *display, Bool discard)
}
declare 114 win {
- VisualID XVisualIDFromVisual(Visual *visual)
+ VisualID XVisualIDFromVisual(Visual *visual)
+}
+
+# For tktreectrl
+declare 120 win {
+ int XOffsetRegion(Region rgn, int dx, int dy)
+}
+declare 121 win {
+ int XUnionRegion(Region srca, Region srcb, Region dr_return)
+}
+
+# For 3dcanvas
+declare 122 win {
+ Window XCreateWindow(Display *display, Window parent, int x, int y,
+ unsigned int width, unsigned int height,
+ unsigned int border_width, int depth, unsigned int clazz,
+ Visual *visual, unsigned long value_mask,
+ XSetWindowAttributes *attributes)
+}
+
+# Various, e.g. for stub-enabled BLT
+declare 129 win {
+ int XLowerWindow(Display *d, Window w)
+}
+declare 130 win {
+ int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
+}
+declare 131 win {
+ int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
+}
+declare 132 win {
+ int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
+}
+declare 133 win {
+ int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n)
+}
+declare 134 win {
+ int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y)
+}
+declare 135 win {
+ int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m)
+}
+declare 136 win {
+ int XReparentWindow(Display *d, Window w, Window p, int x, int y)
+}
+declare 137 win {
+ int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
+ int sx, int sy, int dx, int dy,
+ unsigned int w, unsigned int h)
+}
+declare 138 win {
+ Region XPolygonRegion(XPoint *pts, int n, int rule)
+}
+declare 139 win {
+ int XPointInRegion(Region rgn, int x, int y)
}
################################
@@ -1725,7 +1786,7 @@ declare 79 aqua {
XTextProperty *text_prop_return)
}
declare 80 aqua {
- void XDrawSegments(Display *display, Drawable d, GC gc,
+ int XDrawSegments(Display *display, Drawable d, GC gc,
XSegment *segments, int nsegments)
}
declare 81 aqua {
@@ -1743,10 +1804,10 @@ declare 84 aqua {
void XClearWindow(Display *d, Window w)
}
declare 85 aqua {
- void XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
+ int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 aqua {
- void XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
+ int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
int npoints, int mode)
}
declare 87 aqua {
diff --git a/generic/tkInt.h b/generic/tkInt.h
index b644c5b..f903490 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -25,7 +25,6 @@
* Darwin (where configure runs only once for multiple architectures).
*/
-#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
@@ -59,6 +58,14 @@
# endif
#endif
+#ifndef TkSizeT
+# if TCL_MAJOR_VERSION > 8
+# define TkSizeT size_t
+# else
+# define TkSizeT int
+# endif
+#endif
+
/*
* Macros used to cast between pointers and integers (e.g. when storing an int
* in ClientData), on 64-bit architectures they avoid gcc warning about "cast
@@ -84,6 +91,10 @@
# endif
#endif
+#ifndef TCL_AUTO_LENGTH
+# define TCL_AUTO_LENGTH (-1)
+#endif
+
/*
* Opaque type declarations:
*/
@@ -107,7 +118,7 @@ typedef struct TkCursor {
Tk_Cursor cursor; /* System specific identifier for cursor. */
Display *display; /* Display containing cursor. Needed for
* disposal and retrieval of cursors. */
- int resourceRefCount; /* Number of active uses of this cursor (each
+ TkSizeT resourceRefCount; /* Number of active uses of this cursor (each
* active use corresponds to a call to
* Tk_AllocPreserveFromObj or Tk_Preserve). If
* this count is 0, then this structure is no
@@ -116,7 +127,7 @@ typedef struct TkCursor {
* there are objects referring to it. The
* structure is freed when resourceRefCount
* and objRefCount are both 0. */
- int objRefCount; /* Number of Tcl objects that reference this
+ TkSizeT objRefCount; /* Number of Tcl objects that reference this
* structure.. */
Tcl_HashTable *otherTable; /* Second table (other than idTable) used to
* index this entry. */
@@ -266,7 +277,7 @@ typedef struct TkDisplay {
/* First in list of error handlers for this
* display. NULL means no handlers exist at
* present. */
- int deleteCount; /* Counts # of handlers deleted since last
+ TkSizeT deleteCount; /* Counts # of handlers deleted since last
* time inactive handlers were garbage-
* collected. When this number gets big,
* handlers get cleaned up. */
@@ -423,6 +434,7 @@ typedef struct TkDisplay {
Atom windowAtom; /* Atom for TK_WINDOW. */
Atom clipboardAtom; /* Atom for CLIPBOARD. */
Atom utf8Atom; /* Atom for UTF8_STRING. */
+ Atom atomPairAtom; /* Atom for ATOM_PAIR. */
Tk_Window clipWindow; /* Window used for clipboard ownership and to
* retrieve selections between processes. NULL
@@ -478,7 +490,7 @@ typedef struct TkDisplay {
#endif /* TK_USE_INPUT_METHODS */
Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */
- int refCount; /* Reference count of how many Tk applications
+ size_t refCount; /* Reference count of how many Tk applications
* are using this display. Used to clean up
* the display when we no longer have any Tk
* applications using it. */
@@ -508,6 +520,9 @@ typedef struct TkDisplay {
int iconDataSize; /* Size of default iconphoto image data. */
unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */
+#ifdef TK_USE_INPUT_METHODS
+ int ximGeneration; /* Used to invalidate XIC */
+#endif /* TK_USE_INPUT_METHODS */
} TkDisplay;
/*
@@ -579,7 +594,7 @@ typedef struct TkEventHandler {
*/
typedef struct TkMainInfo {
- int refCount; /* Number of windows whose "mainPtr" fields
+ size_t refCount; /* Number of windows whose "mainPtr" fields
* point here. When this becomes zero, can
* free up the structure (the reference count
* is zero because windows can get deleted in
@@ -590,7 +605,11 @@ typedef struct TkMainInfo {
Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow
* structs for all windows related to this
* main window. Managed by tkWindow.c. */
- long deletionEpoch; /* Incremented by window deletions. */
+#if TCL_MAJOR_VERSION > 8
+ size_t deletionEpoch; /* Incremented by window deletions. */
+#else
+ long deletionEpoch;
+#endif
Tk_BindingTable bindingTable;
/* Used in conjunction with "bind" command to
* bind events to Tcl commands. */
@@ -809,6 +828,9 @@ typedef struct TkWindow {
int minReqWidth; /* Minimum requested width. */
int minReqHeight; /* Minimum requested height. */
char *geometryMaster;
+#ifdef TK_USE_INPUT_METHODS
+ int ximGeneration; /* Used to invalidate XIC */
+#endif /* TK_USE_INPUT_METHODS */
} TkWindow;
/*
@@ -817,13 +839,13 @@ typedef struct TkWindow {
*/
typedef struct {
- XKeyEvent keyEvent; /* The real event from X11. */
- char *charValuePtr; /* A pointer to a string that holds the key's
+ XKeyEvent keyEvent; /* The real event from X11. */
+ char *charValuePtr; /* A pointer to a string that holds the key's
* %A substitution text (before backslash
* adding), or NULL if that has not been
* computed yet. If non-NULL, this string was
* allocated with ckalloc(). */
- int charValueLen; /* Length of string in charValuePtr when that
+ size_t charValueLen; /* Length of string in charValuePtr when that
* is non-NULL. */
KeySym keysym; /* Key symbol computed after input methods
* have been invoked */
@@ -837,6 +859,11 @@ typedef struct {
#define TK_MAKE_MENU_POPUP 1
#define TK_MAKE_MENU_DROPDOWN 2
+/* See TIP #494 */
+#ifndef TCL_IO_FAILURE
+# define TCL_IO_FAILURE (-1)
+#endif
+
/*
* The following structure is used with TkMakeEnsemble to create ensemble
* commands and optionally to create sub-ensembles.
@@ -939,6 +966,7 @@ MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr);
+MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
MODULE_SCOPE TkMainInfo *tkMainWindowList;
@@ -1196,7 +1224,7 @@ MODULE_SCOPE void TkUnderlineCharsInContext(Display *display,
const char *string, int numBytes, int x, int y,
int firstByte, int lastByte);
MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
- Tcl_UniChar c, struct TkFontAttributes *faPtr);
+ int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE Tcl_Obj * TkNewWindowObj(Tk_Window tkwin);
MODULE_SCOPE void TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void TkpHideBusyWindow(TkBusy busy);
@@ -1208,7 +1236,7 @@ MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
MODULE_SCOPE int TkBackgroundEvalObjv(Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv, int flags);
MODULE_SCOPE void TkSendVirtualEvent(Tk_Window tgtWin,
- const char *eventName);
+ const char *eventName, Tcl_Obj *detail);
MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
const char *nsname, const char *name,
ClientData clientData, const TkEnsemble *map);
@@ -1217,6 +1245,10 @@ MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp,
MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp,
ClientData clientData);
MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr);
+MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr);
+MODULE_SCOPE int TkListCreateFrame(ClientData clientData,
+ Tcl_Interp *interp, Tcl_Obj *listObj,
+ int toplevel, Tcl_Obj *nameObj);
#ifdef _WIN32
#define TkParseColor XParseColor
@@ -1229,6 +1261,29 @@ MODULE_SCOPE Status TkParseColor (Display * display,
MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif
+#if TCL_UTF_MAX > 4
+# define TkUtfToUniChar (size_t)Tcl_UtfToUniChar
+# define TkUniCharToUtf (size_t)Tcl_UniCharToUtf
+#else
+ MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
+ MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
+#endif
+
+#ifdef TCL_TYPE_I
+/* With TIP #481 available, we don't need to do anything special here */
+#define TkGetStringFromObj(objPtr, lenPtr) \
+ Tcl_GetStringFromObj(objPtr, lenPtr)
+#define TkGetByteArrayFromObj(objPtr, lenPtr) \
+ Tcl_GetByteArrayFromObj(objPtr, lenPtr)
+#else
+#define TkGetStringFromObj(objPtr, lenPtr) \
+ (((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
+ *(lenPtr) = (objPtr)->length, (objPtr)->bytes)
+
+MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
+ size_t *lengthPtr);
+#endif
+
/*
* Unsupported commands.
*/
diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h
index b8addbd..a646779 100644
--- a/generic/tkIntDecls.h
+++ b/generic/tkIntDecls.h
@@ -104,7 +104,7 @@ EXTERN int TkFindStateNum(Tcl_Interp *interp,
const char *option, const TkStateMap *mapPtr,
const char *strKey);
/* 22 */
-EXTERN CONST86 char * TkFindStateString(const TkStateMap *mapPtr,
+EXTERN const char * TkFindStateString(const TkStateMap *mapPtr,
int numKey);
/* 23 */
EXTERN void TkFocusDeadWindow(TkWindow *winPtr);
@@ -167,7 +167,7 @@ EXTERN void TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr,
/* 45 */
EXTERN void TkInstallFrameMenu(Tk_Window tkwin);
/* 46 */
-EXTERN CONST86 char * TkKeysymToString(KeySym keysym);
+EXTERN const char * TkKeysymToString(KeySym keysym);
/* 47 */
EXTERN int TkLineToArea(double end1Ptr[], double end2Ptr[],
double rectPtr[]);
@@ -324,7 +324,7 @@ EXTERN int TkGetWindowFromObj(Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *objPtr,
Tk_Window *windowPtr);
/* 109 */
-EXTERN CONST86 char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
+EXTERN const char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
Tcl_DString *dsPtr);
/* 110 */
EXTERN void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
@@ -488,7 +488,7 @@ EXTERN int TkStateParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 170 */
-EXTERN CONST86 char * TkStatePrintProc(ClientData clientData,
+EXTERN const char * TkStatePrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 171 */
@@ -496,7 +496,7 @@ EXTERN int TkCanvasDashParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 172 */
-EXTERN CONST86 char * TkCanvasDashPrintProc(ClientData clientData,
+EXTERN const char * TkCanvasDashPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 173 */
@@ -504,7 +504,7 @@ EXTERN int TkOffsetParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 174 */
-EXTERN CONST86 char * TkOffsetPrintProc(ClientData clientData,
+EXTERN const char * TkOffsetPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 175 */
@@ -512,7 +512,7 @@ EXTERN int TkPixelParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 176 */
-EXTERN CONST86 char * TkPixelPrintProc(ClientData clientData,
+EXTERN const char * TkPixelPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 177 */
@@ -520,7 +520,7 @@ EXTERN int TkOrientParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 178 */
-EXTERN CONST86 char * TkOrientPrintProc(ClientData clientData,
+EXTERN const char * TkOrientPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 179 */
@@ -528,7 +528,7 @@ EXTERN int TkSmoothParseProc(ClientData clientData,
Tcl_Interp *interp, Tk_Window tkwin,
const char *value, char *widgRec, int offset);
/* 180 */
-EXTERN CONST86 char * TkSmoothPrintProc(ClientData clientData,
+EXTERN const char * TkSmoothPrintProc(ClientData clientData,
Tk_Window tkwin, char *widgRec, int offset,
Tcl_FreeProc **freeProcPtr);
/* 181 */
@@ -550,6 +550,10 @@ EXTERN void TkDrawAngledChars(Display *display,
Drawable drawable, GC gc, Tk_Font tkfont,
const char *source, int numBytes, double x,
double y, double angle);
+/* 185 */
+EXTERN int TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
+ Tcl_Obj *data, Tcl_Obj *formatString,
+ int *widthPtr, int *heightPtr);
typedef struct TkIntStubs {
int magic;
@@ -577,7 +581,7 @@ typedef struct TkIntStubs {
void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */
int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */
- CONST86 char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */
+ const char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */
void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */
int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */
TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */
@@ -601,7 +605,7 @@ typedef struct TkIntStubs {
void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */
void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */
void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */
- CONST86 char * (*tkKeysymToString) (KeySym keysym); /* 46 */
+ const char * (*tkKeysymToString) (KeySym keysym); /* 46 */
int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */
double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */
int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */
@@ -664,7 +668,7 @@ typedef struct TkIntStubs {
TkDisplay * (*tkGetDisplayList) (void); /* 106 */
TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
- CONST86 char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
+ const char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */
void (*tkpMenuThreadInit) (void); /* 112 */
@@ -752,21 +756,22 @@ typedef struct TkIntStubs {
int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */
- CONST86 char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */
+ const char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */
int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 171 */
- CONST86 char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */
+ const char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */
int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 173 */
- CONST86 char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */
+ const char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */
int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 175 */
- CONST86 char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */
+ const char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */
int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 177 */
- CONST86 char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */
+ const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */
int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 179 */
- CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */
+ const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */
void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
+ int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 185 */
} TkIntStubs;
extern const TkIntStubs *tkIntStubsPtr;
@@ -1139,6 +1144,8 @@ extern const TkIntStubs *tkIntStubsPtr;
(tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */
#define TkDrawAngledChars \
(tkIntStubsPtr->tkDrawAngledChars) /* 184 */
+#define TkDebugPhotoStringMatchDef \
+ (tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 185 */
#endif /* defined(USE_TK_STUBS) */
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index e48e803..9bc76c0 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -224,8 +224,7 @@ EXTERN void TkMacOSXWindowOffset(void *wRef, int *xOffset,
EXTERN int TkSetMacColor(unsigned long pixel, void *macColor);
/* 39 */
EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
-/* 40 */
-EXTERN void TkSuspendClipboard(void);
+/* Slot 40 is reserved */
/* 41 */
EXTERN int TkMacOSXZoomToplevel(void *whichWindow,
short zoomPart);
@@ -384,7 +383,7 @@ typedef struct TkIntPlatStubs {
void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
- void (*tkSuspendClipboard) (void); /* 40 */
+ void (*reserved40)(void);
int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */
Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
@@ -599,8 +598,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
(tkIntPlatStubsPtr->tkSetMacColor) /* 38 */
#define TkSetWMName \
(tkIntPlatStubsPtr->tkSetWMName) /* 39 */
-#define TkSuspendClipboard \
- (tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */
+/* Slot 40 is reserved */
#define TkMacOSXZoomToplevel \
(tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */
#define Tk_TopCoordsToWindow \
@@ -666,4 +664,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
+#undef TkWinGetPlatformId
+#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */
+
#endif /* _TKINTPLATDECLS */
diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h
index 6ac7ccb..4efa241 100644
--- a/generic/tkIntXlibDecls.h
+++ b/generic/tkIntXlibDecls.h
@@ -23,11 +23,25 @@
# include <tcl.h>
#endif
+#ifndef EXTERN
+# define EXTERN extern TCL_STORAGE_CLASS
+#endif
+
+/* Some (older) versions of X11/Xutil.h have a wrong signature of those
+ two functions, so move them out of the way temporarly. */
+#define XOffsetRegion _XOffsetRegion
+#define XUnionRegion _XUnionRegion
#include "X11/Xutil.h"
+#undef XOffsetRegion
+#undef XUnionRegion
#ifdef BUILD_tk
-#undef TCL_STORAGE_CLASS
-#define TCL_STORAGE_CLASS DLLEXPORT
+# undef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLEXPORT
+#else
+# ifndef TCL_STORAGE_CLASS
+# define TCL_STORAGE_CLASS DLLIMPORT
+# endif
#endif
typedef int (*XAfterFunction) ( /* WARNING, this type not in Xlib spec */
@@ -356,6 +370,61 @@ EXTERN XAfterFunction XSynchronize(Display *display, Bool onoff);
EXTERN int XSync(Display *display, Bool discard);
/* 114 */
EXTERN VisualID XVisualIDFromVisual(Visual *visual);
+/* Slot 115 is reserved */
+/* Slot 116 is reserved */
+/* Slot 117 is reserved */
+/* Slot 118 is reserved */
+/* Slot 119 is reserved */
+/* 120 */
+EXTERN int XOffsetRegion(Region rgn, int dx, int dy);
+/* 121 */
+EXTERN int XUnionRegion(Region srca, Region srcb,
+ Region dr_return);
+/* 122 */
+EXTERN Window XCreateWindow(Display *display, Window parent, int x,
+ int y, unsigned int width,
+ unsigned int height,
+ unsigned int border_width, int depth,
+ unsigned int clazz, Visual *visual,
+ unsigned long value_mask,
+ XSetWindowAttributes *attributes);
+/* Slot 123 is reserved */
+/* Slot 124 is reserved */
+/* Slot 125 is reserved */
+/* Slot 126 is reserved */
+/* Slot 127 is reserved */
+/* Slot 128 is reserved */
+/* 129 */
+EXTERN int XLowerWindow(Display *d, Window w);
+/* 130 */
+EXTERN int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a,
+ int n);
+/* 131 */
+EXTERN int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
+ int n);
+/* 132 */
+EXTERN int XDrawRectangles(Display *d, Drawable dr, GC gc,
+ XRectangle *r, int n);
+/* 133 */
+EXTERN int XDrawSegments(Display *d, Drawable dr, GC gc,
+ XSegment *s, int n);
+/* 134 */
+EXTERN int XDrawPoint(Display *d, Drawable dr, GC gc, int x,
+ int y);
+/* 135 */
+EXTERN int XDrawPoints(Display *d, Drawable dr, GC gc,
+ XPoint *p, int n, int m);
+/* 136 */
+EXTERN int XReparentWindow(Display *d, Window w, Window p,
+ int x, int y);
+/* 137 */
+EXTERN int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
+ int sx, int sy, int dx, int dy,
+ unsigned int w, unsigned int h);
+/* 138 */
+EXTERN Region XPolygonRegion(XPoint *pts, int n, int rule);
+/* 139 */
+EXTERN int XPointInRegion(Region rgn, int x, int y);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* 0 */
@@ -584,7 +653,7 @@ EXTERN void XSetWMClientMachine(Display *display, Window w,
EXTERN Status XStringListToTextProperty(char **list, int count,
XTextProperty *text_prop_return);
/* 80 */
-EXTERN void XDrawSegments(Display *display, Drawable d, GC gc,
+EXTERN int XDrawSegments(Display *display, Drawable d, GC gc,
XSegment *segments, int nsegments);
/* 81 */
EXTERN void XForceScreenSaver(Display *display, int mode);
@@ -598,10 +667,10 @@ EXTERN int XFillRectangle(Display *display, Drawable d, GC gc,
/* 84 */
EXTERN void XClearWindow(Display *d, Window w);
/* 85 */
-EXTERN void XDrawPoint(Display *display, Drawable d, GC gc,
+EXTERN int XDrawPoint(Display *display, Drawable d, GC gc,
int x, int y);
/* 86 */
-EXTERN void XDrawPoints(Display *display, Drawable d, GC gc,
+EXTERN int XDrawPoints(Display *display, Drawable d, GC gc,
XPoint *points, int npoints, int mode);
/* 87 */
EXTERN int XWarpPointer(Display *display, Window src_w,
@@ -742,6 +811,31 @@ typedef struct TkIntXlibStubs {
XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
int (*xSync) (Display *display, Bool discard); /* 113 */
VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
+ void (*reserved115)(void);
+ void (*reserved116)(void);
+ void (*reserved117)(void);
+ void (*reserved118)(void);
+ void (*reserved119)(void);
+ int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
+ int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
+ Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
+ void (*reserved123)(void);
+ void (*reserved124)(void);
+ void (*reserved125)(void);
+ void (*reserved126)(void);
+ void (*reserved127)(void);
+ void (*reserved128)(void);
+ int (*xLowerWindow) (Display *d, Window w); /* 129 */
+ int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
+ int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
+ int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
+ int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
+ int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
+ int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
+ int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
+ int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
+ Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
+ int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
@@ -824,13 +918,13 @@ typedef struct TkIntXlibStubs {
XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 77 */
void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 78 */
Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 79 */
- void (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */
+ int (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */
void (*xForceScreenSaver) (Display *display, int mode); /* 81 */
int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 82 */
int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 83 */
void (*xClearWindow) (Display *d, Window w); /* 84 */
- void (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
- void (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
+ int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
+ int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */
void (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
void (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */
@@ -1081,6 +1175,45 @@ extern const TkIntXlibStubs *tkIntXlibStubsPtr;
(tkIntXlibStubsPtr->xSync) /* 113 */
#define XVisualIDFromVisual \
(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
+/* Slot 115 is reserved */
+/* Slot 116 is reserved */
+/* Slot 117 is reserved */
+/* Slot 118 is reserved */
+/* Slot 119 is reserved */
+#define XOffsetRegion \
+ (tkIntXlibStubsPtr->xOffsetRegion) /* 120 */
+#define XUnionRegion \
+ (tkIntXlibStubsPtr->xUnionRegion) /* 121 */
+#define XCreateWindow \
+ (tkIntXlibStubsPtr->xCreateWindow) /* 122 */
+/* Slot 123 is reserved */
+/* Slot 124 is reserved */
+/* Slot 125 is reserved */
+/* Slot 126 is reserved */
+/* Slot 127 is reserved */
+/* Slot 128 is reserved */
+#define XLowerWindow \
+ (tkIntXlibStubsPtr->xLowerWindow) /* 129 */
+#define XFillArcs \
+ (tkIntXlibStubsPtr->xFillArcs) /* 130 */
+#define XDrawArcs \
+ (tkIntXlibStubsPtr->xDrawArcs) /* 131 */
+#define XDrawRectangles \
+ (tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
+#define XDrawSegments \
+ (tkIntXlibStubsPtr->xDrawSegments) /* 133 */
+#define XDrawPoint \
+ (tkIntXlibStubsPtr->xDrawPoint) /* 134 */
+#define XDrawPoints \
+ (tkIntXlibStubsPtr->xDrawPoints) /* 135 */
+#define XReparentWindow \
+ (tkIntXlibStubsPtr->xReparentWindow) /* 136 */
+#define XPutImage \
+ (tkIntXlibStubsPtr->xPutImage) /* 137 */
+#define XPolygonRegion \
+ (tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
+#define XPointInRegion \
+ (tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#define XSetDashes \
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index c7effdd..b3b8ce7 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -12,8 +12,8 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
+#include "default.h"
#ifdef _WIN32
#include "tkWinInt.h"
@@ -567,7 +567,7 @@ Tk_ListboxObjCmd(
ListboxEventProc, listPtr);
Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING,
ListboxFetchSelection, listPtr, XA_STRING);
- if (Tk_InitOptions(interp, (char *)listPtr,
+ if (Tk_InitOptions(interp, listPtr,
optionTables->listboxOptionTable, tkwin) != TCL_OK) {
Tk_DestroyWindow(listPtr->tkwin);
return TCL_ERROR;
@@ -682,7 +682,7 @@ ListboxWidgetObjCmd(
break;
}
- objPtr = Tk_GetOptionValue(interp, (char *) listPtr,
+ objPtr = Tk_GetOptionValue(interp, listPtr,
listPtr->optionTable, objv[2], listPtr->tkwin);
if (objPtr == NULL) {
result = TCL_ERROR;
@@ -694,7 +694,7 @@ ListboxWidgetObjCmd(
case COMMAND_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
+ objPtr = Tk_GetOptionInfo(interp, listPtr,
listPtr->optionTable,
(objc == 3) ? objv[2] : NULL, listPtr->tkwin);
if (objPtr == NULL) {
@@ -926,7 +926,7 @@ ListboxWidgetObjCmd(
attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
if (objc <= 4) {
- objPtr = Tk_GetOptionInfo(interp, (char *) attrPtr,
+ objPtr = Tk_GetOptionInfo(interp, attrPtr,
listPtr->itemAttrOptionTable,
(objc == 4) ? objv[3] : NULL, listPtr->tkwin);
if (objPtr == NULL) {
@@ -1102,7 +1102,8 @@ ListboxBboxSubCmd(
if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
Tcl_Obj *el, *results[4];
const char *stringRep;
- int pixelWidth, stringLen, x, y, result;
+ int pixelWidth, x, y, result;
+ size_t stringLen;
Tk_FontMetrics fm;
/*
@@ -1114,7 +1115,7 @@ ListboxBboxSubCmd(
return result;
}
- stringRep = Tcl_GetStringFromObj(el, &stringLen);
+ stringRep = TkGetStringFromObj(el, &stringLen);
Tk_GetFontMetrics(listPtr->tkfont, &fm);
pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
@@ -1415,7 +1416,7 @@ ListboxGetItemAttributes(
attrs->selBorder = NULL;
attrs->fgColor = NULL;
attrs->selFgColor = NULL;
- Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable,
+ Tk_InitOptions(interp, attrs, listPtr->itemAttrOptionTable,
listPtr->tkwin);
Tcl_SetHashValue(entry, attrs);
} else {
@@ -1565,7 +1566,7 @@ ConfigureListbox(
Tcl_Obj *errorResult = NULL;
int oldExport, error;
- oldExport = listPtr->exportSelection;
+ oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp));
if (listPtr->listVarName != NULL) {
Tcl_UntraceVar2(interp, listPtr->listVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
@@ -1578,7 +1579,7 @@ ConfigureListbox(
* First pass: set options to new values.
*/
- if (Tk_SetOptions(interp, (char *) listPtr,
+ if (Tk_SetOptions(interp, listPtr,
listPtr->optionTable, objc, objv,
listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
@@ -1607,10 +1608,11 @@ ConfigureListbox(
/*
* Claim the selection if we've suddenly started exporting it and
- * there is a selection to export.
+ * there is a selection to export and this interp is unsafe.
*/
- if (listPtr->exportSelection && !oldExport
+ if (listPtr->exportSelection && (!oldExport)
+ && (!Tcl_IsSafe(listPtr->interp))
&& (listPtr->numSelected != 0)) {
Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
ListboxLostSelection, listPtr);
@@ -1723,7 +1725,7 @@ ConfigureListboxItem(
{
Tk_SavedOptions savedOptions;
- if (Tk_SetOptions(interp, (char *)attrs,
+ if (Tk_SetOptions(interp, attrs,
listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
&savedOptions, NULL) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
@@ -1839,7 +1841,8 @@ DisplayListbox(
register Listbox *listPtr = clientData;
register Tk_Window tkwin = listPtr->tkwin;
GC gc;
- int i, limit, x, y, prevSelected, freeGC, stringLen;
+ int i, limit, x, y, prevSelected, freeGC;
+ size_t stringLen;
Tk_FontMetrics fm;
Tcl_Obj *curElement;
Tcl_HashEntry *entry;
@@ -2073,7 +2076,7 @@ DisplayListbox(
*/
Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
- stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
+ stringRep = TkGetStringFromObj(curElement, &stringLen);
textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
Tk_GetFontMetrics(listPtr->tkfont, &fm);
@@ -2235,7 +2238,8 @@ ListboxComputeGeometry(
* Tk_UnsetGrid to update gridding for the
* window. */
{
- int width, height, pixelWidth, pixelHeight, textLength, i, result;
+ int width, height, pixelWidth, pixelHeight, i, result;
+ size_t textLength;
Tk_FontMetrics fm;
Tcl_Obj *element;
const char *text;
@@ -2256,7 +2260,7 @@ ListboxComputeGeometry(
if (result != TCL_OK) {
continue;
}
- text = Tcl_GetStringFromObj(element, &textLength);
+ text = TkGetStringFromObj(element, &textLength);
Tk_GetFontMetrics(listPtr->tkfont, &fm);
pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
if (pixelWidth > listPtr->maxWidth) {
@@ -2322,7 +2326,8 @@ ListboxInsertSubCmd(
int objc, /* Number of new elements to add. */
Tcl_Obj *const objv[]) /* New elements (one per entry). */
{
- int i, oldMaxWidth, pixelWidth, result, length;
+ int i, oldMaxWidth, pixelWidth, result;
+ size_t length;
Tcl_Obj *newListObj;
const char *stringRep;
@@ -2333,7 +2338,7 @@ ListboxInsertSubCmd(
* if so, update our notion of "widest."
*/
- stringRep = Tcl_GetStringFromObj(objv[i], &length);
+ stringRep = TkGetStringFromObj(objv[i], &length);
pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
if (pixelWidth > listPtr->maxWidth) {
listPtr->maxWidth = pixelWidth;
@@ -2436,7 +2441,8 @@ ListboxDeleteSubCmd(
int first, /* Index of first element to delete. */
int last) /* Index of last element to delete. */
{
- int count, i, widthChanged, length, result, pixelWidth;
+ int count, i, widthChanged, result, pixelWidth;
+ size_t length;
Tcl_Obj *newListObj, *element;
const char *stringRep;
Tcl_HashEntry *entry;
@@ -2491,7 +2497,7 @@ ListboxDeleteSubCmd(
if (widthChanged == 0) {
Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element);
- stringRep = Tcl_GetStringFromObj(element, &length);
+ stringRep = TkGetStringFromObj(element, &length);
pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
if (pixelWidth == listPtr->maxWidth) {
widthChanged = 1;
@@ -3079,7 +3085,8 @@ ListboxSelect(
EventuallyRedrawRange(listPtr, first, last);
}
if ((oldCount == 0) && (listPtr->numSelected > 0)
- && listPtr->exportSelection) {
+ && (listPtr->exportSelection)
+ && (!Tcl_IsSafe(listPtr->interp))) {
Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
ListboxLostSelection, listPtr);
}
@@ -3120,12 +3127,13 @@ ListboxFetchSelection(
{
register Listbox *listPtr = clientData;
Tcl_DString selection;
- int length, count, needNewline, stringLen, i;
+ int count, needNewline, i;
+ size_t length, stringLen;
Tcl_Obj *curElement;
const char *stringRep;
Tcl_HashEntry *entry;
- if (!listPtr->exportSelection) {
+ if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
return -1;
}
@@ -3143,7 +3151,7 @@ ListboxFetchSelection(
}
Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
&curElement);
- stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
+ stringRep = TkGetStringFromObj(curElement, &stringLen);
Tcl_DStringAppend(&selection, stringRep, stringLen);
needNewline = 1;
}
@@ -3158,14 +3166,14 @@ ListboxFetchSelection(
* Copy the requested portion of the selection to the buffer.
*/
- count = length - offset;
- if (count <= 0) {
+ if (length <= (size_t)offset) {
count = 0;
} else {
+ count = length - offset;
if (count > maxBytes) {
count = maxBytes;
}
- memcpy(buffer, Tcl_DStringValue(&selection) + offset, (size_t) count);
+ memcpy(buffer, Tcl_DStringValue(&selection) + offset, count);
}
buffer[count] = '\0';
Tcl_DStringFree(&selection);
@@ -3196,7 +3204,8 @@ ListboxLostSelection(
{
register Listbox *listPtr = clientData;
- if ((listPtr->exportSelection) && (listPtr->nElements > 0)) {
+ if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
+ && (listPtr->nElements > 0)) {
ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
GenerateListboxSelectEvent(listPtr);
}
@@ -3223,16 +3232,7 @@ static void
GenerateListboxSelectEvent(
Listbox *listPtr) /* Information about widget. */
{
- union {XEvent general; XVirtualEvent virtual;} event;
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(listPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(listPtr->tkwin);
- event.general.xany.display = Tk_Display(listPtr->tkwin);
- event.virtual.name = Tk_GetUid("ListboxSelect");
- Tk_HandleEvent(&event.general);
+ TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
}
/*
@@ -3437,8 +3437,8 @@ static char *
ListboxListVarProc(
ClientData clientData, /* Information about button. */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* Not used. */
- const char *name2, /* Not used. */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Listbox *listPtr = clientData;
@@ -3447,6 +3447,19 @@ ListboxListVarProc(
Tcl_HashEntry *entry;
/*
+ * See ticket [5d991b82].
+ */
+
+ if (listPtr->listVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ListboxListVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
*/
diff --git a/generic/tkMain.c b/generic/tkMain.c
index 1b21223..ffcaecf 100644
--- a/generic/tkMain.c
+++ b/generic/tkMain.c
@@ -30,14 +30,6 @@
#endif
#include "tkInt.h"
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef NO_STDLIB_H
-# include "../compat/stdlib.h"
-#else
-# include <stdlib.h>
-#endif
extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
@@ -196,7 +188,7 @@ Tk_MainEx(
* Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
abort();
} else {
@@ -235,7 +227,11 @@ Tk_MainEx(
is.gotPartial = 0;
Tcl_Preserve(interp);
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32)
+#if !defined(STATIC_BUILD)
+ /* If compiled for Win32 but running on Cygwin, don't use console */
+ if (!tclStubsPtr->reserved9)
+#endif
Tk_InitConsoleChannels(interp);
#endif
@@ -420,14 +416,15 @@ StdinProc(
int mask) /* Not used. */
{
char *cmd;
- int code, count;
+ int code;
+ size_t count;
InteractiveState *isPtr = clientData;
Tcl_Channel chan = isPtr->input;
Tcl_Interp *interp = isPtr->interp;
count = Tcl_Gets(chan, &isPtr->line);
- if (count < 0 && !isPtr->gotPartial) {
+ if (count == (size_t)-1 && !isPtr->gotPartial) {
if (isPtr->tty) {
Tcl_Exit(0);
} else {
diff --git a/generic/tkMenu.c b/generic/tkMenu.c
index d24516f..14d89cd 100644
--- a/generic/tkMenu.c
+++ b/generic/tkMenu.c
@@ -38,7 +38,7 @@
* implemented using menu clones. Menu clones are full menus in their own
* right; they have a Tk window and pathname associated with them; they have a
* TkMenu structure and array of entries. However, they are linked with the
- * original menu that they were cloned from. The reflect the attributes of the
+ * original menu that they were cloned from. They reflect the attributes of the
* original, or "master", menu. So if an item is added to a menu, and that
* menu has clones, then the item must be added to all of its clones also.
* Menus are cloned when a menu is torn-off or when a menu is assigned as a
@@ -259,6 +259,9 @@ static const Tk_OptionSpec tkMenuConfigSpecs[] = {
"Background", DEF_MENU_ACTIVE_FG_COLOR,
Tk_Offset(TkMenu, activeFgPtr), -1, 0,
(ClientData) DEF_MENU_ACTIVE_FG_MONO, 0},
+ {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief",
+ DEF_MENU_ACTIVE_RELIEF, Tk_Offset(TkMenu, activeReliefPtr),
+ -1, 0, NULL, 0},
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0,
(ClientData) DEF_MENU_BG_MONO, 0},
@@ -465,7 +468,7 @@ Tk_MenuObjCmd(
Tk_CreateEventHandler(newWin,
ExposureMask|StructureNotifyMask|ActivateMask,
TkMenuEventProc, menuPtr);
- if (Tk_InitOptions(interp, (char *) menuPtr,
+ if (Tk_InitOptions(interp, menuPtr,
tsdPtr->menuOptionTable, menuPtr->tkwin)
!= TCL_OK) {
Tk_DestroyWindow(menuPtr->tkwin);
@@ -672,7 +675,7 @@ MenuWidgetObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option");
goto error;
}
- resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr,
+ resultPtr = Tk_GetOptionValue(interp, menuPtr,
tsdPtr->menuOptionTable, objv[2],
menuPtr->tkwin);
if (resultPtr == NULL) {
@@ -692,7 +695,7 @@ MenuWidgetObjCmd(
Tcl_Obj *resultPtr;
if (objc == 2) {
- resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
+ resultPtr = Tk_GetOptionInfo(interp, menuPtr,
tsdPtr->menuOptionTable, NULL,
menuPtr->tkwin);
if (resultPtr == NULL) {
@@ -702,7 +705,7 @@ MenuWidgetObjCmd(
Tcl_SetObjResult(interp, resultPtr);
}
} else if (objc == 3) {
- resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
+ resultPtr = Tk_GetOptionInfo(interp, menuPtr,
tsdPtr->menuOptionTable, objv[2],
menuPtr->tkwin);
if (resultPtr == NULL) {
@@ -776,7 +779,7 @@ MenuWidgetObjCmd(
}
mePtr = menuPtr->entries[index];
Tcl_Preserve(mePtr);
- resultPtr = Tk_GetOptionValue(interp, (char *) mePtr,
+ resultPtr = Tk_GetOptionValue(interp, mePtr,
mePtr->optionTable, objv[3], menuPtr->tkwin);
Tcl_Release(mePtr);
if (resultPtr == NULL) {
@@ -802,7 +805,7 @@ MenuWidgetObjCmd(
mePtr = menuPtr->entries[index];
Tcl_Preserve(mePtr);
if (objc == 3) {
- resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr,
+ resultPtr = Tk_GetOptionInfo(interp, mePtr,
mePtr->optionTable, NULL, menuPtr->tkwin);
if (resultPtr == NULL) {
result = TCL_ERROR;
@@ -811,7 +814,7 @@ MenuWidgetObjCmd(
Tcl_SetObjResult(interp, resultPtr);
}
} else if (objc == 4) {
- resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr,
+ resultPtr = Tk_GetOptionInfo(interp, mePtr,
mePtr->optionTable, objv[3], menuPtr->tkwin);
if (resultPtr == NULL) {
result = TCL_ERROR;
@@ -1528,7 +1531,7 @@ ConfigureMenu(
for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
menuListPtr->errorStructPtr = ckalloc(sizeof(Tk_SavedOptions));
- result = Tk_SetOptions(interp, (char *) menuListPtr,
+ result = Tk_SetOptions(interp, menuListPtr,
tsdPtr->menuOptionTable, objc, objv,
menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
if (result != TCL_OK) {
@@ -1700,12 +1703,12 @@ PostProcessEntry(
if (mePtr->labelPtr == NULL) {
mePtr->labelLength = 0;
} else {
- (void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
+ (void)TkGetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
}
if (mePtr->accelPtr == NULL) {
mePtr->accelLength = 0;
} else {
- (void)Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
+ (void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
}
/*
@@ -1924,7 +1927,7 @@ ConfigureMenuEntry(
result = TCL_OK;
if (menuPtr->tkwin != NULL) {
- if (Tk_SetOptions(menuPtr->interp, (char *) mePtr,
+ if (Tk_SetOptions(menuPtr->interp, mePtr,
mePtr->optionTable, objc, objv, menuPtr->tkwin,
&errorStruct, NULL) != TCL_OK) {
return TCL_ERROR;
@@ -2298,7 +2301,7 @@ MenuNewEntry(
mePtr->entryFlags = 0;
mePtr->index = index;
mePtr->nextCascadePtr = NULL;
- if (Tk_InitOptions(menuPtr->interp, (char *) mePtr,
+ if (Tk_InitOptions(menuPtr->interp, mePtr,
mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
ckfree(mePtr);
return NULL;
@@ -2495,6 +2498,22 @@ MenuVarProc(
}
menuPtr = mePtr->menuPtr;
+
+ if (menuPtr->menuFlags & MENU_DELETION_PENDING) {
+ return NULL;
+ }
+
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (mePtr->namePtr == NULL) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MenuVarProc, clientData);
+ return NULL;
+ }
+
name = Tcl_GetString(mePtr->namePtr);
/*
diff --git a/generic/tkMenu.h b/generic/tkMenu.h
index bac51aa..6e3c3f4 100644
--- a/generic/tkMenu.h
+++ b/generic/tkMenu.h
@@ -68,11 +68,15 @@ typedef struct TkMenuEntry {
Tk_OptionTable optionTable; /* Option table for this menu entry. */
Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL if
* no label). */
- int labelLength; /* Number of non-NULL characters in label. */
+#if TK_MAJOR_VERSION > 8
+ size_t labelLength; /* Number of non-NULL characters in label. */
+#else
+ unsigned int labelLength; /* Number of non-NULL characters in label. */
+#endif
int state; /* State of button for display purposes:
* normal, active, or disabled. */
int underline; /* Value of -underline option: specifies index
- * of character to underline (<0 means don't
+ * of character to underline (-1 means don't
* underline anything). */
Tcl_Obj *underlinePtr; /* Index of character to underline. */
Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or None.
@@ -89,8 +93,13 @@ typedef struct TkMenuEntry {
Tcl_Obj *accelPtr; /* Accelerator string displayed at right of
* menu entry. NULL means no such accelerator.
* Malloc'ed. */
- int accelLength; /* Number of non-NULL characters in
+#if TK_MAJOR_VERSION > 8
+ size_t accelLength; /* Number of non-NULL characters in
+ * accelerator. */
+#else
+ unsigned int accelLength; /* Number of non-NULL characters in
* accelerator. */
+#endif
int indicatorOn; /* True means draw indicator, false means
* don't draw it. This field is ignored unless
* the entry is a radio or check button. */
@@ -288,6 +297,7 @@ typedef struct TkMenu {
Tcl_Obj *activeBorderWidthPtr;
/* Width of border around active element. */
Tcl_Obj *reliefPtr; /* 3-d effect: TK_RELIEF_RAISED, etc. */
+ Tcl_Obj *activeReliefPtr; /* 3-d effect for active element. */
Tcl_Obj *fontPtr; /* Text font for menu entries. */
Tcl_Obj *fgPtr; /* Foreground color for entries. */
Tcl_Obj *disabledFgPtr; /* Foreground color when disabled. NULL means
diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c
index 1abe1c4..3f492db 100644
--- a/generic/tkMenuDraw.c
+++ b/generic/tkMenuDraw.c
@@ -624,7 +624,6 @@ DisplayMenu(
int width;
int borderWidth;
Tk_3DBorder border;
- int activeBorderWidth;
int relief;
@@ -636,8 +635,6 @@ DisplayMenu(
Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
&borderWidth);
border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
- Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
- menuPtr->activeBorderWidthPtr, &activeBorderWidth);
if (menuPtr->menuType == MENUBAR) {
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
@@ -668,28 +665,16 @@ DisplayMenu(
}
mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;
- if (menuPtr->menuType == MENUBAR) {
- width = mePtr->width;
- } else {
- if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
- width = Tk_Width(menuPtr->tkwin) - mePtr->x
- - activeBorderWidth;
- } else {
- width = mePtr->width + borderWidth;
- }
- }
TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
- &menuMetrics, mePtr->x, mePtr->y, width,
+ &menuMetrics, mePtr->x, mePtr->y, mePtr->width,
mePtr->height, strictMotif, 1);
if ((index > 0) && (menuPtr->menuType != MENUBAR)
&& mePtr->columnBreak) {
mePtr = menuPtr->entries[index - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
- mePtr->x, mePtr->y + mePtr->height,
- mePtr->width,
- Tk_Height(tkwin) - mePtr->y - mePtr->height -
- activeBorderWidth, 0,
- TK_RELIEF_FLAT);
+ mePtr->x, mePtr->y + mePtr->height, mePtr->width,
+ Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,
+ 0, TK_RELIEF_FLAT);
}
}
@@ -698,19 +683,18 @@ DisplayMenu(
if (menuPtr->numEntries == 0) {
x = y = borderWidth;
- width = Tk_Width(tkwin) - 2 * activeBorderWidth;
- height = Tk_Height(tkwin) - 2 * activeBorderWidth;
+ width = Tk_Width(tkwin) - 2 * borderWidth;
+ height = Tk_Height(tkwin) - 2 * borderWidth;
} else {
mePtr = menuPtr->entries[menuPtr->numEntries - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
- Tk_Height(tkwin) - mePtr->y - mePtr->height
- - activeBorderWidth, 0,
- TK_RELIEF_FLAT);
+ Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,
+ 0, TK_RELIEF_FLAT);
x = mePtr->x + mePtr->width;
y = mePtr->y + mePtr->height;
- width = Tk_Width(tkwin) - x - activeBorderWidth;
- height = Tk_Height(tkwin) - y - activeBorderWidth;
+ width = Tk_Width(tkwin) - x - borderWidth;
+ height = Tk_Height(tkwin) - y - borderWidth;
}
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
width, height, 0, TK_RELIEF_FLAT);
diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c
index 1a4d5ae..125fe72 100644
--- a/generic/tkMenubutton.c
+++ b/generic/tkMenubutton.c
@@ -308,7 +308,7 @@ Tk_MenubuttonObjCmd(
ExposureMask|StructureNotifyMask|FocusChangeMask,
MenuButtonEventProc, mbPtr);
- if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) {
+ if (Tk_InitOptions(interp, mbPtr, optionTable, tkwin) != TCL_OK) {
Tk_DestroyWindow(mbPtr->tkwin);
return TCL_ERROR;
}
@@ -369,7 +369,7 @@ MenuButtonWidgetObjCmd(
goto error;
}
- objPtr = Tk_GetOptionValue(interp, (char *) mbPtr,
+ objPtr = Tk_GetOptionValue(interp, mbPtr,
mbPtr->optionTable, objv[2], mbPtr->tkwin);
if (objPtr == NULL) {
goto error;
@@ -379,7 +379,7 @@ MenuButtonWidgetObjCmd(
case COMMAND_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr,
+ objPtr = Tk_GetOptionInfo(interp, mbPtr,
mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
mbPtr->tkwin);
if (objPtr == NULL) {
@@ -524,7 +524,7 @@ ConfigureMenuButton(
* First pass: set options to new values.
*/
- if (Tk_SetOptions(interp, (char *) mbPtr,
+ if (Tk_SetOptions(interp, mbPtr,
mbPtr->optionTable, objc, objv,
mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
continue;
@@ -882,6 +882,19 @@ MenuButtonTextVarProc(
unsigned len;
/*
+ * See ticket [5d991b82].
+ */
+
+ if (mbPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MenuButtonTextVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
diff --git a/generic/tkMessage.c b/generic/tkMessage.c
index 2b71998..c009fe7 100644
--- a/generic/tkMessage.c
+++ b/generic/tkMessage.c
@@ -13,8 +13,8 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
+#include "default.h"
/*
* A data structure of the following type is kept for each message widget
@@ -242,7 +242,7 @@ Tk_MessageObjCmd(
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
msgPtr = ckalloc(sizeof(Message));
- memset(msgPtr, 0, (size_t) sizeof(Message));
+ memset(msgPtr, 0, sizeof(Message));
/*
* Set values for those fields that don't take a 0 or NULL value.
@@ -267,7 +267,7 @@ Tk_MessageObjCmd(
Tk_CreateEventHandler(msgPtr->tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
MessageEventProc, msgPtr);
- if (Tk_InitOptions(interp, (char *)msgPtr, optionTable, tkwin) != TCL_OK) {
+ if (Tk_InitOptions(interp, msgPtr, optionTable, tkwin) != TCL_OK) {
Tk_DestroyWindow(msgPtr->tkwin);
return TCL_ERROR;
}
@@ -331,7 +331,7 @@ MessageWidgetObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option");
result = TCL_ERROR;
} else {
- objPtr = Tk_GetOptionValue(interp, (char *) msgPtr,
+ objPtr = Tk_GetOptionValue(interp, msgPtr,
msgPtr->optionTable, objv[2], msgPtr->tkwin);
if (objPtr == NULL) {
result = TCL_ERROR;
@@ -343,7 +343,7 @@ MessageWidgetObjCmd(
break;
case MESSAGE_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) msgPtr,
+ objPtr = Tk_GetOptionInfo(interp, msgPtr,
msgPtr->optionTable, (objc == 3) ? objv[2] : NULL,
msgPtr->tkwin);
if (objPtr == NULL) {
@@ -455,7 +455,7 @@ ConfigureMessage(
MessageTextVarProc, msgPtr);
}
- if (Tk_SetOptions(interp, (char *) msgPtr, msgPtr->optionTable, objc, objv,
+ if (Tk_SetOptions(interp, msgPtr, msgPtr->optionTable, objc, objv,
msgPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
@@ -839,6 +839,19 @@ MessageTextVarProc(
const char *value;
/*
+ * See ticket [5d991b82].
+ */
+
+ if (msgPtr->textVarName == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ MessageTextVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
diff --git a/generic/tkObj.c b/generic/tkObj.c
index 7c09656..b857d98 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -73,8 +73,12 @@ typedef struct MMRep {
typedef struct WindowRep {
Tk_Window tkwin; /* Cached window; NULL if not found. */
TkMainInfo *mainPtr; /* MainWindow associated with tkwin. */
- long epoch; /* Value of mainPtr->deletionEpoch at last
+#if TCL_MAJOR_VERSION > 8
+ size_t epoch; /* Value of mainPtr->deletionEpoch at last
* successful lookup. */
+#else
+ long epoch;
+#endif
} WindowRep;
/*
@@ -104,7 +108,7 @@ static const Tcl_ObjType pixelObjType = {
FreePixelInternalRep, /* freeIntRepProc */
DupPixelInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetPixelFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -118,7 +122,7 @@ static const Tcl_ObjType mmObjType = {
FreeMMInternalRep, /* freeIntRepProc */
DupMMInternalRep, /* dupIntRepProc */
UpdateStringOfMM, /* updateStringProc */
- SetMMFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -131,7 +135,7 @@ static const Tcl_ObjType windowObjType = {
FreeWindowInternalRep, /* freeIntRepProc */
DupWindowInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetWindowFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -153,8 +157,19 @@ GetTypeCache(void)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (tsdPtr->doubleTypePtr == NULL) {
- tsdPtr->doubleTypePtr = Tcl_GetObjType("double");
- tsdPtr->intTypePtr = Tcl_GetObjType("int");
+ /* Smart initialization of doubleTypePtr/intTypePtr without
+ * hash-table lookup or creating complete Tcl_Obj's */
+ Tcl_Obj obj;
+ obj.length = 3;
+ obj.bytes = (char *)"0.0";
+ obj.typePtr = NULL;
+ Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
+ tsdPtr->doubleTypePtr = obj.typePtr;
+ obj.bytes += 2;
+ obj.length = 1;
+ obj.typePtr = NULL;
+ Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
+ tsdPtr->intTypePtr = obj.typePtr;
}
return tsdPtr;
}
@@ -657,7 +672,7 @@ UpdateStringOfMM(
{
MMRep *mmPtr;
char buffer[TCL_DOUBLE_SPACE];
- register int len;
+ size_t len;
mmPtr = objPtr->internalRep.twoPtrValue.ptr1;
/* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
@@ -666,7 +681,7 @@ UpdateStringOfMM(
}
Tcl_PrintDouble(NULL, mmPtr->value, buffer);
- len = (int)strlen(buffer);
+ len = strlen(buffer);
objPtr->bytes = ckalloc(len + 1);
strcpy(objPtr->bytes, buffer);
@@ -881,7 +896,7 @@ SetWindowFromAny(
* Free the old internalRep before setting the new one.
*/
- (void)Tcl_GetString(objPtr);
+ Tcl_GetString(objPtr);
typePtr = objPtr->typePtr;
if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
typePtr->freeIntRepProc(objPtr);
@@ -1112,7 +1127,7 @@ TkParsePadAmount(
* None
*
* Side effects:
- * All instances of Tcl_ObjType structues used in Tk are registered with
+ * All instances of Tcl_ObjType structures used in Tk are registered with
* Tcl.
*
*----------------------------------------------------------------------
diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c
index 920d93e..4473a3e 100644
--- a/generic/tkOldConfig.c
+++ b/generic/tkOldConfig.c
@@ -25,20 +25,24 @@
#define INIT 0x20
+#ifndef TK_CONFIG_OPTION_SPECIFIED
+# define TK_CONFIG_OPTION_SPECIFIED (1 << 4)
+#endif
+
/*
* Forward declarations for functions defined later in this file:
*/
static int DoConfig(Tcl_Interp *interp, Tk_Window tkwin,
Tk_ConfigSpec *specPtr, Tk_Uid value,
- int valueIsUid, char *widgRec);
+ int valueIsUid, void *widgRec);
static Tk_ConfigSpec * FindConfigSpec(Tcl_Interp *interp,
Tk_ConfigSpec *specs, const char *argvName,
int needFlags, int hateFlags);
static char * FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
- const Tk_ConfigSpec *specPtr, char *widgRec);
+ const Tk_ConfigSpec *specPtr, void *widgRec);
static const char * FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
- const Tk_ConfigSpec *specPtr, char *widgRec,
+ const Tk_ConfigSpec *specPtr, void *widgRec,
char *buffer, Tcl_FreeProc **freeProcPtr);
static Tk_ConfigSpec * GetCachedSpecs(Tcl_Interp *interp,
const Tk_ConfigSpec *staticSpecs);
@@ -340,10 +344,10 @@ DoConfig(
Tk_Uid value, /* Value to use to fill in widgRec. */
int valueIsUid, /* Non-zero means value is a Tk_Uid; zero
* means it's an ordinary string. */
- char *widgRec) /* Record whose fields are to be modified.
+ void *widgRec) /* Record whose fields are to be modified.
* Values must be properly initialized. */
{
- char *ptr;
+ void *ptr;
Tk_Uid uid;
int nullValue;
@@ -353,7 +357,7 @@ DoConfig(
}
do {
- ptr = widgRec + specPtr->offset;
+ ptr = (char *)widgRec + specPtr->offset;
switch (specPtr->type) {
case TK_CONFIG_BOOLEAN:
if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
@@ -689,7 +693,7 @@ FormatConfigInfo(
register const Tk_ConfigSpec *specPtr,
/* Pointer to information describing
* option. */
- char *widgRec) /* Pointer to record holding current values of
+ void *widgRec) /* Pointer to record holding current values of
* info for widget. */
{
const char *argv[6];
@@ -755,7 +759,7 @@ FormatConfigValue(
Tk_Window tkwin, /* Window corresponding to widget. */
const Tk_ConfigSpec *specPtr, /* Pointer to information describing option.
* Must not point to a synonym option. */
- char *widgRec, /* Pointer to record holding current values of
+ void *widgRec, /* Pointer to record holding current values of
* info for widget. */
char *buffer, /* Static buffer to use for small values.
* Must have at least 200 bytes of storage. */
@@ -763,10 +767,11 @@ FormatConfigValue(
* function to free the result, or NULL if
* result is static. */
{
- const char *ptr, *result;
+ void *ptr;
+ const char *result;
*freeProcPtr = NULL;
- ptr = widgRec + specPtr->offset;
+ ptr = (char *)widgRec + specPtr->offset;
result = "";
switch (specPtr->type) {
case TK_CONFIG_BOOLEAN:
diff --git a/generic/tkOldTest.c b/generic/tkOldTest.c
index df1bb6c..f78ebba 100644
--- a/generic/tkOldTest.c
+++ b/generic/tkOldTest.c
@@ -172,9 +172,9 @@ ImageCreate(
timPtr->interp = interp;
timPtr->width = 30;
timPtr->height = 15;
- timPtr->imageName = ckalloc((unsigned) (strlen(name) + 1));
+ timPtr->imageName = ckalloc(strlen(name) + 1);
strcpy(timPtr->imageName, name);
- timPtr->varName = ckalloc((unsigned) (strlen(varName) + 1));
+ timPtr->varName = ckalloc(strlen(varName) + 1);
strcpy(timPtr->varName, varName);
Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
*clientDataPtr = timPtr;
diff --git a/generic/tkOption.c b/generic/tkOption.c
index 24e7fb3..cebb86a 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -260,7 +260,7 @@ Tk_AddOption(
register const char *p;
const char *field;
int count, firstField;
- ptrdiff_t length;
+ size_t length;
#define TMP_SIZE 100
char tmp[TMP_SIZE+1];
ThreadSpecificData *tsdPtr =
@@ -311,7 +311,7 @@ Tk_AddOption(
if (length > TMP_SIZE) {
length = TMP_SIZE;
}
- strncpy(tmp, field, (size_t) length);
+ strncpy(tmp, field, length);
tmp[length] = 0;
newEl.nameUid = Tk_GetUid(tmp);
if (isupper(UCHAR(*field))) {
@@ -1081,7 +1081,8 @@ ReadOptionFile(
{
const char *realName;
Tcl_Obj *buffer;
- int result, bufferSize;
+ int result;
+ size_t bufferSize;
Tcl_Channel chan;
Tcl_DString newName;
@@ -1112,7 +1113,7 @@ ReadOptionFile(
Tcl_IncrRefCount(buffer);
Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
- if (bufferSize < 0) {
+ if (bufferSize == (size_t)-1) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading file \"%s\": %s",
fileName, Tcl_PosixError(interp)));
diff --git a/generic/tkPack.c b/generic/tkPack.c
index 88a4b2d..d7fabca 100644
--- a/generic/tkPack.c
+++ b/generic/tkPack.c
@@ -122,8 +122,10 @@ static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
int objc, Tcl_Obj *const objv[]);
static void DestroyPacker(void *memPtr);
static Packer * GetPacker(Tk_Window tkwin);
+#ifndef TK_NO_DEPRECATED
static int PackAfter(Tcl_Interp *interp, Packer *prevPtr,
Packer *masterPtr, int objc,Tcl_Obj *const objv[]);
+#endif /* !TK_NO_DEPRECATED */
static void PackStructureProc(ClientData clientData,
XEvent *eventPtr);
static void Unlink(Packer *packPtr);
@@ -197,11 +199,14 @@ Tk_PackObjCmd(
Tk_Window tkwin = clientData;
const char *argv2;
static const char *const optionStrings[] = {
- /* after, append, before and unpack are deprecated */
+#ifndef TK_NO_DEPRECATED
"after", "append", "before", "unpack",
+#endif /* !TK_NO_DEPRECATED */
"configure", "forget", "info", "propagate", "slaves", NULL };
enum options {
+#ifndef TK_NO_DEPRECATED
PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK,
+#endif /* !TK_NO_DEPRECATED */
PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
int index;
@@ -219,6 +224,7 @@ Tk_PackObjCmd(
if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
sizeof(char *), "option", 0, &index) != TCL_OK) {
+#ifndef TK_NO_DEPRECATED
/*
* Call it again without the deprecated ones to get a proper error
* message. This works well since there can't be any ambiguity between
@@ -228,11 +234,13 @@ Tk_PackObjCmd(
Tcl_ResetResult(interp);
Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4],
sizeof(char *), "option", 0, &index);
+#endif /* TK_NO_DEPRECATED */
return TCL_ERROR;
}
argv2 = Tcl_GetString(objv[2]);
switch ((enum options) index) {
+#ifndef TK_NO_DEPRECATED
case PACK_AFTER: {
Packer *prevPtr;
Tk_Window tkwin2;
@@ -297,6 +305,7 @@ Tk_PackObjCmd(
}
return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3);
}
+#endif /* !TK_NO_DEPRECATED */
case PACK_CONFIGURE:
if (argv2[0] != '.') {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -458,6 +467,7 @@ Tk_PackObjCmd(
Tcl_SetObjResult(interp, resultObj);
break;
}
+#ifndef TK_NO_DEPRECATED
case PACK_UNPACK: {
Tk_Window tkwin2;
Packer *packPtr;
@@ -481,6 +491,7 @@ Tk_PackObjCmd(
}
break;
}
+#endif /* !TK_NO_DEPRECATED */
}
return TCL_OK;
@@ -1087,6 +1098,7 @@ GetPacker(
*------------------------------------------------------------------------
*/
+#ifndef TK_NO_DEPRECATED
static int
PackAfter(
Tcl_Interp *interp, /* Interpreter for error reporting. */
@@ -1169,8 +1181,8 @@ PackAfter(
packPtr->flags |= OLD_STYLE;
for (index = 0 ; index < optionCount; index++) {
Tcl_Obj *curOptPtr = options[index];
- const char *curOpt = Tcl_GetString(curOptPtr);
- size_t length = curOptPtr->length;
+ size_t length;
+ const char *curOpt = TkGetStringFromObj(curOptPtr, &length);
c = curOpt[0];
@@ -1307,6 +1319,7 @@ PackAfter(
}
return TCL_OK;
}
+#endif /* !TK_NO_DEPRECATED */
/*
*----------------------------------------------------------------------
@@ -1362,7 +1375,7 @@ Unlink(
* handling it and should mark it as free.
*/
- if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) {
+ if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
TkFreeGeometryMaster(masterPtr->tkwin, "pack");
masterPtr->flags &= ~ALLOCED_MASTER;
}
diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c
index 2451647..c0bbf5f 100644
--- a/generic/tkPanedWindow.c
+++ b/generic/tkPanedWindow.c
@@ -13,8 +13,8 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
+#include "default.h"
/*
* Flag values for "sticky"ness. The 16 combinations subsume the packer's
@@ -236,7 +236,7 @@ static void AdjustForSticky(int sticky, int cavityWidth,
int *slaveWidthPtr, int *slaveHeightPtr);
static void MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int ObjectIsEmpty(Tcl_Obj *objPtr);
-static char * ComputeSlotAddress(char *recordPtr, int offset);
+static void * ComputeSlotAddress(void *recordPtr, int offset);
static int PanedWindowIdentifyCoords(PanedWindow *pwPtr,
Tcl_Interp *interp, int x, int y);
@@ -459,7 +459,7 @@ Tk_PanedWindowObjCmd(
Tcl_Preserve(pwPtr->tkwin);
- if (Tk_InitOptions(interp, (char *) pwPtr, pwOpts->pwOptions,
+ if (Tk_InitOptions(interp, pwPtr, pwOpts->pwOptions,
tkwin) != TCL_OK) {
Tk_DestroyWindow(pwPtr->tkwin);
return TCL_ERROR;
@@ -578,7 +578,7 @@ PanedWindowWidgetObjCmd(
result = TCL_ERROR;
break;
}
- resultObj = Tk_GetOptionValue(interp, (char *) pwPtr,
+ resultObj = Tk_GetOptionValue(interp, pwPtr,
pwPtr->optionTable, objv[2], pwPtr->tkwin);
if (resultObj == NULL) {
result = TCL_ERROR;
@@ -590,7 +590,7 @@ PanedWindowWidgetObjCmd(
case PW_CONFIGURE:
resultObj = NULL;
if (objc <= 3) {
- resultObj = Tk_GetOptionInfo(interp, (char *) pwPtr,
+ resultObj = Tk_GetOptionInfo(interp, pwPtr,
pwPtr->optionTable,
(objc == 3) ? objv[2] : NULL, pwPtr->tkwin);
if (resultObj == NULL) {
@@ -669,7 +669,7 @@ PanedWindowWidgetObjCmd(
for (i = 0; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i]->tkwin == tkwin) {
resultObj = Tk_GetOptionValue(interp,
- (char *) pwPtr->slaves[i], pwPtr->slaveOpts,
+ pwPtr->slaves[i], pwPtr->slaveOpts,
objv[3], tkwin);
}
}
@@ -709,7 +709,7 @@ PanedWindowWidgetObjCmd(
for (i = 0; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i]->tkwin == tkwin) {
resultObj = Tk_GetOptionInfo(interp,
- (char *) pwPtr->slaves[i], pwPtr->slaveOpts,
+ pwPtr->slaves[i], pwPtr->slaveOpts,
(objc == 4) ? objv[3] : NULL,
pwPtr->tkwin);
if (resultObj == NULL) {
@@ -848,7 +848,7 @@ ConfigureSlaves(
*/
memset((void *)&options, 0, sizeof(Slave));
- if (Tk_SetOptions(interp, (char *) &options, pwPtr->slaveOpts,
+ if (Tk_SetOptions(interp, &options, pwPtr->slaveOpts,
objc - firstOptionArg, objv + firstOptionArg,
pwPtr->tkwin, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
@@ -925,7 +925,7 @@ ConfigureSlaves(
found = 0;
for (j = 0; j < pwPtr->numSlaves; j++) {
if (pwPtr->slaves[j] != NULL && pwPtr->slaves[j]->tkwin == tkwin) {
- Tk_SetOptions(interp, (char *) pwPtr->slaves[j],
+ Tk_SetOptions(interp, pwPtr->slaves[j],
pwPtr->slaveOpts, objc - firstOptionArg,
objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
if (pwPtr->slaves[j]->minSize < 0) {
@@ -972,9 +972,9 @@ ConfigureSlaves(
slavePtr = ckalloc(sizeof(Slave));
memset(slavePtr, 0, sizeof(Slave));
- Tk_InitOptions(interp, (char *)slavePtr, pwPtr->slaveOpts,
+ Tk_InitOptions(interp, slavePtr, pwPtr->slaveOpts,
pwPtr->tkwin);
- Tk_SetOptions(interp, (char *)slavePtr, pwPtr->slaveOpts,
+ Tk_SetOptions(interp, slavePtr, pwPtr->slaveOpts,
objc - firstOptionArg, objv + firstOptionArg,
pwPtr->tkwin, NULL, NULL);
slavePtr->tkwin = tkwin;
@@ -1249,7 +1249,7 @@ ConfigurePanedWindow(
Tk_SavedOptions savedOptions;
int typemask = 0;
- if (Tk_SetOptions(interp, (char *) pwPtr, pwPtr->optionTable, objc, objv,
+ if (Tk_SetOptions(interp, pwPtr, pwPtr->optionTable, objc, objv,
pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) {
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
@@ -1370,11 +1370,15 @@ PanedWindowEventProc(
DestroyPanedWindow(pwPtr);
} else if (eventPtr->type == UnmapNotify) {
for (i = 0; i < pwPtr->numSlaves; i++) {
- Tk_UnmapWindow(pwPtr->slaves[i]->tkwin);
+ if (!pwPtr->slaves[i]->hide) {
+ Tk_UnmapWindow(pwPtr->slaves[i]->tkwin);
+ }
}
} else if (eventPtr->type == MapNotify) {
for (i = 0; i < pwPtr->numSlaves; i++) {
- Tk_MapWindow(pwPtr->slaves[i]->tkwin);
+ if (!pwPtr->slaves[i]->hide) {
+ Tk_MapWindow(pwPtr->slaves[i]->tkwin);
+ }
}
}
}
@@ -1480,10 +1484,10 @@ DisplayPanedWindow(
*/
if (horizontal) {
- sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderWidth(tkwin));
+ sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderLeft(tkwin));
sashWidth = pwPtr->sashWidth;
} else {
- sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderWidth(tkwin));
+ sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderLeft(tkwin));
sashHeight = pwPtr->sashWidth;
}
@@ -1750,7 +1754,7 @@ ArrangePanes(
*/
paneDynSize = paneDynMinSize = 0;
- internalBW = Tk_InternalBorderWidth(pwPtr->tkwin);
+ internalBW = Tk_InternalBorderLeft(pwPtr->tkwin);
pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
x = y = internalBW;
@@ -1785,10 +1789,18 @@ ArrangePanes(
*/
if (horizontal) {
- paneSize = slavePtr->paneWidth;
+ if (slavePtr->width > 0) {
+ paneSize = slavePtr->width;
+ } else {
+ paneSize = slavePtr->paneWidth;
+ }
stretchReserve -= paneSize + (2 * slavePtr->padx);
} else {
- paneSize = slavePtr->paneHeight;
+ if (slavePtr->height > 0) {
+ paneSize = slavePtr->height;
+ } else {
+ paneSize = slavePtr->paneHeight;
+ }
stretchReserve -= paneSize + (2 * slavePtr->pady);
}
if (IsStretchable(slavePtr->stretch,i,first,last)
@@ -1838,10 +1850,18 @@ ArrangePanes(
*/
if (horizontal) {
- paneSize = slavePtr->paneWidth;
+ if (slavePtr->width > 0) {
+ paneSize = slavePtr->width;
+ } else {
+ paneSize = slavePtr->paneWidth;
+ }
pwSize = pwWidth;
} else {
- paneSize = slavePtr->paneHeight;
+ if (slavePtr->height > 0) {
+ paneSize = slavePtr->height;
+ } else {
+ paneSize = slavePtr->paneHeight;
+ }
pwSize = pwHeight;
}
if (IsStretchable(slavePtr->stretch, i, first, last)) {
@@ -2180,7 +2200,7 @@ ComputeGeometry(
pwPtr->flags |= REQUESTED_RELAYOUT;
- x = y = internalBw = Tk_InternalBorderWidth(pwPtr->tkwin);
+ x = y = internalBw = Tk_InternalBorderLeft(pwPtr->tkwin);
reqWidth = reqHeight = 0;
/*
@@ -2435,7 +2455,8 @@ SetSticky(
int flags) /* Flags for the option, set Tk_SetOptions. */
{
int sticky = 0;
- char c, *internalPtr;
+ char c;
+ void *internalPtr;
const char *string;
internalPtr = ComputeSlotAddress(recordPtr, internalOffset);
@@ -2886,7 +2907,7 @@ PanedWindowProxyCommand(
return TCL_ERROR;
}
- internalBW = Tk_InternalBorderWidth(pwPtr->tkwin);
+ internalBW = Tk_InternalBorderLeft(pwPtr->tkwin);
if (pwPtr->orient == ORIENT_HORIZONTAL) {
if (x < 0) {
x = 0;
@@ -2895,10 +2916,10 @@ PanedWindowProxyCommand(
if (x > pwWidth) {
x = pwWidth;
}
- y = Tk_InternalBorderWidth(pwPtr->tkwin);
+ y = Tk_InternalBorderLeft(pwPtr->tkwin);
sashWidth = pwPtr->sashWidth;
sashHeight = Tk_Height(pwPtr->tkwin) -
- (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
+ (2 * Tk_InternalBorderLeft(pwPtr->tkwin));
} else {
if (y < 0) {
y = 0;
@@ -2907,10 +2928,10 @@ PanedWindowProxyCommand(
if (y > pwHeight) {
y = pwHeight;
}
- x = Tk_InternalBorderWidth(pwPtr->tkwin);
+ x = Tk_InternalBorderLeft(pwPtr->tkwin);
sashHeight = pwPtr->sashWidth;
sashWidth = Tk_Width(pwPtr->tkwin) -
- (2 * Tk_InternalBorderWidth(pwPtr->tkwin));
+ (2 * Tk_InternalBorderLeft(pwPtr->tkwin));
}
if (sashWidth < 1) {
@@ -2972,16 +2993,13 @@ static int
ObjectIsEmpty(
Tcl_Obj *objPtr) /* Object to test. May be NULL. */
{
- int length;
-
if (objPtr == NULL) {
return 1;
}
- if (objPtr->bytes != NULL) {
- return (objPtr->length == 0);
+ if (objPtr->bytes == NULL) {
+ Tcl_GetString(objPtr);
}
- (void)Tcl_GetStringFromObj(objPtr, &length);
- return (length == 0);
+ return (objPtr->length == 0);
}
/*
@@ -3002,13 +3020,13 @@ ObjectIsEmpty(
*----------------------------------------------------------------------
*/
-static char *
+static void *
ComputeSlotAddress(
- char *recordPtr, /* Pointer to the start of a record. */
+ void *recordPtr, /* Pointer to the start of a record. */
int offset) /* Offset of a slot within that record; may be < 0. */
{
if (offset >= 0) {
- return recordPtr + offset;
+ return (char *)recordPtr + offset;
} else {
return NULL;
}
@@ -3049,7 +3067,7 @@ PanedWindowIdentifyCoords(
} else {
sashHeight = Tk_ReqHeight(pwPtr->tkwin);
}
- sashHeight -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
+ sashHeight -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin);
if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) {
sashWidth = pwPtr->handleSize;
lpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2;
@@ -3077,7 +3095,7 @@ PanedWindowIdentifyCoords(
} else {
sashWidth = Tk_ReqWidth(pwPtr->tkwin);
}
- sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin);
+ sashWidth -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin);
lpad = rpad = 0;
}
diff --git a/generic/tkPlace.c b/generic/tkPlace.c
index 9fa406a..e627794 100644
--- a/generic/tkPlace.c
+++ b/generic/tkPlace.c
@@ -290,7 +290,7 @@ Tk_PlaceObjCmd(
if (slavePtr == NULL) {
return TCL_OK;
}
- objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, optionTable,
+ objPtr = Tk_GetOptionInfo(interp, slavePtr, optionTable,
(objc == 4) ? objv[3] : NULL, tkwin);
if (objPtr == NULL) {
return TCL_ERROR;
@@ -628,7 +628,7 @@ ConfigureSlave(
slavePtr = CreateSlave(tkwin, table);
- if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv,
+ if (Tk_SetOptions(interp, slavePtr, table, objc, objv,
slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
goto error;
}
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index 50b5f1a..4d48fe7 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -759,11 +759,103 @@ DisplayRectOval(
&x1, &y1);
Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3],
&x2, &y2);
- if (x2 <= x1) {
- x2 = x1+1;
- }
- if (y2 <= y1) {
- y2 = y1+1;
+ if (x2 == x1) {
+
+ /*
+ * The width of the bounding box corresponds to less than one pixel
+ * on screen. Adjustment is needed to avoid drawing attempts with zero
+ * width items (which would draw nothing). The bounding box spans
+ * either 1 or 2 pixels. Select which pixel will be drawn.
+ */
+
+ short ix1 = (short) (rectOvalPtr->bbox[0]);
+ short ix2 = (short) (rectOvalPtr->bbox[2]);
+
+ if (ix1 == ix2) {
+
+ /*
+ * x1 and x2 are "within the same pixel". Use this pixel.
+ * Note: the degenerated case (bbox[0]==bbox[2]) of a completely
+ * flat box results in arbitrary selection of the pixel at the
+ * right (with positive coordinate) or left (with negative
+ * coordinate) of the box. There is no "best choice" here.
+ */
+
+ if (ix1 > 0) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ } else {
+
+ /*
+ * (x1,x2) span two pixels. Select the one with the larger
+ * covered "area".
+ */
+
+ if (ix1 > 0) {
+ if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ } else {
+ if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) {
+ x2 += 1;
+ } else {
+ x1 -= 1;
+ }
+ }
+ }
+ }
+ if (y2 == y1) {
+
+ /*
+ * The height of the bounding box corresponds to less than one pixel
+ * on screen. Adjustment is needed to avoid drawing attempts with zero
+ * height items (which would draw nothing). The bounding box spans
+ * either 1 or 2 pixels. Select which pixel will be drawn.
+ */
+
+ short iy1 = (short) (rectOvalPtr->bbox[1]);
+ short iy2 = (short) (rectOvalPtr->bbox[3]);
+
+ if (iy1 == iy2) {
+
+ /*
+ * y1 and y2 are "within the same pixel". Use this pixel.
+ * Note: the degenerated case (bbox[1]==bbox[3]) of a completely
+ * flat box results in arbitrary selection of the pixel below
+ * (with positive coordinate) or above (with negative coordinate)
+ * the box. There is no "best choice" here.
+ */
+
+ if (iy1 > 0) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ } else {
+
+ /*
+ * (y1,y2) span two pixels. Select the one with the larger
+ * covered "area".
+ */
+
+ if (iy1 > 0) {
+ if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ } else {
+ if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) {
+ y2 += 1;
+ } else {
+ y1 -= 1;
+ }
+ }
+ }
}
/*
diff --git a/generic/tkScale.c b/generic/tkScale.c
index cc7c294..8b016a2 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -17,9 +17,13 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
#include "tkScale.h"
+#include "default.h"
+
+#if defined(_WIN32)
+#define snprintf _snprintf
+#endif
/*
* The following table defines the legal values for the -orient option. It is
@@ -296,13 +300,19 @@ Tk_ScaleObjCmd(
ExposureMask|StructureNotifyMask|FocusChangeMask,
ScaleEventProc, scalePtr);
- if ((Tk_InitOptions(interp, (char *) scalePtr, optionTable, tkwin)
+ if ((Tk_InitOptions(interp, scalePtr, optionTable, tkwin)
!= TCL_OK) ||
(ConfigureScale(interp, scalePtr, objc - 2, objv + 2) != TCL_OK)) {
Tk_DestroyWindow(scalePtr->tkwin);
return TCL_ERROR;
}
+ /*
+ * The widget was just created, no command callback must be invoked.
+ */
+
+ scalePtr->flags &= ~INVOKE_COMMAND;
+
Tcl_SetObjResult(interp, TkNewWindowObj(scalePtr->tkwin));
return TCL_OK;
}
@@ -353,7 +363,7 @@ ScaleWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "cget option");
goto error;
}
- objPtr = Tk_GetOptionValue(interp, (char *) scalePtr,
+ objPtr = Tk_GetOptionValue(interp, scalePtr,
scalePtr->optionTable, objv[2], scalePtr->tkwin);
if (objPtr == NULL) {
goto error;
@@ -362,7 +372,7 @@ ScaleWidgetObjCmd(
break;
case COMMAND_CONFIGURE:
if (objc <= 3) {
- objPtr = Tk_GetOptionInfo(interp, (char *) scalePtr,
+ objPtr = Tk_GetOptionInfo(interp, scalePtr,
scalePtr->optionTable,
(objc == 3) ? objv[2] : NULL, scalePtr->tkwin);
if (objPtr == NULL) {
@@ -572,7 +582,7 @@ ConfigureScale(
* First pass: set options to new values.
*/
- if (Tk_SetOptions(interp, (char *) scalePtr,
+ if (Tk_SetOptions(interp, scalePtr,
scalePtr->optionTable, objc, objv, scalePtr->tkwin,
&savedOptions, NULL) != TCL_OK) {
continue;
@@ -628,7 +638,7 @@ ConfigureScale(
ComputeFormat(scalePtr);
- scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0;
+ scalePtr->labelLength = scalePtr->label ? strlen(scalePtr->label) : 0;
Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder);
@@ -671,9 +681,9 @@ ConfigureScale(
} else {
char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];
- sprintf(varString, scalePtr->format, varValue);
- sprintf(scaleString, scalePtr->format, scalePtr->value);
- if (strcmp(varString, scaleString)) {
+ Tcl_PrintDouble(NULL, varValue, varString);
+ Tcl_PrintDouble(NULL, scalePtr->value, scaleString);
+ if (strcmp(varString, scaleString)) {
ScaleSetVariable(scalePtr);
}
}
@@ -930,10 +940,16 @@ ComputeScaleGeometry(
* whichever length is longer.
*/
- sprintf(valueString, scalePtr->format, scalePtr->fromValue);
+ if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->fromValue) < 0) {
+ valueString[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
- sprintf(valueString, scalePtr->format, scalePtr->toValue);
+ if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->toValue) < 0) {
+ valueString[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
if (valuePixels < tmp) {
valuePixels = tmp;
@@ -1177,6 +1193,19 @@ ScaleVarProc(
int result;
/*
+ * See ticket [5d991b82].
+ */
+
+ if (scalePtr->varNamePtr == NULL) {
+ if (!(flags & TCL_INTERP_DESTROYED)) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ ScaleVarProc, clientData);
+ }
+ return NULL;
+ }
+
+ /*
* If the variable is unset, then immediately recreate it unless the whole
* interpreter is going away.
*/
@@ -1268,7 +1297,14 @@ TkScaleSetValue(
return;
}
scalePtr->value = value;
- if (invokeCommand) {
+
+ /*
+ * Schedule command callback invocation only if there is such a command
+ * already registered, otherwise the callback would trigger later when
+ * configuring the widget -command option even if the value did not change.
+ */
+
+ if ((invokeCommand) && (scalePtr->command != NULL)) {
scalePtr->flags |= INVOKE_COMMAND;
}
TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER);
@@ -1301,7 +1337,10 @@ ScaleSetVariable(
if (scalePtr->varNamePtr != NULL) {
char string[TCL_DOUBLE_SPACE];
- sprintf(string, scalePtr->format, scalePtr->value);
+ if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
+ scalePtr->value) < 0) {
+ string[TCL_DOUBLE_SPACE - 1] = '\0';
+ }
scalePtr->flags |= SETTING_VAR;
Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
diff --git a/generic/tkScale.h b/generic/tkScale.h
index 4fd9995..043d23c 100644
--- a/generic/tkScale.h
+++ b/generic/tkScale.h
@@ -73,7 +73,7 @@ typedef struct TkScale {
* values. 0 means we get to choose the number
* based on resolution and/or the range of the
* scale. */
- char format[10]; /* Sprintf conversion specifier computed from
+ char format[16]; /* Sprintf conversion specifier computed from
* digits and other information. */
double bigIncrement; /* Amount to use for large increments to scale
* value. (0 means we pick a value). */
@@ -85,7 +85,11 @@ typedef struct TkScale {
int repeatInterval; /* Interval between autorepeats (in ms). */
char *label; /* Label to display above or to right of
* scale; NULL means don't display a label. */
- int labelLength; /* Number of non-NULL chars. in label. */
+#if TK_MAJOR_VERSION > 8
+ size_t labelLength; /* Number of non-NULL chars. in label. */
+#else
+ unsigned int labelLength; /* Number of non-NULL chars. in label. */
+#endif
enum state state; /* Values are active, normal, or disabled.
* Value of scale cannot be changed when
* disabled. */
diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c
index 5017d30..02fb740 100644
--- a/generic/tkScrollbar.c
+++ b/generic/tkScrollbar.c
@@ -179,10 +179,12 @@ Tk_ScrollbarObjCmd(
scrollPtr->sliderLast = 0;
scrollPtr->activeField = 0;
scrollPtr->activeRelief = TK_RELIEF_RAISED;
+#ifndef TK_NO_DEPRECATED
scrollPtr->totalUnits = 0;
scrollPtr->windowUnits = 0;
scrollPtr->firstUnit = 0;
scrollPtr->lastUnit = 0;
+#endif /* TK_NO_DEPRECATED */
scrollPtr->firstFraction = 0.0;
scrollPtr->lastFraction = 0.0;
scrollPtr->cursor = None;
@@ -224,8 +226,8 @@ ScrollbarWidgetObjCmd(
Tcl_Obj *const objv[]) /* Argument strings. */
{
register TkScrollbar *scrollPtr = clientData;
- int result = TCL_OK;
- int length, cmdIndex;
+ int result = TCL_OK, cmdIndex;
+ size_t length;
static const char *const commandNames[] = {
"activate", "cget", "configure", "delta", "fraction",
"get", "identify", "set", NULL
@@ -269,7 +271,7 @@ ScrollbarWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "activate element");
goto error;
}
- c = Tcl_GetStringFromObj(objv[2], &length)[0];
+ c = TkGetStringFromObj(objv[2], &length)[0];
oldActiveField = scrollPtr->activeField;
if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) {
scrollPtr->activeField = TOP_ARROW;
@@ -377,17 +379,19 @@ ScrollbarWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "get");
goto error;
}
- if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
- resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
- resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
- Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
- } else {
+#ifndef TK_NO_DEPRECATED
+ if (scrollPtr->flags & OLD_STYLE_COMMANDS) {
resObjs[0] = Tcl_NewIntObj(scrollPtr->totalUnits);
resObjs[1] = Tcl_NewIntObj(scrollPtr->windowUnits);
resObjs[2] = Tcl_NewIntObj(scrollPtr->firstUnit);
resObjs[3] = Tcl_NewIntObj(scrollPtr->lastUnit);
Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs));
+ break;
}
+#endif /* TK_NO_DEPRECATED */
+ resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
+ resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
break;
}
case COMMAND_IDENTIFY: {
@@ -413,8 +417,6 @@ ScrollbarWidgetObjCmd(
break;
}
case COMMAND_SET: {
- int totalUnits, windowUnits, firstUnit, lastUnit;
-
if (objc == 4) {
double first, last;
@@ -438,8 +440,10 @@ ScrollbarWidgetObjCmd(
} else {
scrollPtr->lastFraction = last;
}
- scrollPtr->flags |= NEW_STYLE_COMMANDS;
+#ifndef TK_NO_DEPRECATED
+ scrollPtr->flags &= ~OLD_STYLE_COMMANDS;
} else if (objc == 6) {
+ int totalUnits, windowUnits, firstUnit, lastUnit;
if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) {
goto error;
}
@@ -476,11 +480,10 @@ ScrollbarWidgetObjCmd(
scrollPtr->firstFraction = ((double) firstUnit)/totalUnits;
scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits;
}
- scrollPtr->flags &= ~NEW_STYLE_COMMANDS;
+ scrollPtr->flags |= OLD_STYLE_COMMANDS;
+#endif /* !TK_NO_DEPRECATED */
} else {
Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction");
- Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]),
- " set totalUnits windowUnits firstUnit lastUnit\"", NULL);
goto error;
}
TkpComputeScrollbarGeometry(scrollPtr);
diff --git a/generic/tkScrollbar.h b/generic/tkScrollbar.h
index b0cd085..99f16a4 100644
--- a/generic/tkScrollbar.h
+++ b/generic/tkScrollbar.h
@@ -93,21 +93,25 @@ typedef struct TkScrollbar {
* form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new"
* form (firstFraction and lastFraction). FirstFraction and lastFraction
* will always be valid, but the old-style information is only valid if
- * the NEW_STYLE_COMMANDS flag is 0.
+ * the OLD_STYLE_COMMANDS flag is 1.
*/
+#ifndef TK_NO_DEPRECATED
int totalUnits; /* Total dimension of application, in units.
- * Valid only if the NEW_STYLE_COMMANDS flag
- * isn't set. */
+ * Valid only if the OLD_STYLE_COMMANDS flag
+ * is set. */
int windowUnits; /* Maximum number of units that can be
* displayed in the window at once. Valid only
- * if the NEW_STYLE_COMMANDS flag isn't set. */
+ * if the OLD_STYLE_COMMANDS flag is set. */
int firstUnit; /* Number of last unit visible in
* application's window. Valid only if the
- * NEW_STYLE_COMMANDS flag isn't set. */
+ * OLD_STYLE_COMMANDS flag is set. */
int lastUnit; /* Index of last unit visible in window.
- * Valid only if the NEW_STYLE_COMMANDS flag
+ * Valid only if the OLD_STYLE_COMMANDS flag
* isn't set. */
+#else
+ int dummy1,dummy2,dummy3,dummy4; /* sizeof(TkScrollbar) should not depend on TK_NO_DEPRECATED */
+#endif /* TK_NO_DEPRECATED */
double firstFraction; /* Position of first visible thing in window,
* specified as a fraction between 0 and
* 1.0. */
@@ -144,16 +148,18 @@ typedef struct TkScrollbar {
*
* REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
* already been queued to redraw this window.
- * NEW_STYLE_COMMANDS: Non-zero means the new style of commands
+ * OLD_STYLE_COMMANDS: Non-zero means the old style of commands
* should be used to communicate with the widget:
- * ".t yview scroll 2 lines", instead of
- * ".t yview 40", for example.
+ * ".t yview 40", instead of
+ * ".t yview scroll 2 lines", for example.
* GOT_FOCUS: Non-zero means this window has the input
* focus.
*/
#define REDRAW_PENDING 1
-#define NEW_STYLE_COMMANDS 2
+#ifndef TK_NO_DEPRECATED
+# define OLD_STYLE_COMMANDS 2
+#endif /* TK_NO_DEPRECATED */
#define GOT_FOCUS 4
/*
diff --git a/generic/tkSelect.c b/generic/tkSelect.c
index ab9018a..02268d3 100644
--- a/generic/tkSelect.c
+++ b/generic/tkSelect.c
@@ -26,7 +26,7 @@ typedef struct {
int charOffset; /* The offset of the next char to retrieve. */
int byteOffset; /* The expected byte offset of the next
* chunk. */
- char buffer[TCL_UTF_MAX]; /* A buffer to hold part of a UTF character
+ char buffer[4]; /* A buffer to hold part of a UTF character
* that is split across chunks. */
char command[1]; /* Command to invoke. Actual space is
* allocated as large as necessary. This must
@@ -190,8 +190,8 @@ Tk_CreateSelHandler(
* should make a copy for this selPtr.
*/
- unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) +
- ((CommandInfo *)clientData)->cmdLength + 1;
+ unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 +
+ ((CommandInfo *)clientData)->cmdLength;
selPtr->clientData = ckalloc(cmdInfoLen);
memcpy(selPtr->clientData, clientData, cmdInfoLen);
@@ -831,7 +831,7 @@ Tk_SelectionObjCmd(
const char *targetName = NULL;
const char *formatName = NULL;
register CommandInfo *cmdInfoPtr;
- int cmdLength;
+ size_t cmdLength;
static const char *const handleOptionStrings[] = {
"-format", "-selection", "-type", NULL
};
@@ -900,7 +900,7 @@ Tk_SelectionObjCmd(
} else {
format = XA_STRING;
}
- string = Tcl_GetStringFromObj(objs[1], &cmdLength);
+ string = TkGetStringFromObj(objs[1], &cmdLength);
if (cmdLength == 0) {
Tk_DeleteSelHandler(tkwin, selection, target);
} else {
@@ -1185,6 +1185,7 @@ TkSelInit(
dispPtr->applicationAtom = Tk_InternAtom(tkwin, "TK_APPLICATION");
dispPtr->windowAtom = Tk_InternAtom(tkwin, "TK_WINDOW");
dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD");
+ dispPtr->atomPairAtom = Tk_InternAtom(tkwin, "ATOM_PAIR");
/*
* Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to
diff --git a/generic/tkSquare.c b/generic/tkSquare.c
index 36d2d6e..2a64dbb 100644
--- a/generic/tkSquare.c
+++ b/generic/tkSquare.c
@@ -172,7 +172,7 @@ SquareObjCmd(
squarePtr->gc = None;
squarePtr->optionTable = optionTable;
- if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin)
+ if (Tk_InitOptions(interp, squarePtr, optionTable, tkwin)
!= TCL_OK) {
Tk_DestroyWindow(squarePtr->tkwin);
ckfree(squarePtr);
@@ -181,7 +181,7 @@ SquareObjCmd(
Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask,
SquareObjEventProc, squarePtr);
- if (Tk_SetOptions(interp, (char *) squarePtr, optionTable, objc - 2,
+ if (Tk_SetOptions(interp, squarePtr, optionTable, objc - 2,
objv + 2, tkwin, NULL, NULL) != TCL_OK) {
goto error;
}
@@ -250,7 +250,7 @@ SquareWidgetObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option");
goto error;
}
- resultObjPtr = Tk_GetOptionValue(interp, (char *) squarePtr,
+ resultObjPtr = Tk_GetOptionValue(interp, squarePtr,
squarePtr->optionTable, objv[2], squarePtr->tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
@@ -261,19 +261,19 @@ SquareWidgetObjCmd(
case SQUARE_CONFIGURE:
resultObjPtr = NULL;
if (objc == 2) {
- resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr,
+ resultObjPtr = Tk_GetOptionInfo(interp, squarePtr,
squarePtr->optionTable, NULL, squarePtr->tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
}
} else if (objc == 3) {
- resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr,
+ resultObjPtr = Tk_GetOptionInfo(interp, squarePtr,
squarePtr->optionTable, objv[2], squarePtr->tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
}
} else {
- result = Tk_SetOptions(interp, (char *) squarePtr,
+ result = Tk_SetOptions(interp, squarePtr,
squarePtr->optionTable, objc - 2, objv + 2,
squarePtr->tkwin, NULL, NULL);
if (result == TCL_OK) {
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index f08d7f4..731fa50 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -38,6 +38,43 @@ MODULE_SCOPE const TkStubs tkStubs;
*/
#undef Tk_MainEx
+#undef Tk_FreeXId
+#undef Tk_FreeStyleFromObj
+#undef Tk_GetStyleFromObj
+#undef TkWinGetPlatformId
+
+#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
+#define Tk_MainEx 0
+#define Tk_FreeXId 0
+#define Tk_FreeStyleFromObj 0
+#define Tk_GetStyleFromObj 0
+#define TkWinGetPlatformId 0
+#define Tk_PhotoPutBlock_NoComposite 0
+#define Tk_PhotoPutZoomedBlock_NoComposite 0
+#define Tk_PhotoExpand_Panic 0
+#define Tk_PhotoPutBlock_Panic 0
+#define Tk_PhotoPutZoomedBlock_Panic 0
+#define Tk_PhotoSetSize_Panic 0
+#else
+static void
+doNothing(void)
+{
+ /* dummy implementation, no need to do anything */
+}
+#define Tk_FreeXId ((void (*)(Display *, XID)) doNothing)
+#define Tk_FreeStyleFromObj ((void (*)(Tcl_Obj *)) doNothing)
+#define Tk_GetStyleFromObj getStyleFromObj
+static Tk_Style Tk_GetStyleFromObj(Tcl_Obj *obj)
+{
+ return Tk_AllocStyleFromObj(NULL, obj);
+}
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define TkWinGetPlatformId winGetPlatformId
+static int TkWinGetPlatformId(void) {
+ return 2;
+}
+#endif /* defined(_WIN32) || defined(__CYGWIN__) */
+#endif /* !TK_NO_DEPRECATED */
#ifdef _WIN32
@@ -62,6 +99,11 @@ TkCreateXEventSource(void)
# define TkUnixContainerId 0
# define TkUnixDoOneXEvent 0
# define TkUnixSetMenubar 0
+# define XCreateWindow 0
+# define XOffsetRegion 0
+# define XUnionRegion 0
+# define XPolygonRegion 0
+# define XPointInRegion 0
# define TkWmCleanup (void (*)(TkDisplay *)) TkpSync
# define TkSendCleanup (void (*)(TkDisplay *)) TkpSync
# define TkpTestsendCmd 0
@@ -200,7 +242,6 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
# define TkWinSetForegroundWindow 0
# define TkWinDialogDebug 0
# define TkWinGetMenuSystemDefault 0
-# define TkWinGetPlatformId 0
# define TkWinSetHINSTANCE 0
# define TkWinGetPlatformTheme 0
# define TkWinChildProc 0
@@ -233,6 +274,14 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
* below should be made in the generic/tk.decls script.
*/
+#ifdef __GNUC__
+/*
+ * The rest of this file shouldn't warn about deprecated functions; they're
+ * there because we intend them to be so and know that this file is OK to
+ * touch those fields.
+ */
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
/* !BEGIN!: Do not edit below this line. */
static const TkIntStubs tkIntStubs = {
@@ -450,6 +499,7 @@ static const TkIntStubs tkIntStubs = {
TkUnderlineAngledTextLayout, /* 182 */
TkIntersectAngledTextLayout, /* 183 */
TkDrawAngledChars, /* 184 */
+ TkDebugPhotoStringMatchDef, /* 185 */
};
static const TkIntPlatStubs tkIntPlatStubs = {
@@ -544,7 +594,7 @@ static const TkIntPlatStubs tkIntPlatStubs = {
TkMacOSXWindowOffset, /* 37 */
TkSetMacColor, /* 38 */
TkSetWMName, /* 39 */
- TkSuspendClipboard, /* 40 */
+ 0, /* 40 */
TkMacOSXZoomToplevel, /* 41 */
Tk_TopCoordsToWindow, /* 42 */
TkMacOSXContainerId, /* 43 */
@@ -698,6 +748,31 @@ static const TkIntXlibStubs tkIntXlibStubs = {
XSynchronize, /* 112 */
XSync, /* 113 */
XVisualIDFromVisual, /* 114 */
+ 0, /* 115 */
+ 0, /* 116 */
+ 0, /* 117 */
+ 0, /* 118 */
+ 0, /* 119 */
+ XOffsetRegion, /* 120 */
+ XUnionRegion, /* 121 */
+ XCreateWindow, /* 122 */
+ 0, /* 123 */
+ 0, /* 124 */
+ 0, /* 125 */
+ 0, /* 126 */
+ 0, /* 127 */
+ 0, /* 128 */
+ XLowerWindow, /* 129 */
+ XFillArcs, /* 130 */
+ XDrawArcs, /* 131 */
+ XDrawRectangles, /* 132 */
+ XDrawSegments, /* 133 */
+ XDrawPoint, /* 134 */
+ XDrawPoints, /* 135 */
+ XReparentWindow, /* 136 */
+ XPutImage, /* 137 */
+ XPolygonRegion, /* 138 */
+ XPointInRegion, /* 139 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
XSetDashes, /* 0 */
diff --git a/generic/tkStyle.c b/generic/tkStyle.c
index e7401df..508a2c4 100644
--- a/generic/tkStyle.c
+++ b/generic/tkStyle.c
@@ -155,7 +155,7 @@ static const Tcl_ObjType styleObjType = {
FreeStyleObjProc, /* freeIntRepProc */
DupStyleObjProc, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetStyleFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -1076,7 +1076,7 @@ Tk_GetElementSize(
Tk_Style style, /* The widget style. */
Tk_StyledElement element, /* The styled element, previously returned by
* Tk_GetStyledElement. */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_Window tkwin, /* The widget window. */
int width, int height, /* Requested size. */
int inner, /* If TRUE, compute the outer size according
@@ -1117,7 +1117,7 @@ Tk_GetElementBox(
Tk_Style style, /* The widget style. */
Tk_StyledElement element, /* The styled element, previously returned by
* Tk_GetStyledElement. */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_Window tkwin, /* The widget window. */
int x, int y, /* Top left corner of available area. */
int width, int height, /* Size of available area. */
@@ -1159,7 +1159,7 @@ Tk_GetElementBorderWidth(
Tk_Style style, /* The widget style. */
Tk_StyledElement element, /* The styled element, previously returned by
* Tk_GetStyledElement. */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_Window tkwin) /* The widget window. */
{
Style *stylePtr = (Style *) style;
@@ -1190,7 +1190,7 @@ Tk_DrawElement(
Tk_Style style, /* The widget style. */
Tk_StyledElement element, /* The styled element, previously returned by
* Tk_GetStyledElement. */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_Window tkwin, /* The widget window. */
Drawable d, /* Where to draw element. */
int x, int y, /* Top left corner of element. */
@@ -1405,62 +1405,15 @@ Tk_AllocStyleFromObj(
Tcl_Obj *objPtr) /* Object containing name of the style to
* retrieve. */
{
- Style *stylePtr;
-
- if (objPtr->typePtr != &styleObjType) {
- SetStyleFromAny(interp, objPtr);
- }
- stylePtr = objPtr->internalRep.twoPtrValue.ptr1;
-
- return (Tk_Style) stylePtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tk_GetStyleFromObj --
- *
- * Find the style that corresponds to a given object. The style must have
- * already been created by Tk_CreateStyle.
- *
- * Results:
- * The return value is a token for the style that matches objPtr, or NULL
- * if none found.
- *
- * Side effects:
- * If the object is not already a style ref, the conversion will free any
- * old internal representation.
- *
- *----------------------------------------------------------------------
- */
-
-Tk_Style
-Tk_GetStyleFromObj(
- Tcl_Obj *objPtr) /* The object from which to get the style. */
-{
if (objPtr->typePtr != &styleObjType) {
- SetStyleFromAny(NULL, objPtr);
+ if (SetStyleFromAny(interp, objPtr) != TCL_OK) {
+ return NULL;
+ }
}
-
return objPtr->internalRep.twoPtrValue.ptr1;
}
/*
- *---------------------------------------------------------------------------
- *
- * Tk_FreeStyleFromObj --
- *
- * No-op. Present only for stubs compatibility.
- *
- *---------------------------------------------------------------------------
- */
-void
-Tk_FreeStyleFromObj(
- Tcl_Obj *objPtr)
-{
-}
-
-/*
*----------------------------------------------------------------------
*
* SetStyleFromAny --
@@ -1469,8 +1422,8 @@ Tk_FreeStyleFromObj(
* internal form.
*
* Results:
- * Always returns TCL_OK. If an error occurs is returned (e.g. the style
- * doesn't exist), an error message will be left in interp's result.
+ * If an error occurs is returned (e.g. the style doesn't exist), an
+ * error message will be left in interp's result and TCL_ERROR is returned.
*
* Side effects:
* The object is left with its typePtr pointing to styleObjType.
@@ -1485,6 +1438,7 @@ SetStyleFromAny(
{
const Tcl_ObjType *typePtr;
const char *name;
+ Tk_Style style;
/*
* Free the old internalRep before setting the new one.
@@ -1496,8 +1450,12 @@ SetStyleFromAny(
typePtr->freeIntRepProc(objPtr);
}
+ style = Tk_GetStyle(interp, name);
+ if (style == NULL) {
+ return TCL_ERROR;
+ }
objPtr->typePtr = &styleObjType;
- objPtr->internalRep.twoPtrValue.ptr1 = Tk_GetStyle(interp, name);
+ objPtr->internalRep.twoPtrValue.ptr1 = style;
return TCL_OK;
}
diff --git a/generic/tkTest.c b/generic/tkTest.c
index fa9e073..0cf1f49 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -168,7 +168,7 @@ static int TestmenubarObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
#endif
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
static int TestmetricsObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
@@ -192,6 +192,9 @@ static void CustomOptionFree(ClientData clientData,
static int TestpropObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
+static int TestprintfObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int TestwrapperObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
@@ -203,6 +206,9 @@ static int TrivialConfigObjCmd(ClientData dummy,
Tcl_Obj * const objv[]);
static void TrivialEventProc(ClientData clientData,
XEvent *eventPtr);
+static int TestPhotoStringMatchCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
/*
*----------------------------------------------------------------------
@@ -227,7 +233,7 @@ Tktest_Init(
{
static int initialized = 0;
- if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
return TCL_ERROR;
}
if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
@@ -239,7 +245,7 @@ Tktest_Init(
*/
if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL);
@@ -263,20 +269,24 @@ Tktest_Init(
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
+ Tcl_CreateObjCommand(interp, "testprintf", TestprintfObjCmd, NULL, NULL);
Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
(ClientData) Tk_MainWindow(interp), NULL);
+ Tcl_CreateObjCommand(interp, "testphotostringmatch",
+ TestPhotoStringMatchCmd, (ClientData) Tk_MainWindow(interp),
+ NULL);
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#elif !defined(__CYGWIN__)
+#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#endif /* _WIN32 || MAC_OSX_TK */
+#endif /* _WIN32 */
/*
* Create test image type.
@@ -452,7 +462,7 @@ TestcursorObjCmd(
* A standard Tcl result.
*
* Side effects:
- * All the intepreters created by previous calls to "testnewapp" get
+ * All the interpreters created by previous calls to "testnewapp" get
* deleted.
*
*----------------------------------------------------------------------
@@ -665,7 +675,7 @@ TestobjconfigObjCmd(
recordPtr->mmPtr = NULL;
recordPtr->stringTablePtr = NULL;
recordPtr->customPtr = NULL;
- result = Tk_InitOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_InitOptions(interp, recordPtr, optionTable,
tkwin);
if (result == TCL_OK) {
recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
@@ -673,7 +683,7 @@ TestobjconfigObjCmd(
(ClientData) recordPtr, TrivialCmdDeletedProc);
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
TrivialEventProc, (ClientData) recordPtr);
- result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_SetOptions(interp, recordPtr, optionTable,
objc-3, objv+3, tkwin, NULL, NULL);
if (result != TCL_OK) {
Tk_DestroyWindow(tkwin);
@@ -708,12 +718,12 @@ TestobjconfigObjCmd(
recordPtr->header.tkwin = tkwin;
recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL;
recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL;
- result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin);
+ result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin);
if (result == TCL_OK) {
- result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_SetOptions(interp, recordPtr, optionTable,
objc-3, objv+3, tkwin, NULL, NULL);
if (result != TCL_OK) {
- Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin);
+ Tk_FreeConfigOptions(recordPtr, optionTable, tkwin);
}
}
if (result == TCL_OK) {
@@ -762,9 +772,9 @@ TestobjconfigObjCmd(
recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL;
recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL;
recordPtr->extension5ObjPtr = NULL;
- result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin);
+ result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin);
if (result == TCL_OK) {
- result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_SetOptions(interp, recordPtr, optionTable,
objc-3, objv+3, tkwin, NULL, NULL);
if (result != TCL_OK) {
Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin);
@@ -796,7 +806,7 @@ TestobjconfigObjCmd(
widgetRecord.intPtr = NULL;
optionTable = Tk_CreateOptionTable(interp, errorSpecs);
tables[index] = optionTable;
- return Tk_InitOptions(interp, (char *) &widgetRecord, optionTable,
+ return Tk_InitOptions(interp, &widgetRecord, optionTable,
(Tk_Window) NULL);
}
@@ -944,7 +954,7 @@ TestobjconfigObjCmd(
recordPtr->mm = 0.0;
recordPtr->tkwin = NULL;
recordPtr->custom = NULL;
- result = Tk_InitOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_InitOptions(interp, recordPtr, optionTable,
tkwin);
if (result == TCL_OK) {
recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp,
@@ -952,7 +962,7 @@ TestobjconfigObjCmd(
recordPtr, TrivialCmdDeletedProc);
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
TrivialEventProc, recordPtr);
- result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
+ result = Tk_SetOptions(interp, recordPtr, optionTable,
objc - 3, objv + 3, tkwin, NULL, NULL);
if (result != TCL_OK) {
Tk_DestroyWindow(tkwin);
@@ -1005,10 +1015,10 @@ TestobjconfigObjCmd(
recordPtr->one = recordPtr->two = recordPtr->three = NULL;
recordPtr->four = recordPtr->five = NULL;
Tcl_SetObjResult(interp, objv[2]);
- result = Tk_InitOptions(interp, (char *) recordPtr,
+ result = Tk_InitOptions(interp, recordPtr,
recordPtr->header.optionTable, (Tk_Window) NULL);
if (result == TCL_OK) {
- result = Tk_SetOptions(interp, (char *) recordPtr,
+ result = Tk_SetOptions(interp, recordPtr,
recordPtr->header.optionTable, objc - 3, objv + 3,
(Tk_Window) NULL, NULL, NULL);
if (result == TCL_OK) {
@@ -1016,7 +1026,7 @@ TestobjconfigObjCmd(
Tcl_GetString(objv[2]), TrivialConfigObjCmd,
(ClientData) recordPtr, TrivialCmdDeletedProc);
} else {
- Tk_FreeConfigOptions((char *) recordPtr,
+ Tk_FreeConfigOptions(recordPtr,
recordPtr->header.optionTable, (Tk_Window) NULL);
}
}
@@ -1045,8 +1055,8 @@ TestobjconfigObjCmd(
Tk_SetClass(tkwin, "Config");
optionTable = Tk_CreateOptionTable(interp, errorSpecs);
tables[index] = optionTable;
- Tk_InitOptions(interp, (char *) &record, optionTable, tkwin);
- if (Tk_SetOptions(interp, (char *) &record, optionTable, 1,
+ Tk_InitOptions(interp, &record, optionTable, tkwin);
+ if (Tk_SetOptions(interp, &record, optionTable, 1,
&newObjPtr, tkwin, NULL, NULL) != TCL_OK) {
result = TCL_ERROR;
}
@@ -1083,10 +1093,10 @@ TestobjconfigObjCmd(
recordPtr->header.tkwin = tkwin;
recordPtr->windowPtr = NULL;
- result = Tk_InitOptions(interp, (char *) recordPtr,
+ result = Tk_InitOptions(interp, recordPtr,
recordPtr->header.optionTable, tkwin);
if (result == TCL_OK) {
- result = Tk_SetOptions(interp, (char *) recordPtr,
+ result = Tk_SetOptions(interp, recordPtr,
recordPtr->header.optionTable, objc - 3, objv + 3,
tkwin, NULL, NULL);
if (result == TCL_OK) {
@@ -1097,7 +1107,7 @@ TestobjconfigObjCmd(
TrivialEventProc, recordPtr);
Tcl_SetObjResult(interp, objv[2]);
} else {
- Tk_FreeConfigOptions((char *) recordPtr,
+ Tk_FreeConfigOptions(recordPtr,
recordPtr->header.optionTable, tkwin);
}
}
@@ -1168,7 +1178,7 @@ TrivialConfigObjCmd(
result = TCL_ERROR;
goto done;
}
- resultObjPtr = Tk_GetOptionValue(interp, (char *) clientData,
+ resultObjPtr = Tk_GetOptionValue(interp, clientData,
headerPtr->optionTable, objv[2], tkwin);
if (resultObjPtr != NULL) {
Tcl_SetObjResult(interp, resultObjPtr);
@@ -1179,7 +1189,7 @@ TrivialConfigObjCmd(
break;
case CONFIGURE:
if (objc == 2) {
- resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData,
+ resultObjPtr = Tk_GetOptionInfo(interp, clientData,
headerPtr->optionTable, NULL, tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
@@ -1187,7 +1197,7 @@ TrivialConfigObjCmd(
Tcl_SetObjResult(interp, resultObjPtr);
}
} else if (objc == 3) {
- resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData,
+ resultObjPtr = Tk_GetOptionInfo(interp, clientData,
headerPtr->optionTable, objv[2], tkwin);
if (resultObjPtr == NULL) {
result = TCL_ERROR;
@@ -1195,7 +1205,7 @@ TrivialConfigObjCmd(
Tcl_SetObjResult(interp, resultObjPtr);
}
} else {
- result = Tk_SetOptions(interp, (char *) clientData,
+ result = Tk_SetOptions(interp, clientData,
headerPtr->optionTable, objc - 2, objv + 2,
tkwin, NULL, &mask);
if (result == TCL_OK) {
@@ -1204,7 +1214,7 @@ TrivialConfigObjCmd(
}
break;
case CSAVE:
- result = Tk_SetOptions(interp, (char *) clientData,
+ result = Tk_SetOptions(interp, clientData,
headerPtr->optionTable, objc - 2, objv + 2,
tkwin, &saved, &mask);
Tk_FreeSavedOptions(&saved);
@@ -1550,9 +1560,8 @@ ImageDisplay(
TImageInstance *instPtr = (TImageInstance *) clientData;
char buffer[200 + TCL_INTEGER_SPACE * 6];
- sprintf(buffer, "%s display %d %d %d %d %d %d",
- instPtr->masterPtr->imageName, imageX, imageY, width, height,
- drawableX, drawableY);
+ sprintf(buffer, "%s display %d %d %d %d",
+ instPtr->masterPtr->imageName, imageX, imageY, width, height);
Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
if (width > (instPtr->masterPtr->width - imageX)) {
@@ -1765,7 +1774,7 @@ TestmenubarObjCmd(
*----------------------------------------------------------------------
*/
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
static int
TestmetricsObjCmd(
ClientData clientData, /* Main window for application. */
@@ -1776,38 +1785,15 @@ TestmetricsObjCmd(
char buf[TCL_INTEGER_SPACE];
int val;
-#ifdef _WIN32
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
-#else
- Tk_Window tkwin = (Tk_Window) clientData;
- TkWindow *winPtr;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "option window");
- return TCL_ERROR;
- }
-
- winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (winPtr == NULL) {
- return TCL_ERROR;
- }
-#endif
if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {
-#ifdef _WIN32
val = GetSystemMetrics(SM_CYVSCROLL);
-#else
- val = ((TkScrollbar *) winPtr->instanceData)->width;
-#endif
} else if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {
-#ifdef _WIN32
val = GetSystemMetrics(SM_CXHSCROLL);
-#else
- val = ((TkScrollbar *) winPtr->instanceData)->width;
-#endif
} else {
Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be cxhscroll or cyvscroll", NULL);
@@ -1896,6 +1882,60 @@ TestpropObjCmd(
return TCL_OK;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestpropObjCmd --
+ *
+ * This function implements the "testprop" command. It fetches and prints
+ * the value of a property on a window.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+TestprintfObjCmd(
+ ClientData clientData, /* Not used */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
+{
+ char buffer[256];
+ Tcl_WideInt wideInt;
+#ifdef _WIN32
+ __int64 longLongInt;
+#else
+ long long longLongInt;
+#endif
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "wideint");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &wideInt) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ longLongInt = wideInt;
+
+ /* Just add a lot of arguments to sprintf. Reason: on AMD64, the first
+ * 4 or 6 arguments (we assume 8, just in case) might be put in registers,
+ * which still woudn't tell if the assumed size is correct: We want this
+ * test-case to fail if the 64-bit value is printed as truncated to 32-bit.
+ */
+ sprintf(buffer, "%s%s%s%s%s%s%s%s%" TCL_LL_MODIFIER "d %"
+ TCL_LL_MODIFIER "u", "", "", "", "", "", "", "", "",
+ (Tcl_WideInt)longLongInt, (Tcl_WideUInt)longLongInt);
+ Tcl_AppendResult(interp, buffer, NULL);
+ return TCL_OK;
+}
+
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
*----------------------------------------------------------------------
@@ -1990,7 +2030,7 @@ CustomOptionSet(
objEmpty = 0;
- if (internalOffset >= 0) {
+ if (internalOffset != -1) {
internalPtr = recordPtr + internalOffset;
} else {
internalPtr = NULL;
@@ -2066,6 +2106,54 @@ CustomOptionFree(
ckfree(*(char **)internalPtr);
}
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestPhotoStringMatchCmd --
+ *
+ * This function implements the "testphotostringmatch" command. It
+ * provides a way from Tcl to call the string match function for the
+ * default image handler directly.
+ *
+ * Results:
+ * A standard Tcl result. If data is in the proper format, the result in
+ * interp will contain width and height as a list. If the data cannot be
+ * parsed as default image format, returns TCL_ERROR and leaves an
+ * appropriate error message in interp.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ /* ARGSUSED */
+static int
+TestPhotoStringMatchCmd(
+ ClientData clientData, /* Main window for application. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
+{
+ Tcl_Obj *dummy = NULL;
+ Tcl_Obj *resultObj[2];
+ int width, height;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "imageData");
+ return TCL_ERROR;
+ }
+ if (TkDebugPhotoStringMatchDef(interp, objv[1], dummy, &width, &height)) {
+ resultObj[0] = Tcl_NewIntObj(width);
+ resultObj[1] = Tcl_NewIntObj(height);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObj));
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
+ }
+}
+
+
/*
* Local Variables:
diff --git a/generic/tkText.c b/generic/tkText.c
index 3079417..a08878c 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -14,9 +14,9 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
#include "tkUndo.h"
+#include "default.h"
#if defined(MAC_OSX_TK)
#define Style TkStyle
@@ -122,7 +122,8 @@ static const Tk_ObjCustomOption lineOption = {
static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators",
"AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1,
- Tk_Offset(TkText, autoSeparators), 0, 0, 0},
+ Tk_Offset(TkText, autoSeparators),
+ TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border),
0, DEF_TEXT_BG_MONO, 0},
@@ -193,7 +194,8 @@ static const Tk_OptionSpec optionSpecs[] = {
DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth),
0, 0, 0},
{TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo",
- DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0},
+ DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo),
+ TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0,
TK_TEXT_LINE_GEOMETRY},
@@ -239,7 +241,8 @@ static const Tk_OptionSpec optionSpecs[] = {
DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_BOOLEAN, "-undo", "undo", "Undo",
- DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0},
+ DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo),
+ TK_OPTION_DONT_SET_DEFAULT, 0 , 0},
{TK_OPTION_INT, "-width", "width", "Width",
DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0,
TK_TEXT_LINE_GEOMETRY},
@@ -401,6 +404,7 @@ static Tcl_Obj * TextGetText(const TkText *textPtr,
const TkTextIndex *index1,
const TkTextIndex *index2, int visibleOnly);
static void GenerateModifiedEvent(TkText *textPtr);
+static void GenerateUndoStackEvent(TkText *textPtr);
static void UpdateDirtyFlag(TkSharedText *sharedPtr);
static void RunAfterSyncCmd(ClientData clientData);
static void TextPushUndoAction(TkText *textPtr,
@@ -543,7 +547,7 @@ CreateWidget(
Tcl_InitHashTable(&sharedPtr->windowTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&sharedPtr->imageTable, TCL_STRING_KEYS);
sharedPtr->undoStack = TkUndoInitStack(interp,0);
- sharedPtr->undo = 1;
+ sharedPtr->undo = 0;
sharedPtr->isDirty = 0;
sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
sharedPtr->autoSeparators = 1;
@@ -657,7 +661,7 @@ CreateWidget(
Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING,
TextFetchSelection, textPtr, XA_STRING);
- if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin)
+ if (Tk_InitOptions(interp, textPtr, optionTable, textPtr->tkwin)
!= TCL_OK) {
Tk_DestroyWindow(textPtr->tkwin);
return TCL_ERROR;
@@ -760,7 +764,7 @@ TextWidgetObjCmd(
result = TCL_ERROR;
goto done;
} else {
- Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr,
+ Tcl_Obj *objPtr = Tk_GetOptionValue(interp, textPtr,
textPtr->optionTable, objv[2], textPtr->tkwin);
if (objPtr == NULL) {
@@ -823,7 +827,7 @@ TextWidgetObjCmd(
}
case TEXT_CONFIGURE:
if (objc <= 3) {
- Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr,
+ Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, textPtr,
textPtr->optionTable, ((objc == 3) ? objv[2] : NULL),
textPtr->tkwin);
@@ -860,28 +864,28 @@ TextWidgetObjCmd(
}
for (i = 2; i < objc-2; i++) {
- int value, length;
- const char *option = Tcl_GetString(objv[i]);
+ int value;
+ size_t length;
+ const char *option = TkGetStringFromObj(objv[i], &length);
char c;
- length = objv[i]->length;
if (length < 2 || option[0] != '-') {
goto badOption;
}
c = option[1];
- if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) {
+ if (c == 'c' && !strncmp("-chars", option, length)) {
value = CountIndices(textPtr, indexFromPtr, indexToPtr,
COUNT_CHARS);
} else if (c == 'd' && (length > 8)
- && !strncmp("-displaychars", option, (unsigned) length)) {
+ && !strncmp("-displaychars", option, length)) {
value = CountIndices(textPtr, indexFromPtr, indexToPtr,
COUNT_DISPLAY_CHARS);
} else if (c == 'd' && (length > 8)
- && !strncmp("-displayindices", option,(unsigned)length)) {
+ && !strncmp("-displayindices", option,length)) {
value = CountIndices(textPtr, indexFromPtr, indexToPtr,
COUNT_DISPLAY_INDICES);
} else if (c == 'd' && (length > 8)
- && !strncmp("-displaylines", option, (unsigned) length)) {
+ && !strncmp("-displaylines", option, length)) {
TkTextLine *fromPtr, *lastPtr;
TkTextIndex index, index2;
@@ -919,43 +923,43 @@ TextWidgetObjCmd(
* We're going to count up all display lines in the logical
* line of 'indexFromPtr' up to, but not including the logical
* line of 'indexToPtr' (except if this line is elided), and
- * then subtract off what came in too much from elided lines,
- * also subtract off what we didn't want from 'from' and add
+ * then subtract off what came in too much from elided lines,
+ * also subtract off what we didn't want from 'from' and add
* on what we didn't count from 'to'.
*/
- while (TkTextIndexCmp(&index,indexToPtr) < 0) {
+ while (TkTextIndexCmp(&index,indexToPtr) < 0) {
value += TkTextUpdateOneLine(textPtr, index.linePtr,
- 0, &index, 0);
+ 0, &index, 0);
}
- index2 = index;
-
- /*
- * Now we need to adjust the count to:
- * - subtract off the number of display lines between
- * indexToPtr and index2, since we might have skipped past
- * indexToPtr, if we have several logical lines in a
- * single display line
- * - subtract off the number of display lines overcounted
- * in the first logical line
- * - add on the number of display lines in the last logical
- * line
- * This logic is still ok if both indexFromPtr and indexToPtr
- * are in the same logical line.
- */
-
- index = *indexToPtr;
- index.byteIndex = 0;
- while (TkTextIndexCmp(&index,&index2) < 0) {
- value -= TkTextUpdateOneLine(textPtr, index.linePtr,
- 0, &index, 0);
- }
+ index2 = index;
+
+ /*
+ * Now we need to adjust the count to:
+ * - subtract off the number of display lines between
+ * indexToPtr and index2, since we might have skipped past
+ * indexToPtr, if we have several logical lines in a
+ * single display line
+ * - subtract off the number of display lines overcounted
+ * in the first logical line
+ * - add on the number of display lines in the last logical
+ * line
+ * This logic is still ok if both indexFromPtr and indexToPtr
+ * are in the same logical line.
+ */
+
+ index = *indexToPtr;
+ index.byteIndex = 0;
+ while (TkTextIndexCmp(&index,&index2) < 0) {
+ value -= TkTextUpdateOneLine(textPtr, index.linePtr,
+ 0, &index, 0);
+ }
index.linePtr = indexFromPtr->linePtr;
index.byteIndex = 0;
while (1) {
TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
- if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
+ if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -967,7 +971,7 @@ TextWidgetObjCmd(
index.byteIndex = 0;
while (1) {
TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
- if (TkTextIndexCmp(&index,indexToPtr) >= 0) {
+ if (TkTextIndexCmp(&index,indexToPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -979,19 +983,19 @@ TextWidgetObjCmd(
value = -value;
}
} else if (c == 'i'
- && !strncmp("-indices", option, (unsigned) length)) {
+ && !strncmp("-indices", option, length)) {
value = CountIndices(textPtr, indexFromPtr, indexToPtr,
COUNT_INDICES);
} else if (c == 'l'
- && !strncmp("-lines", option, (unsigned) length)) {
+ && !strncmp("-lines", option, length)) {
value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr)
- TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
} else if (c == 'u'
- && !strncmp("-update", option, (unsigned) length)) {
+ && !strncmp("-update", option, length)) {
update = 1;
continue;
} else if (c == 'x'
- && !strncmp("-xpixels", option, (unsigned) length)) {
+ && !strncmp("-xpixels", option, length)) {
int x1, x2;
TkTextIndex index;
@@ -1001,7 +1005,7 @@ TextWidgetObjCmd(
TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2);
value = x2 - x1;
} else if (c == 'y'
- && !strncmp("-ypixels", option, (unsigned) length)) {
+ && !strncmp("-ypixels", option, length)) {
if (update) {
TkTextUpdateLineMetrics(textPtr,
TkBTreeLinesTo(textPtr, indexFromPtr->linePtr),
@@ -1151,14 +1155,14 @@ TextWidgetObjCmd(
objc++;
}
useIdx = ckalloc(objc);
- memset(useIdx, 0, (unsigned) objc);
+ memset(useIdx, 0, objc);
/*
* Do a decreasing order sort so that we delete the end ranges
* first to maintain index consistency.
*/
- qsort(indices, (unsigned) objc / 2,
+ qsort(indices, objc / 2,
2 * sizeof(TkTextIndex), TextIndexSortProc);
lastStart = NULL;
@@ -1256,7 +1260,7 @@ TextWidgetObjCmd(
Tcl_Obj *objPtr = NULL;
int i, found = 0, visible = 0;
const char *name;
- int length;
+ size_t length;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -1272,14 +1276,12 @@ TextWidgetObjCmd(
i = 2;
if (objc > 3) {
- name = Tcl_GetString(objv[i]);
- length = objv[i]->length;
+ name = TkGetStringFromObj(objv[i], &length);
if (length > 1 && name[0] == '-') {
- if (strncmp("-displaychars", name, (unsigned) length) == 0) {
+ if (strncmp("-displaychars", name, length) == 0) {
i++;
visible = 1;
- name = Tcl_GetString(objv[i]);
- length = objv[i]->length;
+ name = TkGetStringFromObj(objv[i], &length);
}
if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
i++;
@@ -1395,14 +1397,14 @@ TextWidgetObjCmd(
result = TextPeerCmd(textPtr, interp, objc, objv);
break;
case TEXT_PENDINGSYNC: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- result = TCL_ERROR;
- goto done;
- }
- Tcl_SetObjResult(interp,
- Tcl_NewBooleanObj(TkTextPendingsync(textPtr)));
- break;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(TkTextPendingsync(textPtr)));
+ break;
}
case TEXT_REPLACE: {
const TkTextIndex *indexFromPtr, *indexToPtr;
@@ -1461,7 +1463,7 @@ TextWidgetObjCmd(
* unnecessarily.
*/
- int deleteInsertOffset, insertLength, j;
+ int deleteInsertOffset, insertLength, j, indexFromLine, indexFromByteOffset;
insertLength = 0;
for (j = 4; j < objc; j += 2) {
@@ -1479,6 +1481,9 @@ TextWidgetObjCmd(
deleteInsertOffset = insertLength;
}
+ indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
+ indexFromByteOffset = indexFromPtr->byteIndex;
+
result = TextReplaceCmd(textPtr, interp, indexFromPtr,
indexToPtr, objc, objv, 0);
@@ -1487,7 +1492,11 @@ TextWidgetObjCmd(
* Move the insertion position to the correct place.
*/
- TkTextIndexForwChars(NULL, indexFromPtr,
+ TkTextIndex indexTmp;
+
+ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine,
+ indexFromByteOffset, &indexTmp);
+ TkTextIndexForwChars(NULL, &indexTmp,
deleteInsertOffset, &index, COUNT_INDICES);
TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
textPtr->insertMarkPtr->body.mark.linePtr);
@@ -1535,7 +1544,7 @@ TextWidgetObjCmd(
textPtr->afterSyncCmd = cmd;
} else {
textPtr->afterSyncCmd = cmd;
- Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr);
+ Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr);
}
break;
} else if (objc != 2) {
@@ -1566,8 +1575,7 @@ TextWidgetObjCmd(
}
done:
- textPtr->refCount--;
- if (textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
return result;
@@ -1960,9 +1968,7 @@ DestroyText(
* portion of the text widget.
*/
- sharedTextPtr->refCount--;
-
- if (sharedTextPtr->refCount > 0) {
+ if (sharedTextPtr->refCount-- > 1) {
TkBTreeRemoveClient(sharedTextPtr->tree, textPtr);
/*
@@ -2038,13 +2044,12 @@ DestroyText(
}
textPtr->tkwin = NULL;
- textPtr->refCount--;
Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);
if (textPtr->afterSyncCmd){
Tcl_DecrRefCount(textPtr->afterSyncCmd);
textPtr->afterSyncCmd = NULL;
}
- if (textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
}
@@ -2077,7 +2082,7 @@ ConfigureText(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_SavedOptions savedOptions;
- int oldExport = textPtr->exportSelection;
+ int oldExport = (textPtr->exportSelection) && (!Tcl_IsSafe(textPtr->interp));
int mask = 0;
if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable,
@@ -2093,7 +2098,7 @@ ConfigureText(
textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo;
textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators;
- TkUndoSetDepth(textPtr->sharedTextPtr->undoStack,
+ TkUndoSetMaxDepth(textPtr->sharedTextPtr->undoStack,
textPtr->sharedTextPtr->maxUndo);
/*
@@ -2191,10 +2196,10 @@ ConfigureText(
* Also, clamp the insert and current (unshared) marks to the new
* -startline/-endline range limits of the widget. All other (shared)
* marks are unchanged.
- * The return value of TkTextMarkNameToIndex does not need to be
- * checked: "insert" and "current" marks always exist, and the
- * purpose of the code below precisely is to move them inside the
- * -startline/-endline range.
+ * The return value of TkTextMarkNameToIndex does not need to be
+ * checked: "insert" and "current" marks always exist, and the
+ * purpose of the code below precisely is to move them inside the
+ * -startline/-endline range.
*/
textPtr->sharedTextPtr->stateEpoch++;
@@ -2253,12 +2258,20 @@ ConfigureText(
* replaced in the widget record.
*/
- textPtr->selTagPtr->border = textPtr->selBorder;
+ if (textPtr->selTagPtr->selBorder == NULL) {
+ textPtr->selTagPtr->border = textPtr->selBorder;
+ } else {
+ textPtr->selTagPtr->selBorder = textPtr->selBorder;
+ }
if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) {
textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr;
textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth;
}
- textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
+ if (textPtr->selTagPtr->selFgColor == NULL) {
+ textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
+ } else {
+ textPtr->selTagPtr->selFgColor = textPtr->selFgColorPtr;
+ }
textPtr->selTagPtr->affectsDisplay = 0;
textPtr->selTagPtr->affectsDisplayGeometry = 0;
if ((textPtr->selTagPtr->elideString != NULL)
@@ -2277,12 +2290,18 @@ ConfigureText(
textPtr->selTagPtr->affectsDisplayGeometry = 1;
}
if ((textPtr->selTagPtr->border != NULL)
+ || (textPtr->selTagPtr->selBorder != NULL)
|| (textPtr->selTagPtr->reliefString != NULL)
|| (textPtr->selTagPtr->bgStipple != None)
|| (textPtr->selTagPtr->fgColor != NULL)
+ || (textPtr->selTagPtr->selFgColor != NULL)
|| (textPtr->selTagPtr->fgStipple != None)
|| (textPtr->selTagPtr->overstrikeString != NULL)
- || (textPtr->selTagPtr->underlineString != NULL)) {
+ || (textPtr->selTagPtr->overstrikeColor != NULL)
+ || (textPtr->selTagPtr->underlineString != NULL)
+ || (textPtr->selTagPtr->underlineColor != NULL)
+ || (textPtr->selTagPtr->lMarginColor != NULL)
+ || (textPtr->selTagPtr->rMarginColor != NULL)) {
textPtr->selTagPtr->affectsDisplay = 1;
}
TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1);
@@ -2292,7 +2311,7 @@ ConfigureText(
* are tagged characters.
*/
- if (textPtr->exportSelection && (!oldExport)) {
+ if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) {
TkTextSearch search;
TkTextIndex first, last;
@@ -2406,7 +2425,7 @@ TextWorldChanged(
textPtr->charHeight = 1;
}
if (textPtr->charHeight != oldCharHeight) {
- TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
+ TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
}
border = textPtr->borderWidth + textPtr->highlightWidth;
Tk_GeometryRequest(textPtr->tkwin,
@@ -2612,14 +2631,14 @@ InsertChars(
* information to add to text. */
int viewUpdate) /* Update the view if set. */
{
- int lineIndex, length;
+ int lineIndex;
+ size_t length;
TkText *tPtr;
int *lineAndByteIndex;
int resetViewCount;
int pixels[2*PIXEL_CLIENTS];
- const char *string = Tcl_GetString(stringPtr);
+ const char *string = TkGetStringFromObj(stringPtr, &length);
- length = stringPtr->length;
if (sharedTextPtr == NULL) {
sharedTextPtr = textPtr->sharedTextPtr;
}
@@ -2711,10 +2730,14 @@ InsertChars(
}
/*
- * Invalidate any selection retrievals in progress.
+ * Invalidate any selection retrievals in progress, and send an event
+ * that the selection changed if that is the case.
*/
for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
+ if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) {
+ TkTextSelectionEvent(tPtr);
+ }
tPtr->abortSelections = 1;
}
@@ -2755,6 +2778,10 @@ TextPushUndoAction(
/* Index describing second location. */
{
TkUndoSubAtom *iAtom, *dAtom;
+ int canUndo, canRedo;
+ char lMarkName[20] = "tk::undoMarkL";
+ char rMarkName[20] = "tk::undoMarkR";
+ char stringUndoMarkId[7] = "";
/*
* Create the helpers.
@@ -2765,6 +2792,10 @@ TextPushUndoAction(
Tcl_Obj *markSet2InsertObj = NULL;
Tcl_Obj *insertCmdObj = Tcl_NewObj();
Tcl_Obj *deleteCmdObj = Tcl_NewObj();
+ Tcl_Obj *markSetLUndoMarkCmdObj = Tcl_NewObj();
+ Tcl_Obj *markSetRUndoMarkCmdObj = NULL;
+ Tcl_Obj *markGravityLUndoMarkCmdObj = Tcl_NewObj();
+ Tcl_Obj *markGravityRUndoMarkCmdObj = NULL;
/*
* Get the index positions.
@@ -2814,6 +2845,40 @@ TextPushUndoAction(
Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj);
Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj);
+ Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
+ Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
+ Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
+ Tcl_NewStringObj("mark", 4));
+ Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
+ Tcl_NewStringObj("set", 3));
+ markSetRUndoMarkCmdObj = Tcl_DuplicateObj(markSetLUndoMarkCmdObj);
+ textPtr->sharedTextPtr->undoMarkId++;
+ sprintf(stringUndoMarkId, "%d", textPtr->sharedTextPtr->undoMarkId);
+ strcat(lMarkName, stringUndoMarkId);
+ strcat(rMarkName, stringUndoMarkId);
+ Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj,
+ Tcl_NewStringObj(lMarkName, -1));
+ Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj,
+ Tcl_NewStringObj(rMarkName, -1));
+ Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, index1Obj);
+ Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, index2Obj);
+
+ Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
+ Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1));
+ Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
+ Tcl_NewStringObj("mark", 4));
+ Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
+ Tcl_NewStringObj("gravity", 7));
+ markGravityRUndoMarkCmdObj = Tcl_DuplicateObj(markGravityLUndoMarkCmdObj);
+ Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
+ Tcl_NewStringObj(lMarkName, -1));
+ Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj,
+ Tcl_NewStringObj(rMarkName, -1));
+ Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj,
+ Tcl_NewStringObj("left", 4));
+ Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj,
+ Tcl_NewStringObj("right", 5));
+
/*
* Note: we don't wish to use textPtr->widgetCmd in these callbacks
* because if we delete the textPtr, but peers still exist, we will then
@@ -2831,16 +2896,27 @@ TextPushUndoAction(
insertCmdObj, NULL);
TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom);
TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom);
+ TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, iAtom);
+ TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, iAtom);
+ TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, iAtom);
+ TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, iAtom);
dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr,
deleteCmdObj, NULL);
TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom);
TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom);
+ TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, dAtom);
+ TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, dAtom);
+ TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, dAtom);
+ TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, dAtom);
Tcl_DecrRefCount(seeInsertObj);
Tcl_DecrRefCount(index1Obj);
Tcl_DecrRefCount(index2Obj);
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+
/*
* Depending whether the action is to insert or delete, we provide the
* appropriate second and third arguments to TkUndoPushAction. (The first
@@ -2852,6 +2928,10 @@ TextPushUndoAction(
} else {
TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
}
+
+ if (!canUndo || canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
}
/*
@@ -3016,7 +3096,7 @@ CountIndices(
* If 'viewUpdate' is true, we may adjust the window contents'
* y-position, and scrollbar setting.
*
- * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex
+ * If 'viewUpdate' is true we can guarantee that textPtr->topIndex
* points to a valid TkTextLine after this function returns. However, if
* 'viewUpdate' is false, then there is no such guarantee (since
* topIndex.linePtr can be garbage). The caller is expected to take
@@ -3046,6 +3126,9 @@ DeleteIndexRange(
int *lineAndByteIndex;
int resetViewCount;
int pixels[2*PIXEL_CLIENTS];
+ Tcl_HashSearch search;
+ Tcl_HashEntry *hPtr;
+ int i;
if (sharedTextPtr == NULL) {
sharedTextPtr = textPtr->sharedTextPtr;
@@ -3075,11 +3158,16 @@ DeleteIndexRange(
* The code below is ugly, but it's needed to make sure there is always a
* dummy empty line at the end of the text. If the final newline of the
* file (just before the dummy line) is being deleted, then back up index
- * to just before the newline. Furthermore, remove any tags that are
- * present on the newline that isn't going to be deleted after all (this
- * simulates deleting the newline and then adding a "clean" one back
- * again). Note that index1 and index2 might now be equal again which
- * means that no text will be deleted but tags might be removed.
+ * to just before the newline. If there is a newline just before the first
+ * character being deleted, then back up the first index too. The idea is
+ * that a deletion involving a range starting at a line start and
+ * including the final \n (i.e. index2 is "end") is an attempt to delete
+ * complete lines, so the \n before the deleted block shall become the new
+ * final \n. Furthermore, remove any tags that are present on the newline
+ * that isn't going to be deleted after all (this simulates deleting the
+ * newline and then adding a "clean" one back again). Note that index1 and
+ * index2 might now be equal again which means that no text will be
+ * deleted but tags might be removed.
*/
line1 = TkBTreeLinesTo(textPtr, index1.linePtr);
@@ -3092,6 +3180,10 @@ DeleteIndexRange(
oldIndex2 = index2;
TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES);
line2--;
+ if ((index1.byteIndex == 0) && (line1 != 0)) {
+ TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES);
+ line1--;
+ }
arrayPtr = TkBTreeGetTags(&index2, NULL, &arraySize);
if (arrayPtr != NULL) {
for (i = 0; i < arraySize; i++) {
@@ -3101,42 +3193,36 @@ DeleteIndexRange(
}
}
- if (line1 < line2) {
- /*
- * We are deleting more than one line. For speed, we remove all tags
- * from the range first. If we don't do this, the code below can (when
- * there are many tags) grow non-linearly in execution time.
- */
-
- Tcl_HashSearch search;
- Tcl_HashEntry *hPtr;
- int i;
+ /*
+ * For speed, we remove all tags from the range first. If we don't
+ * do this, the code below can (when there are many tags) grow
+ * non-linearly in execution time.
+ */
- for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
- hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
- TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);
+ for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
+ hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
+ TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);
- TkBTreeTag(&index1, &index2, tagPtr, 0);
- }
+ TkBTreeTag(&index1, &index2, tagPtr, 0);
+ }
- /*
- * Special case for the sel tag which is not in the hash table. We
- * need to do this once for each peer text widget.
- */
+ /*
+ * Special case for the sel tag which is not in the hash table. We
+ * need to do this once for each peer text widget.
+ */
- for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
- tPtr = tPtr->next) {
- if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
- /*
- * Send an event that the selection changed. This is
- * equivalent to:
- * event generate $textWidget <<Selection>>
- */
+ for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
+ tPtr = tPtr->next) {
+ if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
+ /*
+ * Send an event that the selection changed. This is
+ * equivalent to:
+ * event generate $textWidget <<Selection>>
+ */
- TkTextSelectionEvent(textPtr);
- tPtr->abortSelections = 1;
- }
- }
+ TkTextSelectionEvent(textPtr);
+ tPtr->abortSelections = 1;
+ }
}
/*
@@ -3179,11 +3265,11 @@ DeleteIndexRange(
resetView = 1;
line = line1;
byteIndex = tPtr->topIndex.byteIndex;
- } else {
- /*
- * Deletion range starts after the top line. This peers's view
- * will not need to be reset. Nothing to do.
- */
+ } else {
+ /*
+ * Deletion range starts after the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
}
} else if (index2.linePtr == tPtr->topIndex.linePtr) {
/*
@@ -3200,11 +3286,11 @@ DeleteIndexRange(
} else {
byteIndex -= (index2.byteIndex - index1.byteIndex);
}
- } else {
- /*
- * Deletion range ends before the top line. This peers's view
- * will not need to be reset. Nothing to do.
- */
+ } else {
+ /*
+ * Deletion range ends before the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
}
if (resetView) {
lineAndByteIndex[resetViewCount] = line;
@@ -3249,43 +3335,43 @@ DeleteIndexRange(
TkTextIndex indexTmp;
if (tPtr == textPtr) {
- if (viewUpdate) {
- /*
- * line cannot be before -startline of textPtr because
- * this line corresponds to an index which is necessarily
- * between "1.0" and "end" relative to textPtr.
- * Therefore no need to clamp line to the -start/-end
- * range.
- */
+ if (viewUpdate) {
+ /*
+ * line cannot be before -startline of textPtr because
+ * this line corresponds to an index which is necessarily
+ * between "1.0" and "end" relative to textPtr.
+ * Therefore no need to clamp line to the -start/-end
+ * range.
+ */
TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line,
byteIndex, &indexTmp);
TkTextSetYView(tPtr, &indexTmp, 0);
}
} else {
- TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
+ TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
byteIndex, &indexTmp);
- /*
- * line may be before -startline of tPtr and must be
- * clamped to -startline before providing it to
- * TkTextSetYView otherwise lines before -startline
- * would be displayed.
- * There is no need to worry about -endline however,
- * because the view will only be reset if the deletion
- * involves the TOP line of the screen
- */
-
- if (tPtr->start != NULL) {
- int start;
- TkTextIndex indexStart;
-
- start = TkBTreeLinesTo(NULL, tPtr->start);
- TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start,
+ /*
+ * line may be before -startline of tPtr and must be
+ * clamped to -startline before providing it to
+ * TkTextSetYView otherwise lines before -startline
+ * would be displayed.
+ * There is no need to worry about -endline however,
+ * because the view will only be reset if the deletion
+ * involves the TOP line of the screen
+ */
+
+ if (tPtr->start != NULL) {
+ int start;
+ TkTextIndex indexStart;
+
+ start = TkBTreeLinesTo(NULL, tPtr->start);
+ TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start,
0, &indexStart);
- if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) {
- indexTmp = indexStart;
- }
- }
+ if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) {
+ indexTmp = indexStart;
+ }
+ }
TkTextSetYView(tPtr, &indexTmp, 0);
}
}
@@ -3346,7 +3432,7 @@ TextFetchSelection(
TkTextSearch search;
TkTextSegment *segPtr;
- if (!textPtr->exportSelection) {
+ if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
return -1;
}
@@ -3476,7 +3562,7 @@ TkTextLostSelection(
if (TkpAlwaysShowSelection(textPtr->tkwin)) {
TkTextIndex start, end;
- if (!textPtr->exportSelection) {
+ if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
return;
}
@@ -3531,16 +3617,7 @@ TkTextSelectionEvent(
* event generate $textWidget <<Selection>>
*/
- union {XEvent general; XVirtualEvent virtual;} event;
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(textPtr->tkwin);
- event.general.xany.display = Tk_Display(textPtr->tkwin);
- event.virtual.name = Tk_GetUid("Selection");
- Tk_HandleEvent(&event.general);
+ TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL);
}
/*
@@ -3732,10 +3809,10 @@ TextSearchCmd(
"-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL
};
enum SearchSwitches {
- SEARCH_HIDDEN,
- SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE,
- SEARCH_EXACT, SEARCH_FWD, SEARCH_NOCASE,
- SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS
+ TK_TEXT_SEARCH_HIDDEN,
+ TK_TEXT_SEARCH_END, TK_TEXT_SEARCH_ALL, TK_TEXT_SEARCH_BACK, TK_TEXT_SEARCH_COUNT, TK_TEXT_SEARCH_ELIDE,
+ TK_TEXT_SEARCH_EXACT, TK_TEXT_SEARCH_FWD, TK_TEXT_SEARCH_NOCASE,
+ TK_TEXT_SEARCH_NOLINESTOP, TK_TEXT_SEARCH_OVERLAP, TK_TEXT_SEARCH_REGEXP, TK_TEXT_SEARCH_STRICTLIMITS
};
/*
@@ -3785,16 +3862,16 @@ TextSearchCmd(
}
switch ((enum SearchSwitches) index) {
- case SEARCH_END:
+ case TK_TEXT_SEARCH_END:
i++;
goto endOfSwitchProcessing;
- case SEARCH_ALL:
+ case TK_TEXT_SEARCH_ALL:
searchSpec.all = 1;
break;
- case SEARCH_BACK:
+ case TK_TEXT_SEARCH_BACK:
searchSpec.backwards = 1;
break;
- case SEARCH_COUNT:
+ case TK_TEXT_SEARCH_COUNT:
if (i >= objc-1) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"no value given for \"-count\" option", -1));
@@ -3810,29 +3887,29 @@ TextSearchCmd(
searchSpec.varPtr = objv[i];
break;
- case SEARCH_ELIDE:
- case SEARCH_HIDDEN:
+ case TK_TEXT_SEARCH_ELIDE:
+ case TK_TEXT_SEARCH_HIDDEN:
searchSpec.searchElide = 1;
break;
- case SEARCH_EXACT:
+ case TK_TEXT_SEARCH_EXACT:
searchSpec.exact = 1;
break;
- case SEARCH_FWD:
+ case TK_TEXT_SEARCH_FWD:
searchSpec.backwards = 0;
break;
- case SEARCH_NOCASE:
+ case TK_TEXT_SEARCH_NOCASE:
searchSpec.noCase = 1;
break;
- case SEARCH_NOLINESTOP:
+ case TK_TEXT_SEARCH_NOLINESTOP:
searchSpec.noLineStop = 1;
break;
- case SEARCH_OVERLAP:
+ case TK_TEXT_SEARCH_OVERLAP:
searchSpec.overlap = 1;
break;
- case SEARCH_STRICTLIMITS:
+ case TK_TEXT_SEARCH_STRICTLIMITS:
searchSpec.strictLimits = 1;
break;
- case SEARCH_REGEXP:
+ case TK_TEXT_SEARCH_REGEXP:
searchSpec.exact = 0;
break;
default:
@@ -4152,7 +4229,7 @@ TextSearchAddNextLine(
if (lenPtr != NULL) {
if (searchSpecPtr->exact) {
- (void)Tcl_GetString(theLine);
+ Tcl_GetString(theLine);
*lenPtr = theLine->length;
} else {
*lenPtr = Tcl_GetCharLength(theLine);
@@ -4433,7 +4510,7 @@ TkTextGetTabs(
Tcl_Obj **objv;
TkTextTabArray *tabArrayPtr;
TkTextTab *tabPtr;
- Tcl_UniChar ch;
+ int ch;
double prevStop, lastStop;
/*
* Map these strings to TkTextTabAlign values.
@@ -4540,7 +4617,7 @@ TkTextGetTabs(
* There may be a more efficient way of getting this.
*/
- Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch);
+ TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch);
if (!Tcl_UniCharIsAlpha(ch)) {
continue;
}
@@ -4677,15 +4754,14 @@ TextDumpCmd(
if (objc == arg) {
TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
} else {
- int length;
+ size_t length;
const char *str;
if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
return TCL_ERROR;
}
- str = Tcl_GetString(objv[arg]);
- length = objv[arg]->length;
- if (strncmp(str, "end", (unsigned) length) == 0) {
+ str = TkGetStringFromObj(objv[arg], &length);
+ if (strncmp(str, "end", length) == 0) {
atEnd = 1;
}
}
@@ -5000,7 +5076,7 @@ DumpSegment(
Tcl_DecrRefCount(tuple);
return 0;
} else {
- int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
+ TkSizeT oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
Tcl_DString buf;
int code;
@@ -5043,6 +5119,8 @@ TextEditUndo(
TkText *textPtr) /* Overall information about text widget. */
{
int status;
+ Tcl_Obj *cmdObj;
+ int code;
if (!textPtr->sharedTextPtr->undo) {
return TCL_OK;
@@ -5066,6 +5144,22 @@ TextEditUndo(
}
textPtr->sharedTextPtr->undo = 1;
+ /*
+ * Convert undo/redo temporary marks set by TkUndoRevert() into
+ * indices left in the interp result.
+ */
+
+ cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s",
+ Tk_PathName(textPtr->tkwin));
+ Tcl_IncrRefCount(cmdObj);
+ code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL);
+ if (code != TCL_OK) {
+ Tcl_AddErrorInfo(textPtr->interp,
+ "\n (on undoing)");
+ Tcl_BackgroundException(textPtr->interp, code);
+ }
+ Tcl_DecrRefCount(cmdObj);
+
return status;
}
@@ -5091,6 +5185,8 @@ TextEditRedo(
TkText *textPtr) /* Overall information about text widget. */
{
int status;
+ Tcl_Obj *cmdObj;
+ int code;
if (!textPtr->sharedTextPtr->undo) {
return TCL_OK;
@@ -5113,6 +5209,23 @@ TextEditRedo(
textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
}
textPtr->sharedTextPtr->undo = 1;
+
+ /*
+ * Convert undo/redo temporary marks set by TkUndoApply() into
+ * indices left in the interp result.
+ */
+
+ cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s",
+ Tk_PathName(textPtr->tkwin));
+ Tcl_IncrRefCount(cmdObj);
+ code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL);
+ if (code != TCL_OK) {
+ Tcl_AddErrorInfo(textPtr->interp,
+ "\n (on undoing)");
+ Tcl_BackgroundException(textPtr->interp, code);
+ }
+ Tcl_DecrRefCount(cmdObj);
+
return status;
}
@@ -5141,11 +5254,16 @@ TextEditCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
int index, setModified, oldModified;
+ int canRedo = 0;
+ int canUndo = 0;
+
static const char *const editOptionStrings[] = {
- "modified", "redo", "reset", "separator", "undo", NULL
+ "canundo", "canredo", "modified", "redo", "reset", "separator",
+ "undo", NULL
};
enum editOptions {
- EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO
+ EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET,
+ EDIT_SEPARATOR, EDIT_UNDO
};
if (objc < 3) {
@@ -5159,6 +5277,26 @@ TextEditCmd(
}
switch ((enum editOptions) index) {
+ case EDIT_CANREDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo));
+ break;
+ case EDIT_CANUNDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo));
+ break;
case EDIT_MODIFIED:
if (objc == 3) {
Tcl_SetObjResult(interp,
@@ -5200,18 +5338,28 @@ TextEditCmd(
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
if (TextEditRedo(textPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
return TCL_ERROR;
}
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+ if (!canUndo || !canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_RESET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
+ if (canUndo || canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_SEPARATOR:
if (objc != 3) {
@@ -5225,11 +5373,16 @@ TextEditCmd(
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
if (TextEditUndo(textPtr)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ if (!canRedo || !canUndo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
}
return TCL_OK;
@@ -5324,6 +5477,7 @@ TextGetText(
*
* Send an event that the text was modified. This is equivalent to:
* event generate $textWidget <<Modified>>
+ * for all peers of $textWidget.
*
* Results:
* None
@@ -5338,21 +5492,41 @@ static void
GenerateModifiedEvent(
TkText *textPtr) /* Information about text widget. */
{
- union {
- XEvent general;
- XVirtualEvent virtual;
- } event;
-
- Tk_MakeWindowExist(textPtr->tkwin);
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(textPtr->tkwin);
- event.general.xany.display = Tk_Display(textPtr->tkwin);
- event.virtual.name = Tk_GetUid("Modified");
- Tk_HandleEvent(&event.general);
+ for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ Tk_MakeWindowExist(textPtr->tkwin);
+ TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateUndoStackEvent --
+ *
+ * Send an event that the undo or redo stack became empty or unempty.
+ * This is equivalent to:
+ * event generate $textWidget <<UndoStack>>
+ * for all peers of $textWidget.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * May force the text window (and all peers) into existence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateUndoStackEvent(
+ TkText *textPtr) /* Information about text widget. */
+{
+ for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ Tk_MakeWindowExist(textPtr->tkwin);
+ TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
+ }
}
/*
@@ -5376,7 +5550,6 @@ UpdateDirtyFlag(
TkSharedText *sharedTextPtr)/* Information about text widget. */
{
int oldDirtyFlag;
- TkText *textPtr;
/*
* If we've been forced to be dirty, we stay dirty (until explicitly
@@ -5407,10 +5580,7 @@ UpdateDirtyFlag(
}
if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) {
- for (textPtr = sharedTextPtr->peers; textPtr != NULL;
- textPtr = textPtr->next) {
- GenerateModifiedEvent(textPtr);
- }
+ GenerateModifiedEvent(sharedTextPtr->peers);
}
}
@@ -5439,21 +5609,21 @@ RunAfterSyncCmd(
int code;
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
- /*
- * The widget has been deleted. Don't do anything.
- */
+ /*
+ * The widget has been deleted. Don't do anything.
+ */
- if (--textPtr->refCount == 0) {
- ckfree((char *) textPtr);
- }
- return;
+ if (textPtr->refCount-- <= 1) {
+ ckfree((char *) textPtr);
+ }
+ return;
}
Tcl_Preserve((ClientData) textPtr->interp);
code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL);
if (code == TCL_ERROR) {
- Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
- Tcl_BackgroundError(textPtr->interp);
+ Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
+ Tcl_BackgroundError(textPtr->interp);
}
Tcl_Release((ClientData) textPtr->interp);
Tcl_DecrRefCount(textPtr->afterSyncCmd);
@@ -5663,8 +5833,7 @@ SearchCore(
* it has dual purpose.
*/
- pattern = Tcl_GetString(patObj);
- matchLength = patObj->length;
+ pattern = Tcl_GetStringFromObj(patObj, &matchLength);
nl = strchr(pattern, '\n');
/*
@@ -5734,7 +5903,7 @@ SearchCore(
firstOffset = 0;
}
- if (alreadySearchOffset != -1) {
+ if (alreadySearchOffset >= 0) {
if (searchSpecPtr->backwards) {
if (alreadySearchOffset < lastOffset) {
lastOffset = alreadySearchOffset;
@@ -5797,7 +5966,7 @@ SearchCore(
CLANG_ASSERT(pattern);
do {
- Tcl_UniChar ch;
+ int ch;
const char *p;
int lastFullLine = lastOffset;
@@ -5823,17 +5992,17 @@ SearchCore(
* match.
*/
- const char c = pattern[0];
+ const char c = matchLength ? pattern[0] : '\0';
- if (alreadySearchOffset != -1) {
+ if (alreadySearchOffset >= 0) {
p = startOfLine + alreadySearchOffset;
alreadySearchOffset = -1;
} else {
p = startOfLine + lastOffset -1;
}
while (p >= startOfLine + firstOffset) {
- if (p[0] == c && !strncmp(p, pattern,
- (unsigned) matchLength)) {
+ if (matchLength == 0 || (p[0] == c && !strncmp(
+ p, pattern, (size_t) matchLength))) {
goto backwardsMatch;
}
p--;
@@ -5928,7 +6097,7 @@ SearchCore(
* result.
*/
- if (strncmp(p,pattern,(unsigned)matchLength)) {
+ if (strncmp(p,pattern,(size_t)matchLength)) {
p = NULL;
}
break;
@@ -5996,10 +6165,14 @@ SearchCore(
if (firstNewLine != -1) {
break;
} else {
- alreadySearchOffset -= matchLength;
+ alreadySearchOffset -= (matchLength ? matchLength : 1);
+ if (alreadySearchOffset < 0) {
+ break;
+ }
}
} else {
- firstOffset = p - startOfLine + matchLength;
+ firstOffset = matchLength ? p - startOfLine + matchLength
+ : p - startOfLine + 1;
if (firstOffset >= lastOffset) {
/*
* Now, we have to be careful not to find
@@ -6027,7 +6200,7 @@ SearchCore(
}
} else {
firstOffset = p - startOfLine +
- Tcl_UtfToUniChar(startOfLine+matchOffset,&ch);
+ TkUtfToUniChar(startOfLine+matchOffset,&ch);
}
}
} while (searchSpecPtr->all);
@@ -6660,7 +6833,7 @@ SetLineStartEnd(
TkText *textPtr = (TkText *) recordPtr;
if (internalOffset >= 0) {
- internalPtr = recordPtr + internalOffset;
+ internalPtr = (char *)recordPtr + internalOffset;
} else {
internalPtr = NULL;
}
@@ -6735,10 +6908,9 @@ ObjectIsEmpty(
if (objPtr == NULL) {
return 1;
}
- if (objPtr->bytes != NULL) {
- return (objPtr->length == 0);
+ if (objPtr->bytes == NULL) {
+ Tcl_GetString(objPtr);
}
- (void)Tcl_GetString(objPtr);
return (objPtr->length == 0);
}
diff --git a/generic/tkText.h b/generic/tkText.h
index fc92644..5e84fd5 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -347,6 +347,9 @@ typedef struct TkTextTag {
int lMargin2; /* Left margin for second and later display
* lines of each text line, in pixels. Only
* valid if lMargin2String is non-NULL. */
+ Tk_3DBorder lMarginColor; /* Used for drawing background in left margins.
+ * This is used for both lmargin1 and lmargin2.
+ * NULL means no value specified here. */
char *offsetString; /* -offset option string (malloc-ed). NULL
* means option not specified. */
int offset; /* Vertical offset of text's baseline from
@@ -358,10 +361,18 @@ typedef struct TkTextTag {
int overstrike; /* Non-zero means draw horizontal line through
* middle of text. Only valid if
* overstrikeString is non-NULL. */
+ XColor *overstrikeColor; /* Color for the overstrike. NULL means same
+ * color as foreground. */
char *rMarginString; /* -rmargin option string (malloc-ed). NULL
* means option not specified. */
int rMargin; /* Right margin for text, in pixels. Only
* valid if rMarginString is non-NULL. */
+ Tk_3DBorder rMarginColor; /* Used for drawing background in right margin.
+ * NULL means no value specified here. */
+ Tk_3DBorder selBorder; /* Used for drawing background for selected text.
+ * NULL means no value specified here. */
+ XColor *selFgColor; /* Foreground color for selected text. NULL means
+ * no value specified here. */
char *spacing1String; /* -spacing1 option string (malloc-ed). NULL
* means option not specified. */
int spacing1; /* Extra spacing above first display line for
@@ -389,6 +400,8 @@ typedef struct TkTextTag {
int underline; /* Non-zero means draw underline underneath
* text. Only valid if underlineString is
* non-NULL. */
+ XColor *underlineColor; /* Color for the underline. NULL means same
+ * color as foreground. */
TkWrapMode wrapMode; /* How to handle wrap-around for this tag.
* Must be TEXT_WRAPMODE_CHAR,
* TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or
@@ -519,8 +532,16 @@ typedef enum {
* that are peers.
*/
+#ifndef TkSizeT
+# if TCL_MAJOR_VERSION > 8
+# define TkSizeT size_t
+# else
+# define TkSizeT int
+# endif
+#endif
+
typedef struct TkSharedText {
- int refCount; /* Reference count this shared object. */
+ TkSizeT refCount; /* Reference count this shared object. */
TkTextBTree tree; /* B-tree representation of text and tags for
* widget. */
Tcl_HashTable tagTable; /* Hash table that maps from tag names to
@@ -549,7 +570,7 @@ typedef struct TkSharedText {
* exist, so the table hasn't been created.
* Each "object" used for this table is the
* name of a tag. */
- int stateEpoch; /* This is incremented each time the B-tree's
+ TkSizeT stateEpoch; /* This is incremented each time the B-tree's
* contents change structurally, or when the
* start/end limits change, and means that any
* cached TkTextIndex objects are no longer
@@ -567,6 +588,8 @@ typedef struct TkSharedText {
* statements. */
int autoSeparators; /* Non-zero means the separators will be
* inserted automatically. */
+ int undoMarkId; /* Counts undo marks temporarily used during
+ undo and redo operations. */
int isDirty; /* Flag indicating the 'dirtyness' of the
* text widget. If the flag is not zero,
* unsaved modifications have been applied to
@@ -768,7 +791,7 @@ typedef struct TkText {
* definitions. */
Tk_OptionTable optionTable; /* Token representing the configuration
* specifications. */
- int refCount; /* Number of cached TkTextIndex objects
+ TkSizeT refCount; /* Number of cached TkTextIndex objects
* refering to us. */
int insertCursorType; /* 0 = standard insertion cursor, 1 = block
* cursor. */
@@ -994,7 +1017,7 @@ MODULE_SCOPE void TkBTreeRemoveClient(TkTextBTree tree,
MODULE_SCOPE void TkBTreeDestroy(TkTextBTree tree);
MODULE_SCOPE void TkBTreeDeleteIndexRange(TkTextBTree tree,
TkTextIndex *index1Ptr, TkTextIndex *index2Ptr);
-MODULE_SCOPE int TkBTreeEpoch(TkTextBTree tree);
+MODULE_SCOPE TkSizeT TkBTreeEpoch(TkTextBTree tree);
MODULE_SCOPE TkTextLine *TkBTreeFindLine(TkTextBTree tree,
const TkText *textPtr, int line);
MODULE_SCOPE TkTextLine *TkBTreeFindPixelLine(TkTextBTree tree,
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index 0fdc280..66fa140 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -105,7 +105,7 @@ typedef struct BTree {
int clients; /* Number of clients of this B-tree. */
int pixelReferences; /* Number of clients of this B-tree which care
* about pixel heights. */
- int stateEpoch; /* Updated each time any aspect of the B-tree
+ TkSizeT stateEpoch; /* Updated each time any aspect of the B-tree
* changes. */
TkSharedText *sharedTextPtr;/* Used to find tagTable in consistency
* checking code, and to access list of all
@@ -140,10 +140,10 @@ int tkBTreeDebug = 0;
* Macros that determine how much space to allocate for new segments:
*/
-#define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \
- + 1 + (chars)))
-#define TSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
- + sizeof(TkTextToggle)))
+#define CSEG_SIZE(chars) (Tk_Offset(TkTextSegment, body) \
+ + 1 + (chars))
+#define TSEG_SIZE (Tk_Offset(TkTextSegment, body) \
+ + sizeof(TkTextToggle))
/*
* Forward declarations for functions defined in this file:
@@ -501,7 +501,7 @@ TkBTreeDestroy(
*----------------------------------------------------------------------
*/
-int
+TkSizeT
TkBTreeEpoch(
TkTextBTree tree) /* Tree to get epoch for. */
{
@@ -799,6 +799,7 @@ RemovePixelClient(
nodePtr->numPixels[treePtr->pixelReferences-1];
}
if (treePtr->pixelReferences == 1) {
+ ckfree(nodePtr->numPixels);
nodePtr->numPixels = NULL;
} else {
nodePtr->numPixels = ckrealloc(nodePtr->numPixels,
@@ -1020,7 +1021,7 @@ TkBTreeInsertChars(
* this line). */
register TkTextSegment *segPtr;
TkTextLine *newLinePtr;
- int chunkSize; /* # characters in current chunk. */
+ size_t chunkSize; /* # characters in current chunk. */
register const char *eol; /* Pointer to character just after last one in
* current chunk. */
int changeToLineCount; /* Counts change to total number of lines in
@@ -1069,7 +1070,7 @@ TkBTreeInsertChars(
curPtr->nextPtr = segPtr;
}
segPtr->size = chunkSize;
- memcpy(segPtr->body.chars, string, (size_t) chunkSize);
+ memcpy(segPtr->body.chars, string, chunkSize);
segPtr->body.chars[chunkSize] = 0;
if (eol[-1] != '\n') {
@@ -1439,6 +1440,8 @@ TkBTreeDeleteIndexRange(
prevNodePtr->nextPtr = curNodePtr->nextPtr;
}
parentPtr->numChildren--;
+ DeleteSummaries(curNodePtr->summaryPtr);
+ ckfree(curNodePtr->numPixels);
ckfree(curNodePtr);
curNodePtr = parentPtr;
}
@@ -4185,6 +4188,7 @@ Rebalance(
treePtr->rootPtr = nodePtr->children.nodePtr;
treePtr->rootPtr->parentPtr = NULL;
DeleteSummaries(nodePtr->summaryPtr);
+ ckfree(nodePtr->numPixels);
ckfree(nodePtr);
}
return;
@@ -4274,6 +4278,7 @@ Rebalance(
nodePtr->nextPtr = otherPtr->nextPtr;
nodePtr->parentPtr->numChildren--;
DeleteSummaries(otherPtr->summaryPtr);
+ ckfree(otherPtr->numPixels);
ckfree(otherPtr);
continue;
}
@@ -4558,7 +4563,7 @@ CharSplitProc(
newPtr1->typePtr = &tkTextCharType;
newPtr1->nextPtr = newPtr2;
newPtr1->size = index;
- memcpy(newPtr1->body.chars, segPtr->body.chars, (size_t) index);
+ memcpy(newPtr1->body.chars, segPtr->body.chars, index);
newPtr1->body.chars[index] = 0;
newPtr2->typePtr = &tkTextCharType;
newPtr2->nextPtr = segPtr->nextPtr;
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index 1eea37d..9f0d7e0 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -16,12 +16,6 @@
#include "tkInt.h"
#include "tkText.h"
-#ifdef _WIN32
-#include "tkWinInt.h"
-#elif defined(__CYGWIN__)
-#include "tkUnixInt.h"
-#endif
-
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
@@ -136,11 +130,15 @@ typedef struct StyleValues {
* line of each text line. */
int lMargin2; /* Left margin, in pixels, for second and
* later display lines of each text line. */
+ Tk_3DBorder lMarginColor; /* Color of left margins (1 and 2). */
int offset; /* Offset in pixels of baseline, relative to
* baseline of line. */
int overstrike; /* Non-zero means draw overstrike through
* text. */
+ XColor *overstrikeColor; /* Foreground color for overstrike through
+ * text. */
int rMargin; /* Right margin, in pixels. */
+ Tk_3DBorder rMarginColor; /* Color of right margin. */
int spacing1; /* Spacing above first dline in text line. */
int spacing2; /* Spacing between lines of dline. */
int spacing3; /* Spacing below last dline in text line. */
@@ -149,6 +147,8 @@ typedef struct StyleValues {
int tabStyle; /* One of TABULAR or WORDPROCESSOR. */
int underline; /* Non-zero means draw underline underneath
* text. */
+ XColor *underlineColor; /* Foreground color for underline underneath
+ * text. */
int elide; /* Zero means draw text, otherwise not. */
TkWrapMode wrapMode; /* How to handle wrap-around for this tag.
* One of TEXT_WRAPMODE_CHAR,
@@ -162,11 +162,13 @@ typedef struct StyleValues {
*/
typedef struct TextStyle {
- int refCount; /* Number of times this structure is
+ TkSizeT refCount; /* Number of times this structure is
* referenced in Chunks. */
GC bgGC; /* Graphics context for background. None means
* use widget background. */
GC fgGC; /* Graphics context for foreground. */
+ GC ulGC; /* Graphics context for underline. */
+ GC ovGC; /* Graphics context for overstrike. */
StyleValues *sValuePtr; /* Raw information from which GCs were
* derived. */
Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used to
@@ -234,6 +236,14 @@ typedef struct DLine {
int spaceBelow; /* How much extra space was added to the
* bottom of the line because of spacing
* options. This is included in height. */
+ Tk_3DBorder lMarginColor; /* Background color of the area corresponding
+ * to the left margin of the display line. */
+ int lMarginWidth; /* Pixel width of the area corresponding to
+ * the left margin. */
+ Tk_3DBorder rMarginColor; /* Background color of the area corresponding
+ * to the right margin of the display line. */
+ int rMarginWidth; /* Pixel width of the area corresponding to
+ * the right margin. */
int length; /* Total length of line, in pixels. */
TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all of
* those that are displayed on this line of
@@ -390,7 +400,7 @@ typedef struct TextDInfo {
* to so far... */
int metricPixelHeight; /* ...and this is for the height calculation
* so far...*/
- int metricEpoch; /* ...and this for the epoch of the partial
+ TkSizeT metricEpoch; /* ...and this for the epoch of the partial
* calculation so it can be cancelled if
* things change once more. This field will be
* -1 if there is no long-line calculation in
@@ -594,7 +604,7 @@ static void AsyncUpdateLineMetrics(ClientData clientData);
static void GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync);
static void AsyncUpdateYScrollbar(ClientData clientData);
static int IsStartOfNotMergedLine(TkText *textPtr,
- CONST TkTextIndex *indexPtr);
+ const TkTextIndex *indexPtr);
/*
* Result values returned by TextGetScrollInfoObj:
@@ -748,6 +758,7 @@ GetStyle(
TextStyle *stylePtr;
Tcl_HashEntry *hPtr;
int numTags, isNew, i;
+ int isSelected;
XGCValues gcValues;
unsigned long mask;
/*
@@ -758,6 +769,7 @@ GetStyle(
int fgPrio, fontPrio, fgStipplePrio;
int underlinePrio, elidePrio, justifyPrio, offsetPrio;
int lMargin1Prio, lMargin2Prio, rMarginPrio;
+ int lMarginColorPrio, rMarginColorPrio;
int spacing1Prio, spacing2Prio, spacing3Prio;
int overstrikePrio, tabPrio, tabStylePrio, wrapPrio;
@@ -772,11 +784,14 @@ GetStyle(
fgPrio = fontPrio = fgStipplePrio = -1;
underlinePrio = elidePrio = justifyPrio = offsetPrio = -1;
lMargin1Prio = lMargin2Prio = rMarginPrio = -1;
+ lMarginColorPrio = rMarginColorPrio = -1;
spacing1Prio = spacing2Prio = spacing3Prio = -1;
overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1;
memset(&styleValues, 0, sizeof(StyleValues));
styleValues.relief = TK_RELIEF_FLAT;
styleValues.fgColor = textPtr->fgColor;
+ styleValues.underlineColor = textPtr->fgColor;
+ styleValues.overstrikeColor = textPtr->fgColor;
styleValues.tkfont = textPtr->tkfont;
styleValues.justify = TK_JUSTIFY_LEFT;
styleValues.spacing1 = textPtr->spacing1;
@@ -786,12 +801,22 @@ GetStyle(
styleValues.tabStyle = textPtr->tabStyle;
styleValues.wrapMode = textPtr->wrapMode;
styleValues.elide = 0;
+ isSelected = 0;
+
+ for (i = 0 ; i < numTags; i++) {
+ if (textPtr->selTagPtr == tagPtrs[i]) {
+ isSelected = 1;
+ break;
+ }
+ }
for (i = 0 ; i < numTags; i++) {
Tk_3DBorder border;
+ XColor *fgColor;
tagPtr = tagPtrs[i];
border = tagPtr->border;
+ fgColor = tagPtr->fgColor;
/*
* If this is the selection tag, and inactiveSelBorder is NULL (the
@@ -811,6 +836,14 @@ GetStyle(
border = textPtr->inactiveSelBorder;
}
+ if ((tagPtr->selBorder != NULL) && (isSelected)) {
+ border = tagPtr->selBorder;
+ }
+
+ if ((tagPtr->selFgColor != None) && (isSelected)) {
+ fgColor = tagPtr->selFgColor;
+ }
+
if ((border != NULL) && (tagPtr->priority > borderPrio)) {
styleValues.border = border;
borderPrio = tagPtr->priority;
@@ -834,8 +867,8 @@ GetStyle(
styleValues.bgStipple = tagPtr->bgStipple;
bgStipplePrio = tagPtr->priority;
}
- if ((tagPtr->fgColor != None) && (tagPtr->priority > fgPrio)) {
- styleValues.fgColor = tagPtr->fgColor;
+ if ((fgColor != None) && (tagPtr->priority > fgPrio)) {
+ styleValues.fgColor = fgColor;
fgPrio = tagPtr->priority;
}
if ((tagPtr->tkfont != None) && (tagPtr->priority > fontPrio)) {
@@ -862,6 +895,11 @@ GetStyle(
styleValues.lMargin2 = tagPtr->lMargin2;
lMargin2Prio = tagPtr->priority;
}
+ if ((tagPtr->lMarginColor != NULL)
+ && (tagPtr->priority > lMarginColorPrio)) {
+ styleValues.lMarginColor = tagPtr->lMarginColor;
+ lMarginColorPrio = tagPtr->priority;
+ }
if ((tagPtr->offsetString != NULL)
&& (tagPtr->priority > offsetPrio)) {
styleValues.offset = tagPtr->offset;
@@ -871,12 +909,22 @@ GetStyle(
&& (tagPtr->priority > overstrikePrio)) {
styleValues.overstrike = tagPtr->overstrike;
overstrikePrio = tagPtr->priority;
+ if (tagPtr->overstrikeColor != None) {
+ styleValues.overstrikeColor = tagPtr->overstrikeColor;
+ } else if (fgColor != None) {
+ styleValues.overstrikeColor = fgColor;
+ }
}
if ((tagPtr->rMarginString != NULL)
&& (tagPtr->priority > rMarginPrio)) {
styleValues.rMargin = tagPtr->rMargin;
rMarginPrio = tagPtr->priority;
}
+ if ((tagPtr->rMarginColor != NULL)
+ && (tagPtr->priority > rMarginColorPrio)) {
+ styleValues.rMarginColor = tagPtr->rMarginColor;
+ rMarginColorPrio = tagPtr->priority;
+ }
if ((tagPtr->spacing1String != NULL)
&& (tagPtr->priority > spacing1Prio)) {
styleValues.spacing1 = tagPtr->spacing1;
@@ -906,6 +954,11 @@ GetStyle(
&& (tagPtr->priority > underlinePrio)) {
styleValues.underline = tagPtr->underline;
underlinePrio = tagPtr->priority;
+ if (tagPtr->underlineColor != None) {
+ styleValues.underlineColor = tagPtr->underlineColor;
+ } else if (fgColor != None) {
+ styleValues.underlineColor = fgColor;
+ }
}
if ((tagPtr->elideString != NULL)
&& (tagPtr->priority > elidePrio)) {
@@ -962,6 +1015,11 @@ GetStyle(
mask |= GCStipple|GCFillStyle;
}
stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
+ mask = GCForeground;
+ gcValues.foreground = styleValues.underlineColor->pixel;
+ stylePtr->ulGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
+ gcValues.foreground = styleValues.overstrikeColor->pixel;
+ stylePtr->ovGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues);
stylePtr->sValuePtr = (StyleValues *)
Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr);
stylePtr->hPtr = hPtr;
@@ -994,14 +1052,19 @@ FreeStyle(
register TextStyle *stylePtr)
/* Information about style to free. */
{
- stylePtr->refCount--;
- if (stylePtr->refCount == 0) {
+ if (stylePtr->refCount-- <= 1) {
if (stylePtr->bgGC != None) {
Tk_FreeGC(textPtr->display, stylePtr->bgGC);
}
if (stylePtr->fgGC != None) {
Tk_FreeGC(textPtr->display, stylePtr->fgGC);
}
+ if (stylePtr->ulGC != None) {
+ Tk_FreeGC(textPtr->display, stylePtr->ulGC);
+ }
+ if (stylePtr->ovGC != None) {
+ Tk_FreeGC(textPtr->display, stylePtr->ovGC);
+ }
Tcl_DeleteHashEntry(stylePtr->hPtr);
ckfree(stylePtr);
}
@@ -1113,6 +1176,10 @@ LayoutDLine(
dlPtr->nextPtr = NULL;
dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID;
dlPtr->logicalLinesMerged = 0;
+ dlPtr->lMarginColor = NULL;
+ dlPtr->lMarginWidth = 0;
+ dlPtr->rMarginColor = NULL;
+ dlPtr->rMarginWidth = 0;
/*
* This is not necessarily totally correct, where we have merged logical
@@ -1387,6 +1454,7 @@ LayoutDLine(
x = chunkPtr->stylePtr->sValuePtr->lMargin2;
}
+ dlPtr->lMarginWidth = x;
if (wrapMode == TEXT_WRAPMODE_NONE) {
maxX = -1;
} else {
@@ -1698,6 +1766,11 @@ LayoutDLine(
}
dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow;
dlPtr->baseline += dlPtr->spaceAbove;
+ dlPtr->lMarginColor = sValuePtr->lMarginColor;
+ dlPtr->rMarginColor = sValuePtr->rMarginColor;
+ if (wrapMode != TEXT_WRAPMODE_NONE) {
+ dlPtr->rMarginWidth = rMargin;
+ }
/*
* Recompute line length: may have changed because of justification.
@@ -2384,12 +2457,26 @@ DisplayDLine(
Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT);
/*
- * Next, draw background information for the whole line.
+ * Second, draw background information for the whole line.
*/
DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap);
/*
+ * Third, draw the background color of the left and right margins.
+ */
+ if (dlPtr->lMarginColor != NULL) {
+ Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->lMarginColor, 0, y,
+ dlPtr->lMarginWidth + dInfoPtr->x - dInfoPtr->curXPixelOffset,
+ dlPtr->height, 0, TK_RELIEF_FLAT);
+ }
+ if (dlPtr->rMarginColor != NULL) {
+ Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->rMarginColor,
+ dInfoPtr->maxX - dlPtr->rMarginWidth + dInfoPtr->curXPixelOffset,
+ y, dlPtr->rMarginWidth, dlPtr->height, 0, TK_RELIEF_FLAT);
+ }
+
+ /*
* Make another pass through all of the chunks to redraw the insertion
* cursor, if it is visible on this line. Must do it here rather than in
* the foreground pass below because otherwise a wide insertion cursor
@@ -2911,7 +2998,7 @@ AsyncUpdateLineMetrics(
* The widget has been deleted, or is not mapped. Don't do anything.
*/
- if (--textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
return;
@@ -2956,7 +3043,7 @@ AsyncUpdateLineMetrics(
* and we've reached the last line, then we're done.
*/
- if (dInfoPtr->metricEpoch == -1
+ if (dInfoPtr->metricEpoch == TCL_AUTO_LENGTH
&& lineNum == dInfoPtr->lastMetricUpdateLine) {
/*
* We have looped over all lines, so we're done. We must release our
@@ -2986,8 +3073,7 @@ AsyncUpdateLineMetrics(
GenerateWidgetViewSyncEvent(textPtr, 1);
- textPtr->refCount--;
- if (textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
return;
@@ -3010,7 +3096,7 @@ AsyncUpdateLineMetrics(
* Send the <<WidgetViewSync>> event related to the text widget
* line metrics asynchronous update.
* This is equivalent to:
- * event generate $textWidget <<WidgetViewSync>> -detail $s
+ * event generate $textWidget <<WidgetViewSync>> -data $s
* where $s is the sync status: true (when the widget view is in
* sync with its internal data) or false (when it is not).
*
@@ -3026,19 +3112,10 @@ AsyncUpdateLineMetrics(
static void
GenerateWidgetViewSyncEvent(
TkText *textPtr, /* Information about text widget. */
- Bool InSync) /* True if in sync, false otherwise */
+ Bool InSync) /* true if in sync, false otherwise */
{
- union {XEvent general; XVirtualEvent virtual;} event;
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(textPtr->tkwin);
- event.general.xany.display = Tk_Display(textPtr->tkwin);
- event.virtual.name = Tk_GetUid("WidgetViewSync");
- event.virtual.user_data = Tcl_NewBooleanObj(InSync);
- Tk_HandleEvent(&event.general);
+ TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
+ Tcl_NewBooleanObj(InSync));
}
/*
@@ -3116,7 +3193,7 @@ TkTextUpdateLineMetrics(
* then we can't be done.
*/
- if (textPtr->dInfoPtr->metricEpoch == -1 && lineNum == endLine) {
+ if (textPtr->dInfoPtr->metricEpoch == TCL_AUTO_LENGTH && lineNum == endLine) {
/*
* We have looped over all lines, so we're done.
*/
@@ -4036,8 +4113,8 @@ DisplayText(
MacDrawable *macWin = winPtr->privatePtr;
if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
dInfoPtr->flags &= ~REDRAW_PENDING;
- return;
- }
+ return;
+ }
#endif
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
@@ -4078,7 +4155,7 @@ DisplayText(
textPtr->refCount++;
dInfoPtr->flags &= ~REPICK_NEEDED;
TkTextPickCurrent(textPtr, &textPtr->pickEvent);
- if (--textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
goto end;
}
@@ -4190,7 +4267,6 @@ DisplayText(
}
dlPtr = dlPtr->nextPtr;
}
-
/*
* Scan through the lines following the copied ones to see if we are
* going to overwrite them with the copy operation. If so, mark them
@@ -4215,7 +4291,6 @@ DisplayText(
oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
damageRgn)) {
TextInvalidateRegion(textPtr, damageRgn);
-
}
numCopies++;
TkDestroyRegion(damageRgn);
@@ -4357,11 +4432,38 @@ DisplayText(
}
dlPtr->oldY = dlPtr->y;
dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID);
+#ifdef MAC_OSX_TK
+ } else if (dlPtr->chunkPtr != NULL) {
+ /*
+ * On macOS we need to redisplay all embedded windows which
+ * were moved by the call to TkScrollWindows above. This is
+ * not necessary on Unix or Windows because XScrollWindow will
+ * have included the bounding rectangles of all of these
+ * windows in the damage region. The macosx implementation of
+ * TkScrollWindow does not do this. It simply generates a
+ * damage region which is the scroll source rectangle minus
+ * the scroll destination rectangle. This is because there is
+ * no efficient process available for iterating through the
+ * subwindows which meet the scrolled area. (On Unix this is
+ * handled by GraphicsExpose events generated by XCopyArea and
+ * on Windows by ScrollWindowEx. On macOS the low level
+ * scrolling is accomplished by calling [view scrollRect:by:].
+ * This method does not provide any damage information and, in
+ * any case, could not be aware of Tk windows which were not
+ * based on NSView objects.
+ *
+ * On the other hand, this loop is already iterating through
+ * all embedded windows which could possibly have been moved
+ * by the scrolling. So it is as efficient to redisplay them
+ * here as it would have been if they had been redisplayed by
+ * the call to TextInvalidateRegion above.
+ */
+#else
} else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0)
|| (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) {
- register TkTextDispChunk *chunkPtr;
-
/*
+ * On platforms other than the Mac:
+ *
* It's the first or last DLine which are also overlapping the
* top or bottom of the window, but we decided above it wasn't
* necessary to display them (we were able to update them by
@@ -4375,6 +4477,8 @@ DisplayText(
* So, we loop through all the chunks, calling the display
* proc of embedded windows only.
*/
+#endif
+ register TkTextDispChunk *chunkPtr;
for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
chunkPtr = chunkPtr->nextPtr) {
@@ -4397,13 +4501,18 @@ DisplayText(
x = -chunkPtr->width;
}
+ if (tkTextDebug) {
+ char string[TK_POS_CHARS];
+
+ TkTextPrintIndex(textPtr, &dlPtr->index, string);
+ LOG("tk_textEmbWinDisplay", string);
+ }
TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
dlPtr->spaceAbove,
dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, NULL,
(Drawable) None, dlPtr->y + dlPtr->spaceAbove);
}
-
}
}
#ifndef TK_NO_DOUBLE_BUFFERING
@@ -5973,7 +6082,7 @@ TkTextYviewCmd(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
int pickPlace, type;
int pixels, count;
- int switchLength;
+ size_t switchLength;
double fraction;
TkTextIndex index;
@@ -5993,7 +6102,7 @@ TkTextYviewCmd(
pickPlace = 0;
if (Tcl_GetString(objv[2])[0] == '-') {
register const char *switchStr =
- Tcl_GetStringFromObj(objv[2], &switchLength);
+ TkGetStringFromObj(objv[2], &switchLength);
if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace",
(unsigned) switchLength) == 0)) {
@@ -6148,7 +6257,7 @@ TkTextPendingsync(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
return (
- ((dInfoPtr->metricEpoch == -1) &&
+ ((dInfoPtr->metricEpoch == TCL_AUTO_LENGTH) &&
(dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ?
0 : 1);
}
@@ -6667,7 +6776,7 @@ AsyncUpdateYScrollbar(
GetYView(textPtr->interp, textPtr, 1);
}
- if (--textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
}
@@ -6805,7 +6914,7 @@ FindDLine(
static int
IsStartOfNotMergedLine(
TkText *textPtr, /* Widget record for text widget. */
- CONST TkTextIndex *indexPtr) /* Index to check. */
+ const TkTextIndex *indexPtr) /* Index to check. */
{
TkTextIndex indexPtr2;
@@ -7457,6 +7566,9 @@ TkTextCharLayoutProc(
* (b) at least one pixel of the character is visible, we have not
* already exceeded the character limit, and the next character is a
* white space character.
+ * In the specific case of 'word' wrapping mode however, include all space
+ * characters following the characters that fit in the space we've got,
+ * even if no pixel of them is visible.
*/
p = segPtr->body.chars + byteOffset;
@@ -7496,8 +7608,8 @@ TkTextCharLayoutProc(
if (bytesThatFit < maxBytes) {
if ((bytesThatFit == 0) && noCharsYet) {
- Tcl_UniChar ch;
- int chLen = Tcl_UtfToUniChar(p, &ch);
+ int ch;
+ int chLen = TkUtfToUniChar(p, &ch);
#if TK_LAYOUT_WITH_BASE_CHUNKS
bytesThatFit = CharChunkMeasureChars(chunkPtr, line,
@@ -7519,6 +7631,21 @@ TkTextCharLayoutProc(
nextX = maxX;
bytesThatFit++;
}
+ if (wrapMode == TEXT_WRAPMODE_WORD) {
+ while (p[bytesThatFit] == ' ') {
+ /*
+ * Space characters that would go at the beginning of the
+ * next line are allocated to the current line. This gives
+ * the effect of trimming white spaces that would otherwise
+ * be seen at the beginning of wrapped lines.
+ * Note that testing for '\t' is useless here because the
+ * chunk always includes at most one trailing \t, see
+ * LayoutDLine.
+ */
+
+ bytesThatFit++;
+ }
+ }
if (p[bytesThatFit] == '\n') {
/*
* A newline character takes up no space, so if the previous
@@ -7562,7 +7689,7 @@ TkTextCharLayoutProc(
chunkPtr->breakIndex = -1;
#if !TK_LAYOUT_WITH_BASE_CHUNKS
- ciPtr = ckalloc((Tk_Offset(CharInfo, chars) + 1) + bytesThatFit);
+ ciPtr = ckalloc(Tk_Offset(CharInfo, chars) + 1 + bytesThatFit);
chunkPtr->clientData = ciPtr;
memcpy(ciPtr->chars, p, (unsigned) bytesThatFit);
#endif /* TK_LAYOUT_WITH_BASE_CHUNKS */
@@ -7716,7 +7843,7 @@ CharChunkMeasureChars(
MeasureChars(tkfont, chars, charsLen, 0, bstart,
0, -1, 0, &widthUntilStart);
- xDisplacement = startX - widthUntilStart - chunkPtr->x;
+ xDisplacement = startX - widthUntilStart - ciPtr->baseChunkPtr->x;
}
fit = MeasureChars(tkfont, chars, charsLen, 0, bend,
@@ -7845,7 +7972,7 @@ CharDisplayProc(
y + baseline - sValuePtr->offset);
if (sValuePtr->underline) {
- TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ TkUnderlineCharsInContext(display, dst, stylePtr->ulGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset,
@@ -7855,7 +7982,7 @@ CharDisplayProc(
Tk_FontMetrics fm;
Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
- TkUnderlineCharsInContext(display, dst, stylePtr->fgGC,
+ TkUnderlineCharsInContext(display, dst, stylePtr->ovGC,
sValuePtr->tkfont, string, numBytes,
ciPtr->baseChunkPtr->x + xDisplacement,
y + baseline - sValuePtr->offset
@@ -7872,7 +7999,7 @@ CharDisplayProc(
Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string,
numBytes, offsetX, y + baseline - sValuePtr->offset);
if (sValuePtr->underline) {
- Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
+ Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont,
string, offsetX,
y + baseline - sValuePtr->offset,
0, numBytes);
@@ -7882,7 +8009,7 @@ CharDisplayProc(
Tk_FontMetrics fm;
Tk_GetFontMetrics(sValuePtr->tkfont, &fm);
- Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont,
+ Tk_UnderlineChars(display, dst, stylePtr->ovGC, sValuePtr->tkfont,
string, offsetX,
y + baseline - sValuePtr->offset
- fm.descent - (fm.ascent * 3) / 10,
@@ -8690,7 +8817,7 @@ FinalizeBaseChunk(
#if TK_DRAW_IN_CONTEXT
newwidth = 0;
CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth);
- if (newwidth != chunkPtr->width) {
+ if (newwidth < chunkPtr->width) {
widthAdjust += newwidth - chunkPtr->width;
chunkPtr->width = newwidth;
}
@@ -8878,13 +9005,13 @@ RemoveFromBaseChunk(
bciPtr = baseCharChunkPtr->clientData;
+#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS
if ((ciPtr->baseOffset + ciPtr->numBytes)
!= Tcl_DStringLength(&bciPtr->baseChars)) {
-#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS
fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk "
"(not last)\n");
-#endif
}
+#endif
Tcl_DStringSetLength(&bciPtr->baseChars, ciPtr->baseOffset);
diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c
index 41dd448..defda56 100644
--- a/generic/tkTextImage.c
+++ b/generic/tkTextImage.c
@@ -18,7 +18,7 @@
*/
#define EI_SEG_SIZE \
- ((unsigned) (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage)))
+ (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage))
/*
* Prototypes for functions defined in this file:
@@ -161,7 +161,7 @@ TkTextImageCmd(
Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL);
return TCL_ERROR;
}
- objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei,
+ objPtr = Tk_GetOptionValue(interp, &eiPtr->body.ei,
eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin);
if (objPtr == NULL) {
return TCL_ERROR;
@@ -188,7 +188,7 @@ TkTextImageCmd(
}
if (objc <= 5) {
Tcl_Obj *objPtr = Tk_GetOptionInfo(interp,
- (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable,
+ &eiPtr->body.ei, eiPtr->body.ei.optionTable,
(objc == 5) ? objv[4] : NULL, textPtr->tkwin);
if (objPtr == NULL) {
@@ -337,7 +337,7 @@ EmbImageConfigure(
int conflict = 0; /* True if we have a name conflict */
size_t len; /* length of image name */
- if (Tk_SetOptions(textPtr->interp, (char *) &eiPtr->body.ei,
+ if (Tk_SetOptions(textPtr->interp, &eiPtr->body.ei,
eiPtr->body.ei.optionTable,
objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c
index 8820191..2870c07 100644
--- a/generic/tkTextIndex.c
+++ b/generic/tkTextIndex.c
@@ -11,9 +11,9 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
#include "tkText.h"
+#include "default.h"
/*
* Index to use to select last character in line (very large integer):
@@ -40,9 +40,9 @@ static const char * StartEnd(TkText *textPtr, const char *string,
static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr,
TkText *textPtr, const char *string,
TkTextIndex *indexPtr, int *canCachePtr);
-static int IndexCountBytesOrdered(CONST TkText *textPtr,
- CONST TkTextIndex *indexPtr1,
- CONST TkTextIndex *indexPtr2);
+static int IndexCountBytesOrdered(const TkText *textPtr,
+ const TkTextIndex *indexPtr1,
+ const TkTextIndex *indexPtr2);
/*
* The "textindex" Tcl_Obj definition:
@@ -64,7 +64,7 @@ static void UpdateStringOfTextIndex(Tcl_Obj *objPtr);
#define SET_TEXTINDEX(objPtr, indexPtr) \
((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (indexPtr))
#define SET_INDEXEPOCH(objPtr, epoch) \
- ((objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(epoch))
+ ((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (size_t) (epoch))
/*
* Define the 'textindex' object type, which Tk uses to represent indices in
@@ -87,7 +87,7 @@ FreeTextIndexInternalRep(
TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr);
if (indexPtr->textPtr != NULL) {
- if (--indexPtr->textPtr->refCount == 0) {
+ if (indexPtr->textPtr->refCount-- <= 1) {
/*
* The text widget has been deleted and we need to free it now.
*/
@@ -104,7 +104,7 @@ DupTextIndexInternalRep(
Tcl_Obj *srcPtr, /* TextIndex obj with internal rep to copy. */
Tcl_Obj *copyPtr) /* TextIndex obj with internal rep to set. */
{
- int epoch;
+ TkSizeT epoch;
TkTextIndex *dupIndexPtr, *indexPtr;
dupIndexPtr = ckalloc(sizeof(TkTextIndex));
@@ -134,7 +134,7 @@ UpdateStringOfTextIndex(
Tcl_Obj *objPtr)
{
char buffer[TK_POS_CHARS];
- register int len;
+ size_t len;
const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);
len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);
@@ -206,7 +206,7 @@ TkTextGetIndexFromObj(
int cache;
if (objPtr->typePtr == &tkTextIndexType) {
- int epoch;
+ TkSizeT epoch;
indexPtr = GET_TEXTINDEX(objPtr);
epoch = GET_INDEXEPOCH(objPtr);
@@ -387,7 +387,7 @@ TkTextMakeByteIndex(
TkTextSegment *segPtr;
int index;
const char *p, *start;
- Tcl_UniChar ch;
+ int ch;
indexPtr->tree = tree;
if (lineIndex < 0) {
@@ -437,7 +437,7 @@ TkTextMakeByteIndex(
start = segPtr->body.chars + (byteIndex - index);
p = Tcl_UtfPrev(start, segPtr->body.chars);
- p += Tcl_UtfToUniChar(p, &ch);
+ p += TkUtfToUniChar(p, &ch);
indexPtr->byteIndex += p - start;
}
break;
@@ -480,7 +480,7 @@ TkTextMakeCharIndex(
register TkTextSegment *segPtr;
char *p, *start, *end;
int index, offset;
- Tcl_UniChar ch;
+ int ch;
indexPtr->tree = tree;
if (lineIndex < 0) {
@@ -527,7 +527,7 @@ TkTextMakeCharIndex(
return indexPtr;
}
charIndex--;
- offset = Tcl_UtfToUniChar(p, &ch);
+ offset = TkUtfToUniChar(p, &ch);
index += offset;
}
} else {
@@ -923,7 +923,7 @@ GetIndex(
}
if ((string[0] == 'e')
&& (strncmp(string, "end",
- (size_t) (endOfBase-Tcl_DStringValue(&copy))) == 0)) {
+ endOfBase-Tcl_DStringValue(&copy)) == 0)) {
/*
* Base position is end of text.
*/
@@ -1475,7 +1475,7 @@ TkTextIndexForwChars(
TkTextElideInfo *infoPtr = NULL;
int byteOffset;
char *start, *end, *p;
- Tcl_UniChar ch;
+ int ch;
int elide = 0;
int checkElided = (type & COUNT_DISPLAY);
@@ -1574,7 +1574,7 @@ TkTextIndexForwChars(
if (segPtr->typePtr == &tkTextCharType) {
start = segPtr->body.chars + byteOffset;
end = segPtr->body.chars + segPtr->size;
- for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) {
+ for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) {
if (charCount == 0) {
dstPtr->byteIndex += (p - start);
goto forwardCharDone;
@@ -1636,9 +1636,9 @@ TkTextIndexForwChars(
int
TkTextIndexCountBytes(
- CONST TkText *textPtr,
- CONST TkTextIndex *indexPtr1, /* Index describing one location. */
- CONST TkTextIndex *indexPtr2) /* Index describing second location. */
+ const TkText *textPtr,
+ const TkTextIndex *indexPtr1, /* Index describing one location. */
+ const TkTextIndex *indexPtr2) /* Index describing second location. */
{
int compare = TkTextIndexCmp(indexPtr1, indexPtr2);
@@ -1653,11 +1653,11 @@ TkTextIndexCountBytes(
static int
IndexCountBytesOrdered(
- CONST TkText *textPtr,
- CONST TkTextIndex *indexPtr1,
+ const TkText *textPtr,
+ const TkTextIndex *indexPtr1,
/* Index describing location of character from
* which to count. */
- CONST TkTextIndex *indexPtr2)
+ const TkTextIndex *indexPtr2)
/* Index describing location of last character
* at which to stop the count. */
{
@@ -2298,9 +2298,9 @@ StartEnd(
int chSize = 1;
if (segPtr->typePtr == &tkTextCharType) {
- Tcl_UniChar ch;
+ int ch;
- chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch);
+ chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch);
if (!Tcl_UniCharIsWordChar(ch)) {
break;
}
@@ -2343,9 +2343,9 @@ StartEnd(
int chSize = 1;
if (segPtr->typePtr == &tkTextCharType) {
- Tcl_UniChar ch;
- Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch);
+ int ch;
+ TkUtfToUniChar(segPtr->body.chars + offset, &ch);
if (!Tcl_UniCharIsWordChar(ch)) {
break;
}
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index 6a41c77..da455d3 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -19,8 +19,8 @@
* Macro that determines the size of a mark segment:
*/
-#define MSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
- + sizeof(TkTextMark)))
+#define MSEG_SIZE (Tk_Offset(TkTextSegment, body) \
+ + sizeof(TkTextMark))
/*
* Forward references for functions defined in this file:
@@ -126,14 +126,14 @@ TkTextMarkCmd(
switch ((enum markOptions) optionIndex) {
case MARK_GRAVITY: {
char c;
- int length;
+ size_t length;
const char *str;
if (objc < 4 || objc > 5) {
Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
return TCL_ERROR;
}
- str = Tcl_GetStringFromObj(objv[3], &length);
+ str = TkGetStringFromObj(objv[3], &length);
if (length == 6 && !strcmp(str, "insert")) {
markPtr = textPtr->insertMarkPtr;
} else if (length == 7 && !strcmp(str, "current")) {
@@ -160,7 +160,7 @@ TkTextMarkCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
return TCL_OK;
}
- str = Tcl_GetStringFromObj(objv[4],&length);
+ str = TkGetStringFromObj(objv[4],&length);
c = str[0];
if ((c == 'l') && (strncmp(str, "left", (unsigned) length) == 0)) {
newTypePtr = &tkTextLeftMarkType;
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index 3363d25..0a749c4 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -12,9 +12,9 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "default.h"
#include "tkInt.h"
#include "tkText.h"
+#include "default.h"
/*
* The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap
@@ -30,7 +30,7 @@ static const char *const wrapStrings[] = {
/*
* The 'TkTextTabStyle' enum in tkText.h is used to define a type for the
* -tabstyle option of the Text widget. These values are used as indices into
- * the string table below. Tags are allowed an empty wrap value, but the
+ * the string table below. Tags are allowed an empty tabstyle value, but the
* widget as a whole is not.
*/
@@ -61,15 +61,26 @@ static const Tk_OptionSpec tagOptionSpecs[] = {
NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-lmargin2", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0},
+ {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-offset", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-overstrike", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, overstrikeString),
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, overstrikeColor),
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-relief", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-rmargin", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0},
+ {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-spacing1", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-spacing2", NULL, NULL,
@@ -84,6 +95,9 @@ static const Tk_OptionSpec tagOptionSpecs[] = {
{TK_OPTION_STRING, "-underline", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, underlineString),
TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_COLOR, "-underlinefg", NULL, NULL,
+ NULL, -1, Tk_Offset(TkTextTag, underlineColor),
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, wrapMode),
TK_OPTION_NULL_OK, wrapStrings, 0},
@@ -229,6 +243,7 @@ TkTextTagCmd(
TkTextSelectionEvent(textPtr);
if (addTag && textPtr->exportSelection
+ && (!Tcl_IsSafe(textPtr->interp))
&& !(textPtr->flags & GOT_SELECTION)) {
Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
TkTextLostSelection, textPtr);
@@ -328,7 +343,7 @@ TkTextTagCmd(
if (tagPtr == NULL) {
return TCL_ERROR;
}
- objPtr = Tk_GetOptionValue(interp, (char *) tagPtr,
+ objPtr = Tk_GetOptionValue(interp, tagPtr,
tagPtr->optionTable, objv[4], textPtr->tkwin);
if (objPtr == NULL) {
return TCL_ERROR;
@@ -347,7 +362,7 @@ TkTextTagCmd(
}
tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag);
if (objc <= 5) {
- Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr,
+ Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, tagPtr,
tagPtr->optionTable,
(objc == 5) ? objv[4] : NULL, textPtr->tkwin);
@@ -359,7 +374,7 @@ TkTextTagCmd(
} else {
int result = TCL_OK;
- if (Tk_SetOptions(interp, (char *) tagPtr, tagPtr->optionTable,
+ if (Tk_SetOptions(interp, tagPtr, tagPtr->optionTable,
objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
@@ -484,10 +499,18 @@ TkTextTagCmd(
*/
if (tagPtr == textPtr->selTagPtr) {
- textPtr->selBorder = tagPtr->border;
+ if (tagPtr->selBorder == NULL) {
+ textPtr->selBorder = tagPtr->border;
+ } else {
+ textPtr->selBorder = tagPtr->selBorder;
+ }
textPtr->selBorderWidth = tagPtr->borderWidth;
textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr;
- textPtr->selFgColorPtr = tagPtr->fgColor;
+ if (tagPtr->selFgColor == NULL) {
+ textPtr->selFgColorPtr = tagPtr->fgColor;
+ } else {
+ textPtr->selFgColorPtr = tagPtr->selFgColor;
+ }
}
tagPtr->affectsDisplay = 0;
@@ -509,12 +532,18 @@ TkTextTagCmd(
tagPtr->affectsDisplayGeometry = 1;
}
if ((tagPtr->border != NULL)
+ || (tagPtr->selBorder != NULL)
|| (tagPtr->reliefString != NULL)
|| (tagPtr->bgStipple != None)
|| (tagPtr->fgColor != NULL)
+ || (tagPtr->selFgColor != NULL)
|| (tagPtr->fgStipple != None)
|| (tagPtr->overstrikeString != NULL)
- || (tagPtr->underlineString != NULL)) {
+ || (tagPtr->overstrikeColor != NULL)
+ || (tagPtr->underlineString != NULL)
+ || (tagPtr->underlineColor != NULL)
+ || (tagPtr->lMarginColor != NULL)
+ || (tagPtr->rMarginColor != NULL)) {
tagPtr->affectsDisplay = 1;
}
if (!newTag) {
@@ -1011,12 +1040,17 @@ TkTextCreateTag(
tagPtr->lMargin1 = 0;
tagPtr->lMargin2String = NULL;
tagPtr->lMargin2 = 0;
+ tagPtr->lMarginColor = NULL;
tagPtr->offsetString = NULL;
tagPtr->offset = 0;
tagPtr->overstrikeString = NULL;
tagPtr->overstrike = 0;
+ tagPtr->overstrikeColor = NULL;
tagPtr->rMarginString = NULL;
tagPtr->rMargin = 0;
+ tagPtr->rMarginColor = NULL;
+ tagPtr->selBorder = NULL;
+ tagPtr->selFgColor = NULL;
tagPtr->spacing1String = NULL;
tagPtr->spacing1 = 0;
tagPtr->spacing2String = NULL;
@@ -1028,6 +1062,7 @@ TkTextCreateTag(
tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
tagPtr->underlineString = NULL;
tagPtr->underline = 0;
+ tagPtr->underlineColor = NULL;
tagPtr->elideString = NULL;
tagPtr->elide = 0;
tagPtr->wrapMode = TEXT_WRAPMODE_NULL;
@@ -1073,10 +1108,10 @@ FindTag(
Tcl_Obj *tagName) /* Name of desired tag. */
{
Tcl_HashEntry *hPtr;
- int len;
+ size_t len;
const char *str;
- str = Tcl_GetStringFromObj(tagName, &len);
+ str = TkGetStringFromObj(tagName, &len);
if (len == 3 && !strcmp(str, "sel")) {
return textPtr->selTagPtr;
}
@@ -1224,8 +1259,7 @@ TkTextFreeTag(
if (textPtr != tagPtr->textPtr) {
Tcl_Panic("Tag being deleted from wrong widget");
}
- textPtr->refCount--;
- if (textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
tagPtr->textPtr = NULL;
@@ -1488,7 +1522,7 @@ TkTextBindProc(
}
done:
- if (--textPtr->refCount == 0) {
+ if (textPtr->refCount-- <= 1) {
ckfree(textPtr);
}
}
@@ -1529,7 +1563,8 @@ TkTextPickCurrent(
TkTextTag **copyArrayPtr = NULL;
/* Initialization needed to prevent compiler
* warning. */
- int numOldTags, numNewTags, i, j, size, nearby;
+ int numOldTags, numNewTags, i, j, nearby;
+ size_t size;
XEvent event;
/*
@@ -1622,7 +1657,7 @@ TkTextPickCurrent(
if (numNewTags > 0) {
size = numNewTags * sizeof(TkTextTag *);
copyArrayPtr = ckalloc(size);
- memcpy(copyArrayPtr, newArrayPtr, (size_t) size);
+ memcpy(copyArrayPtr, newArrayPtr, size);
for (i = 0; i < textPtr->numCurTags; i++) {
for (j = 0; j < numNewTags; j++) {
if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {
diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c
index c9fc20f..79ed1a1 100644
--- a/generic/tkTextWind.c
+++ b/generic/tkTextWind.c
@@ -35,8 +35,8 @@ static const Tk_GeomMgr textGeomType = {
* Macro that determines the size of an embedded window segment:
*/
-#define EW_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \
- + sizeof(TkTextEmbWindow)))
+#define EW_SEG_SIZE (Tk_Offset(TkTextSegment, body) \
+ + sizeof(TkTextEmbWindow))
/*
* Prototypes for functions defined in this file:
@@ -191,7 +191,7 @@ TkTextWindowCmd(
ewPtr->body.ew.tkwin = NULL;
}
- objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew,
+ objPtr = Tk_GetOptionValue(interp, &ewPtr->body.ew,
ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
if (objPtr == NULL) {
return TCL_ERROR;
@@ -233,7 +233,7 @@ TkTextWindowCmd(
ewPtr->body.ew.tkwin = NULL;
}
- objPtr = Tk_GetOptionInfo(interp, (char *) &ewPtr->body.ew,
+ objPtr = Tk_GetOptionInfo(interp, &ewPtr->body.ew,
ewPtr->body.ew.optionTable, (objc == 5) ? objv[4] : NULL,
textPtr->tkwin);
if (objPtr == NULL) {
@@ -403,7 +403,7 @@ EmbWinConfigure(
}
oldWindow = ewPtr->body.ew.tkwin;
- if (Tk_SetOptions(textPtr->interp, (char *) &ewPtr->body.ew,
+ if (Tk_SetOptions(textPtr->interp, &ewPtr->body.ew,
ewPtr->body.ew.optionTable, objc, objv, textPtr->tkwin, NULL,
NULL) != TCL_OK) {
return TCL_ERROR;
diff --git a/generic/tkUndo.c b/generic/tkUndo.c
index 8359e0a..c66905d 100644
--- a/generic/tkUndo.c
+++ b/generic/tkUndo.c
@@ -353,7 +353,7 @@ TkUndoInitStack(
/*
*----------------------------------------------------------------------
*
- * TkUndoSetDepth --
+ * TkUndoSetMaxDepth --
*
* Set the maximum depth of stack.
*
@@ -368,7 +368,7 @@ TkUndoInitStack(
*/
void
-TkUndoSetDepth(
+TkUndoSetMaxDepth(
TkUndoRedoStack *stack, /* An Undo/Redo stack */
int maxdepth) /* The maximum stack depth */
{
@@ -478,6 +478,52 @@ TkUndoFreeStack(
/*
*----------------------------------------------------------------------
*
+ * TkUndoCanRedo --
+ *
+ * Returns true if redo is possible, i.e. if the redo stack is not empty.
+ *
+ * Results:
+ * A boolean.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkUndoCanRedo(
+ TkUndoRedoStack *stack) /* An Undo/Redo stack */
+{
+ return stack->redoStack != NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUndoCanUndo --
+ *
+ * Returns true if undo is possible, i.e. if the undo stack is not empty.
+ *
+ * Results:
+ * A boolean.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkUndoCanUndo(
+ TkUndoRedoStack *stack) /* An Undo/Redo stack */
+{
+ return stack->undoStack != NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkUndoInsertUndoSeparator --
*
* Insert a separator on the undo stack, indicating a border for an
@@ -498,7 +544,7 @@ TkUndoInsertUndoSeparator(
{
if (TkUndoInsertSeparator(&stack->undoStack)) {
stack->depth++;
- TkUndoSetDepth(stack, stack->maxdepth);
+ TkUndoSetMaxDepth(stack, stack->maxdepth);
}
}
diff --git a/generic/tkUndo.h b/generic/tkUndo.h
index e63aac4..490ede9 100644
--- a/generic/tkUndo.h
+++ b/generic/tkUndo.h
@@ -96,9 +96,11 @@ MODULE_SCOPE void TkUndoClearStack(TkUndoAtom **stack);
*/
MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth);
-MODULE_SCOPE void TkUndoSetDepth(TkUndoRedoStack *stack, int maxdepth);
+MODULE_SCOPE void TkUndoSetMaxDepth(TkUndoRedoStack *stack, int maxdepth);
MODULE_SCOPE void TkUndoClearStacks(TkUndoRedoStack *stack);
MODULE_SCOPE void TkUndoFreeStack(TkUndoRedoStack *stack);
+MODULE_SCOPE int TkUndoCanRedo(TkUndoRedoStack *stack);
+MODULE_SCOPE int TkUndoCanUndo(TkUndoRedoStack *stack);
MODULE_SCOPE void TkUndoInsertUndoSeparator(TkUndoRedoStack *stack);
MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command,
Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList);
diff --git a/generic/tkUtil.c b/generic/tkUtil.c
index 7ff9ecb..56d80bc 100644
--- a/generic/tkUtil.c
+++ b/generic/tkUtil.c
@@ -729,11 +729,11 @@ Tk_GetScrollInfoObj(
int *intPtr) /* Filled in with number of pages or lines to
* scroll, if any. */
{
- const char *arg = Tcl_GetString(objv[2]);
- size_t length = objv[2]->length;
+ size_t length;
+ const char *arg = TkGetStringFromObj(objv[2], &length);
#define ArgPfxEq(str) \
- ((arg[0] == str[0]) && !strncmp(arg, str, (unsigned)length))
+ ((arg[0] == str[0]) && !strncmp(arg, str, length))
if (ArgPfxEq("moveto")) {
if (objc != 4) {
@@ -753,8 +753,7 @@ Tk_GetScrollInfoObj(
return TK_SCROLL_ERROR;
}
- arg = Tcl_GetString(objv[4]);
- length = objv[4]->length;
+ arg = TkGetStringFromObj(objv[4], &length);
if (ArgPfxEq("pages")) {
return TK_SCROLL_PAGES;
} else if (ArgPfxEq("units")) {
@@ -1162,7 +1161,8 @@ TkMakeEnsemble(
* TkSendVirtualEvent --
*
* Send a virtual event notification to the specified target window.
- * Equivalent to "event generate $target <<$eventName>>"
+ * Equivalent to:
+ * "event generate $target <<$eventName>> -data $detail"
*
* Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent, so this
* routine does not reenter the interpreter.
@@ -1173,7 +1173,8 @@ TkMakeEnsemble(
void
TkSendVirtualEvent(
Tk_Window target,
- const char *eventName)
+ const char *eventName,
+ Tcl_Obj *detail)
{
union {XEvent general; XVirtualEvent virtual;} event;
@@ -1184,9 +1185,114 @@ TkSendVirtualEvent(
event.general.xany.window = Tk_WindowId(target);
event.general.xany.display = Tk_Display(target);
event.virtual.name = Tk_GetUid(eventName);
+ if (detail != NULL) {
+ event.virtual.user_data = detail;
+ }
Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}
+
+#if TCL_UTF_MAX <= 4
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkUtfToUniChar --
+ *
+ * Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar.
+ * This function is capable of collapsing a upper/lower surrogate pair to a
+ * single unicode character. So, up to 6 bytes might be consumed.
+ *
+ * Results:
+ * *chPtr is filled with the Tcl_UniChar, and the return value is the
+ * number of bytes from the UTF-8 string that were consumed.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+size_t
+TkUtfToUniChar(
+ const char *src, /* The UTF-8 string. */
+ int *chPtr) /* Filled with the Tcl_UniChar represented by
+ * the UTF-8 string. */
+{
+ Tcl_UniChar uniChar = 0;
+
+ size_t len = Tcl_UtfToUniChar(src, &uniChar);
+ if ((uniChar & 0xfc00) == 0xd800) {
+ Tcl_UniChar high = uniChar;
+ /* This can only happen if Tcl is compiled with TCL_UTF_MAX=4,
+ * or when a high surrogate character is detected in UTF-8 form */
+ size_t len2 = Tcl_UtfToUniChar(src+len, &uniChar);
+ if ((uniChar & 0xfc00) == 0xdc00) {
+ *chPtr = (((high & 0x3ff) << 10) | (uniChar & 0x3ff)) + 0x10000;
+ len += len2;
+ } else {
+ *chPtr = high;
+ }
+ } else {
+ *chPtr = uniChar;
+ }
+ return len;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TkUniCharToUtf --
+ *
+ * Almost the same as Tcl_UniCharToUtf but producing surrogates if
+ * TCL_UTF_MAX==3. So, up to 6 bytes might be produced.
+ *
+ * Results:
+ * *buf is filled with the UTF-8 string, and the return value is the
+ * number of bytes produced.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+size_t TkUniCharToUtf(int ch, char *buf)
+{
+ size_t size = Tcl_UniCharToUtf(ch, buf);
+ if ((((unsigned)(ch - 0x10000) <= 0xFFFFF)) && (size < 4)) {
+ /* Hey, this is wrong, we must be running TCL_UTF_MAX==3
+ * The best thing we can do is spit out 2 surrogates */
+ ch -= 0x10000;
+ size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf);
+ size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size);
+ }
+ return size;
+}
+
+
+#endif
+
+#ifndef TCL_TYPE_I
+unsigned char *
+TkGetByteArrayFromObj(
+ Tcl_Obj *objPtr,
+ size_t *lengthPtr
+) {
+ int length;
+
+ unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
+#if TK_MAJOR_VERSION > 8
+ if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
+ /* 64-bit and TIP #494 situation: */
+ *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
+ } else
+#endif
+ /* 32-bit or without TIP #494 */
+ *lengthPtr = (size_t) (unsigned) length;
+ return result;
+}
+#endif /* !TCL_TYPE_I */
+
/*
* Local Variables:
* mode: c
diff --git a/generic/tkVisual.c b/generic/tkVisual.c
index 8b0c155..427e946 100644
--- a/generic/tkVisual.c
+++ b/generic/tkVisual.c
@@ -21,9 +21,9 @@
typedef struct VisualDictionary {
const char *name; /* Textual name of class. */
- int minLength; /* Minimum # characters that must be specified
+ unsigned short minLength; /* Minimum # characters that must be specified
* for an unambiguous match. */
- int class; /* X symbol for class. */
+ short class; /* X symbol for class. */
} VisualDictionary;
static const VisualDictionary visualNames[] = {
{"best", 1, 0},
@@ -46,7 +46,7 @@ static const VisualDictionary visualNames[] = {
struct TkColormap {
Colormap colormap; /* X's identifier for the colormap. */
Visual *visual; /* Visual for which colormap was allocated. */
- int refCount; /* How many uses of the colormap are still
+ size_t refCount; /* How many uses of the colormap are still
* outstanding (calls to Tk_GetColormap minus
* calls to Tk_FreeColormap). */
int shareable; /* 0 means this colormap was allocated by a
@@ -99,7 +99,7 @@ Tk_GetVisual(
XVisualInfo template, *visInfoList, *bestPtr;
long mask;
Visual *visual;
- ptrdiff_t length;
+ size_t length;
int c, numVisuals, prio, bestPrio, i;
const char *p;
const VisualDictionary *dictPtr;
@@ -137,7 +137,7 @@ Tk_GetVisual(
for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
cmapPtr = cmapPtr->nextPtr) {
if (cmapPtr->colormap == *colormapPtr) {
- cmapPtr->refCount += 1;
+ cmapPtr->refCount++;
break;
}
}
@@ -195,8 +195,7 @@ Tk_GetVisual(
template.class = -1;
for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength)
- && (strncmp(string, dictPtr->name,
- (size_t) length) == 0)) {
+ && (strncmp(string, dictPtr->name, length) == 0)) {
template.class = dictPtr->class;
break;
}
@@ -324,7 +323,7 @@ Tk_GetVisual(
cmapPtr = cmapPtr->nextPtr) {
if (cmapPtr->shareable && (cmapPtr->visual == visual)) {
*colormapPtr = cmapPtr->colormap;
- cmapPtr->refCount += 1;
+ cmapPtr->refCount++;
goto done;
}
}
@@ -427,7 +426,7 @@ Tk_GetColormap(
for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
cmapPtr = cmapPtr->nextPtr) {
if (cmapPtr->colormap == colormap) {
- cmapPtr->refCount += 1;
+ cmapPtr->refCount++;
}
}
return colormap;
@@ -476,8 +475,7 @@ Tk_FreeColormap(
for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) {
if (cmapPtr->colormap == colormap) {
- cmapPtr->refCount -= 1;
- if (cmapPtr->refCount == 0) {
+ if (cmapPtr->refCount-- <= 1) {
XFreeColormap(display, colormap);
if (prevPtr == NULL) {
dispPtr->cmapPtr = cmapPtr->nextPtr;
@@ -534,7 +532,7 @@ Tk_PreserveColormap(
for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL;
cmapPtr = cmapPtr->nextPtr) {
if (cmapPtr->colormap == colormap) {
- cmapPtr->refCount += 1;
+ cmapPtr->refCount++;
return;
}
}
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index b5cbbab..d36313b 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -54,12 +54,6 @@ typedef struct ThreadSpecificData {
static Tcl_ThreadDataKey dataKey;
/*
- * The Mutex below is used to lock access to the Tk_Uid structs above.
- */
-
-TCL_DECLARE_MUTEX(windowMutex)
-
-/*
* Default values for "changes" and "atts" fields of TkWindows. Note that Tk
* always requests all events for all windows, except StructureNotify events
* on internal windows: these events are generated internally.
@@ -206,40 +200,6 @@ static const TkCmd commands[] = {
};
/*
- * The variables and table below are used to parse arguments from the "argv"
- * variable in Tk_Init.
- */
-
-static int synchronize = 0;
-static char *name = NULL;
-static char *display = NULL;
-static char *geometry = NULL;
-static char *colormap = NULL;
-static char *use = NULL;
-static char *visual = NULL;
-static int rest = 0;
-
-static const Tk_ArgvInfo argTable[] = {
- {"-colormap", TK_ARGV_STRING, NULL, (char *) &colormap,
- "Colormap for main window"},
- {"-display", TK_ARGV_STRING, NULL, (char *) &display,
- "Display to use"},
- {"-geometry", TK_ARGV_STRING, NULL, (char *) &geometry,
- "Initial geometry for window"},
- {"-name", TK_ARGV_STRING, NULL, (char *) &name,
- "Name to use for application"},
- {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize,
- "Use synchronous mode for display server"},
- {"-visual", TK_ARGV_STRING, NULL, (char *) &visual,
- "Visual for main window"},
- {"-use", TK_ARGV_STRING, NULL, (char *) &use,
- "Id of window in which to embed application"},
- {"--", TK_ARGV_REST, (char *) 1, (char *) &rest,
- "Pass all remaining arguments through to script"},
- {NULL, TK_ARGV_END, NULL, NULL, NULL}
-};
-
-/*
* Forward declarations to functions defined later in this file:
*/
@@ -279,6 +239,8 @@ TkCloseDisplay(
{
TkClipCleanup(dispPtr);
+ TkpCancelWarp(dispPtr);
+
if (dispPtr->name != NULL) {
ckfree(dispPtr->name);
}
@@ -374,6 +336,7 @@ CreateTopLevelWindow(
* Create built-in photo image formats.
*/
+ Tk_CreatePhotoImageFormat(&tkImgFmtDefault);
Tk_CreatePhotoImageFormat(&tkImgFmtGIF);
Tk_CreatePhotoImageFormat(&tkImgFmtPNG);
Tk_CreatePhotoImageFormat(&tkImgFmtPPM);
@@ -395,6 +358,9 @@ CreateTopLevelWindow(
* Set the flags specified in the call.
*/
+#ifdef TK_USE_INPUT_METHODS
+ winPtr->ximGeneration = 0;
+#endif /*TK_USE_INPUT_METHODS*/
winPtr->flags |= flags;
/*
@@ -690,6 +656,7 @@ TkAllocWindow(
winPtr->flags = 0;
winPtr->handlerList = NULL;
#ifdef TK_USE_INPUT_METHODS
+ winPtr->ximGeneration = 0;
winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
winPtr->tagPtr = NULL;
@@ -983,7 +950,7 @@ TkCreateMainWindow(
}
/*
- * Set variables for the intepreter.
+ * Set variables for the interpreter.
*/
Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
@@ -1169,7 +1136,7 @@ Tk_CreateWindowFromPath(
char fixedSpace[FIXED_SPACE+1];
char *p;
Tk_Window parent;
- int numChars;
+ size_t numChars;
/*
* Strip the parent's name out of pathName (it's everything up to the last
@@ -1186,7 +1153,7 @@ Tk_CreateWindowFromPath(
Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
return NULL;
}
- numChars = (int) (p-pathName);
+ numChars = p-pathName;
if (numChars > FIXED_SPACE) {
p = ckalloc(numChars + 1);
} else {
@@ -1196,7 +1163,7 @@ Tk_CreateWindowFromPath(
*p = '.';
p[1] = '\0';
} else {
- strncpy(p, pathName, (size_t) numChars);
+ strncpy(p, pathName, numChars);
p[numChars] = '\0';
}
@@ -1482,10 +1449,11 @@ Tk_DestroyWindow(
UnlinkWindow(winPtr);
TkEventDeadWindow(winPtr);
#ifdef TK_USE_INPUT_METHODS
- if (winPtr->inputContext != NULL) {
+ if (winPtr->inputContext != NULL &&
+ winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
XDestroyIC(winPtr->inputContext);
- winPtr->inputContext = NULL;
}
+ winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
if (winPtr->tagPtr != NULL) {
TkFreeBindingTags(winPtr);
@@ -1519,8 +1487,7 @@ Tk_DestroyWindow(
winPtr->mainPtr->deletionEpoch++;
}
- winPtr->mainPtr->refCount--;
- if (winPtr->mainPtr->refCount == 0) {
+ if (winPtr->mainPtr->refCount-- <= 1) {
register const TkCmd *cmdPtr;
/*
@@ -2391,6 +2358,9 @@ Tk_IdToWindow(
break;
}
}
+ if (window == None) {
+ return NULL;
+ }
hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window);
if (hPtr == NULL) {
@@ -2817,6 +2787,18 @@ DeleteWindowsExitProc(
}
/*
+ * Let error handlers catch up before actual close of displays.
+ * Must be done before tsdPtr->displayList is cleared, otherwise
+ * ErrorProc() in tkError.c cannot associate the pending X errors
+ * to the remaining error handlers.
+ */
+
+ for (dispPtr = tsdPtr->displayList; dispPtr != NULL;
+ dispPtr = dispPtr->nextPtr) {
+ XSync(dispPtr->display, False);
+ }
+
+ /*
* Iterate destroying the displays until no more displays remain. It is
* possible for displays to get recreated during exit by any code that
* calls GetScreen, so we must destroy these new displays as well as the
@@ -3028,22 +3010,57 @@ MODULE_SCOPE const TkStubs tkStubs;
*/
static int
+CopyValue(
+ ClientData dummy,
+ Tcl_Obj *objPtr,
+ void *dstPtr)
+{
+ *(Tcl_Obj **)dstPtr = objPtr;
+ return 1;
+}
+
+static int
Initialize(
Tcl_Interp *interp) /* Interpreter to initialize. */
{
- char *p;
- int argc, code;
- const char **argv;
- const char *args[20];
- const char *argString = NULL;
- Tcl_DString class;
+ int code = TCL_OK;
ThreadSpecificData *tsdPtr;
+ Tcl_Obj *value = NULL;
+ Tcl_Obj *cmd;
+
+ Tcl_Obj *nameObj = NULL;
+ Tcl_Obj *classObj = NULL;
+ Tcl_Obj *displayObj = NULL;
+ Tcl_Obj *colorMapObj = NULL;
+ Tcl_Obj *useObj = NULL;
+ Tcl_Obj *visualObj = NULL;
+ Tcl_Obj *geometryObj = NULL;
+
+ int sync = 0;
+
+ const Tcl_ArgvInfo table[] = {
+ {TCL_ARGV_CONSTANT, "-sync", INT2PTR(1), &sync,
+ "Use synchronous mode for display server", NULL},
+ {TCL_ARGV_FUNC, "-colormap", CopyValue, &colorMapObj,
+ "Colormap for main window", NULL},
+ {TCL_ARGV_FUNC, "-display", CopyValue, &displayObj,
+ "Display to use", NULL},
+ {TCL_ARGV_FUNC, "-geometry", CopyValue, &geometryObj,
+ "Initial geometry for window", NULL},
+ {TCL_ARGV_FUNC, "-name", CopyValue, &nameObj,
+ "Name to use for application", NULL},
+ {TCL_ARGV_FUNC, "-visual", CopyValue, &visualObj,
+ "Visual for main window", NULL},
+ {TCL_ARGV_FUNC, "-use", CopyValue, &useObj,
+ "Id of window in which to embed application", NULL},
+ TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
+ };
/*
* Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
return TCL_ERROR;
}
@@ -3056,23 +3073,6 @@ Initialize(
tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * Start by initializing all the static variables to default acceptable
- * values so that no information is leaked from a previous run of this
- * code.
- */
-
- Tcl_MutexLock(&windowMutex);
- synchronize = 0;
- name = NULL;
- display = NULL;
- geometry = NULL;
- colormap = NULL;
- use = NULL;
- visual = NULL;
- rest = 0;
- argv = NULL;
-
- /*
* We start by resetting the result because it might not be clean.
*/
@@ -3084,8 +3084,6 @@ Initialize(
* master.
*/
- Tcl_DString ds;
-
/*
* Step 1 : find the master and construct the interp name (could be a
* function if new APIs were ok). We could also construct the path
@@ -3095,18 +3093,13 @@ Initialize(
Tcl_Interp *master = interp;
- while (1) {
+ while (Tcl_IsSafe(master)) {
master = Tcl_GetMaster(master);
if (master == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"no controlling master interpreter", -1));
Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_MASTER", NULL);
- code = TCL_ERROR;
- goto done;
- }
- if (!Tcl_IsSafe(master)) {
- /* Found the trusted master. */
- break;
+ return TCL_ERROR;
}
}
@@ -3116,39 +3109,30 @@ Initialize(
code = Tcl_GetInterpPath(master, interp);
if (code != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "error in Tcl_GetInterpPath", -1));
- Tcl_SetErrorCode(interp, "TK", "SAFE", "FAILED", NULL);
- goto done;
+ Tcl_Panic("Tcl_GetInterpPath broken!");
}
/*
- * Build the string to eval.
+ * Build the command to eval in trusted master.
*/
- Tcl_DStringInit(&ds);
- Tcl_DStringAppendElement(&ds, "::safe::TkInit");
- Tcl_DStringAppendElement(&ds, Tcl_GetString(Tcl_GetObjResult(master)));
+ cmd = Tcl_NewListObj(2, NULL);
+ Tcl_ListObjAppendElement(NULL, cmd,
+ Tcl_NewStringObj("::safe::TkInit", -1));
+ Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master));
/*
* Step 2 : Eval in the master. The argument is the *reversed* interp
* path of the slave.
*/
- code = Tcl_EvalEx(master, Tcl_DStringValue(&ds), -1, 0);
+ Tcl_IncrRefCount(cmd);
+ code = Tcl_EvalObjEx(master, cmd, 0);
+ Tcl_DecrRefCount(cmd);
+ Tcl_TransferResult(master, code, interp);
if (code != TCL_OK) {
- /*
- * We might want to transfer the error message or not. We don't.
- * (No API to do it and maybe security reasons).
- */
-
- Tcl_DStringFree(&ds);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "not allowed to start Tk by master's safe::TkInit", -1));
- Tcl_SetErrorCode(interp, "TK", "SAFE", "FAILED", NULL);
- goto done;
+ return code;
}
- Tcl_DStringFree(&ds);
/*
* Use the master's result as argv. Note: We don't use the Obj
@@ -3156,7 +3140,7 @@ Initialize(
* changing the code below.
*/
- argString = Tcl_GetString(Tcl_GetObjResult(master));
+ value = Tcl_GetObjResult(interp);
} else {
/*
* If there is an "argv" variable, get its value, extract out relevant
@@ -3164,50 +3148,67 @@ Initialize(
* that we used.
*/
- argString = Tcl_GetVar2(interp, "argv", NULL, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
}
- if (argString != NULL) {
- char buffer[TCL_INTEGER_SPACE];
- if (Tcl_SplitList(interp, argString, &argc, &argv) != TCL_OK) {
- argError:
+ if (value) {
+ int objc;
+ Tcl_Obj **objv, **rest;
+ Tcl_Obj *parseList = Tcl_NewListObj(1, NULL);
+
+ Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj());
+
+ Tcl_IncrRefCount(value);
+ if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) ||
+ TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) ||
+ TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) {
Tcl_AddErrorInfo(interp,
"\n (processing arguments in argv variable)");
code = TCL_ERROR;
- goto done;
}
- if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv,
- argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS)
- != TCL_OK) {
- goto argError;
+ if (code == TCL_OK) {
+ Tcl_SetVar2Ex(interp, "argv", NULL,
+ Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(interp, "argc", NULL,
+ Tcl_NewIntObj(objc-1), TCL_GLOBAL_ONLY);
+ ckfree(rest);
+ }
+ Tcl_DecrRefCount(parseList);
+ if (code != TCL_OK) {
+ goto done;
}
- p = Tcl_Merge(argc, argv);
- Tcl_SetVar2(interp, "argv", NULL, p, TCL_GLOBAL_ONLY);
- sprintf(buffer, "%d", argc);
- Tcl_SetVar2(interp, "argc", NULL, buffer, TCL_GLOBAL_ONLY);
- ckfree(p);
}
/*
* Figure out the application's name and class.
*/
- Tcl_DStringInit(&class);
- if (name == NULL) {
- int offset;
+ /*
+ * If we got no -name argument, fetch from TkpGetAppName().
+ */
- TkpGetAppName(interp, &class);
- offset = Tcl_DStringLength(&class)+1;
- Tcl_DStringSetLength(&class, offset);
- Tcl_DStringAppend(&class, Tcl_DStringValue(&class), offset-1);
- name = Tcl_DStringValue(&class) + offset;
- } else {
- Tcl_DStringAppend(&class, name, -1);
+ if (nameObj == NULL) {
+ Tcl_DString nameDS;
+
+ Tcl_DStringInit(&nameDS);
+ TkpGetAppName(interp, &nameDS);
+ nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS),
+ Tcl_DStringLength(&nameDS));
+ Tcl_DStringFree(&nameDS);
}
- p = Tcl_DStringValue(&class);
- if (*p) {
- Tcl_UtfToTitle(p);
+ /*
+ * The -class argument is always the ToTitle of the -name
+ */
+
+ {
+ size_t numBytes;
+ const char *bytes = TkGetStringFromObj(nameObj, &numBytes);
+
+ classObj = Tcl_NewStringObj(bytes, numBytes);
+
+ numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
+ Tcl_SetObjLength(classObj, numBytes);
}
/*
@@ -3215,15 +3216,14 @@ Initialize(
* information parsed from argv, if any.
*/
- args[0] = "toplevel";
- args[1] = ".";
- args[2] = "-class";
- args[3] = Tcl_DStringValue(&class);
- argc = 4;
- if (display != NULL) {
- args[argc] = "-screen";
- args[argc+1] = display;
- argc += 2;
+ cmd = Tcl_NewStringObj("toplevel . -class", -1);
+
+ Tcl_ListObjAppendElement(NULL, cmd, classObj);
+ classObj = NULL;
+
+ if (displayObj) {
+ Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", -1));
+ Tcl_ListObjAppendElement(NULL, cmd, displayObj);
/*
* If this is the first application for this process, save the display
@@ -3232,36 +3232,35 @@ Initialize(
*/
if (tsdPtr->numMainWindows == 0) {
- Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY);
}
+ displayObj = NULL;
}
- if (colormap != NULL) {
- args[argc] = "-colormap";
- args[argc+1] = colormap;
- argc += 2;
- colormap = NULL;
+ if (colorMapObj) {
+ Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", -1));
+ Tcl_ListObjAppendElement(NULL, cmd, colorMapObj);
+ colorMapObj = NULL;
}
- if (use != NULL) {
- args[argc] = "-use";
- args[argc+1] = use;
- argc += 2;
- use = NULL;
+ if (useObj) {
+ Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", -1));
+ Tcl_ListObjAppendElement(NULL, cmd, useObj);
+ useObj = NULL;
}
- if (visual != NULL) {
- args[argc] = "-visual";
- args[argc+1] = visual;
- argc += 2;
- visual = NULL;
+ if (visualObj) {
+ Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", -1));
+ Tcl_ListObjAppendElement(NULL, cmd, visualObj);
+ visualObj = NULL;
}
- args[argc] = NULL;
- code = TkCreateFrame(NULL, interp, argc, args, 1, name);
- Tcl_DStringFree(&class);
+ code = TkListCreateFrame(NULL, interp, cmd, 1, nameObj);
+
+ Tcl_DecrRefCount(cmd);
+
if (code != TCL_OK) {
goto done;
}
Tcl_ResetResult(interp);
- if (synchronize) {
+ if (sync) {
XSynchronize(Tk_Display(Tk_MainWindow(interp)), True);
}
@@ -3270,19 +3269,19 @@ Initialize(
* geometry into the "geometry" variable.
*/
- if (geometry != NULL) {
- Tcl_DString buf;
+ if (geometryObj) {
- Tcl_SetVar2(interp, "geometry", NULL, geometry, TCL_GLOBAL_ONLY);
- Tcl_DStringInit(&buf);
- Tcl_DStringAppend(&buf, "wm geometry . ", -1);
- Tcl_DStringAppend(&buf, geometry, -1);
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
- Tcl_DStringFree(&buf);
+ Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY);
+
+ cmd = Tcl_NewStringObj("wm geometry .", -1);
+ Tcl_ListObjAppendElement(NULL, cmd, geometryObj);
+ Tcl_IncrRefCount(cmd);
+ code = Tcl_EvalObjEx(interp, cmd, 0);
+ Tcl_DecrRefCount(cmd);
+ geometryObj = NULL;
if (code != TCL_OK) {
goto done;
}
- geometry = NULL;
}
/*
@@ -3319,10 +3318,6 @@ Initialize(
* console window interpreter.
*/
- Tcl_MutexUnlock(&windowMutex);
- if (argv != NULL) {
- ckfree(argv);
- }
code = TkpInit(interp);
if (code == TCL_OK) {
@@ -3355,12 +3350,10 @@ tkInit", -1, 0);
TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr);
}
- return code;
-
done:
- Tcl_MutexUnlock(&windowMutex);
- if (argv != NULL) {
- ckfree(argv);
+ if (value) {
+ Tcl_DecrRefCount(value);
+ value = NULL;
}
return code;
}
diff --git a/generic/ttk/ttkBlink.c b/generic/ttk/ttkBlink.c
index 706a871..7294f8b 100644
--- a/generic/ttk/ttkBlink.c
+++ b/generic/ttk/ttkBlink.c
@@ -14,7 +14,7 @@
* Add script-level access to configure application-wide blink rate.
*/
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c
index bc44f25..722e034 100644
--- a/generic/ttk/ttkButton.c
+++ b/generic/ttk/ttkButton.c
@@ -4,8 +4,7 @@
* label, button, checkbutton, radiobutton, and menubutton widgets.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -23,6 +22,7 @@ typedef struct
* Text element resources:
*/
Tcl_Obj *textObj;
+ Tcl_Obj *justifyObj;
Tcl_Obj *textVariableObj;
Tcl_Obj *underlineObj;
Tcl_Obj *widthObj;
@@ -56,6 +56,9 @@ typedef struct
static Tk_OptionSpec BaseOptionSpecs[] =
{
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ "left", Tk_Offset(Base,base.justifyObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
{TK_OPTION_STRING, "-text", "text", "Text", "",
Tk_Offset(Base,base.textObj), -1,
0,0,GEOMETRY_CHANGED },
@@ -136,6 +139,15 @@ BaseCleanup(void *recordPtr)
TtkFreeImageSpec(basePtr->base.imageSpec);
}
+static void
+BaseImageChanged(
+ ClientData clientData, int x, int y, int width, int height,
+ int imageWidth, int imageHeight)
+{
+ Base *basePtr = (Base *)clientData;
+ TtkResizeWidget(&basePtr->core);
+}
+
static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
Base *basePtr = recordPtr;
@@ -149,8 +161,8 @@ static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
}
if (basePtr->base.imageObj) {
- imageSpec = TtkGetImageSpec(
- interp, basePtr->core.tkwin, basePtr->base.imageObj);
+ imageSpec = TtkGetImageSpecEx(
+ interp, basePtr->core.tkwin, basePtr->base.imageObj, BaseImageChanged, basePtr);
if (!imageSpec) {
goto error;
}
@@ -480,12 +492,15 @@ static int
CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
{
Checkbutton *checkPtr = recordPtr;
- Ttk_TraceHandle *vt = Ttk_TraceVariable(
- interp, checkPtr->checkbutton.variableObj,
- CheckbuttonVariableChanged, checkPtr);
-
- if (!vt) {
- return TCL_ERROR;
+ Tcl_Obj *varName = checkPtr->checkbutton.variableObj;
+ Ttk_TraceHandle *vt = NULL;
+
+ if (varName != NULL && *Tcl_GetString(varName) != '\0') {
+ vt = Ttk_TraceVariable(interp, varName,
+ CheckbuttonVariableChanged, checkPtr);
+ if (!vt) {
+ return TCL_ERROR;
+ }
}
if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){
@@ -493,7 +508,9 @@ CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
return TCL_ERROR;
}
- Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
+ if (checkPtr->checkbutton.variableTrace) {
+ Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
+ }
checkPtr->checkbutton.variableTrace = vt;
return TCL_OK;
@@ -539,10 +556,13 @@ CheckbuttonInvokeCommand(
else
newValue = checkPtr->checkbutton.onValueObj;
- if (Tcl_ObjSetVar2(interp,
- checkPtr->checkbutton.variableObj, NULL, newValue,
- TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
- == NULL)
+ if (checkPtr->checkbutton.variableObj == NULL ||
+ *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0')
+ CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue));
+ else if (Tcl_ObjSetVar2(interp,
+ checkPtr->checkbutton.variableObj, NULL, newValue,
+ TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
+ == NULL)
return TCL_ERROR;
if (WidgetDestroyed(corePtr))
diff --git a/generic/ttk/ttkCache.c b/generic/ttk/ttkCache.c
index 0ae2372..c29007c 100644
--- a/generic/ttk/ttkCache.c
+++ b/generic/ttk/ttkCache.c
@@ -28,8 +28,7 @@
* but this will be a transient effect.
*/
-#include <stdio.h> /* for sprintf */
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
struct Ttk_ResourceCache_ {
diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c
index 15ebcb7..e9bc74a 100644
--- a/generic/ttk/ttkClamTheme.c
+++ b/generic/ttk/ttkClamTheme.c
@@ -4,11 +4,11 @@
* "clam" theme; inspired by the XFCE family of Gnome themes.
*/
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
-/*
- * Under windows, the Tk-provided XDrawLine and XDrawArc have an
+/*
+ * Under windows, the Tk-provided XDrawLine and XDrawArc have an
* off-by-one error in the end point. This is especially apparent with this
* theme. Defining this macro as true handles this case.
*/
@@ -123,8 +123,8 @@ static Ttk_ElementOptionSpec BorderElementOptions[] = {
/*
* <<NOTE-BORDERWIDTH>>: -borderwidth is only partially supported:
* in this theme, borders are always exactly 2 pixels thick.
- * With -borderwidth 0, border is not drawn at all;
- * otherwise a 2-pixel border is used. For -borderwidth > 2,
+ * With -borderwidth 0, border is not drawn at all;
+ * otherwise a 2-pixel border is used. For -borderwidth > 2,
* the excess is used as padding.
*/
@@ -402,7 +402,7 @@ typedef struct {
static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
{
{ "-arrowsize", TK_OPTION_PIXELS,
- Tk_Offset(MenuIndicatorElement,sizeObj),
+ Tk_Offset(MenuIndicatorElement,sizeObj),
STR(MENUBUTTON_ARROW_SIZE)},
{ "-arrowcolor",TK_OPTION_COLOR,
Tk_Offset(MenuIndicatorElement,colorObj),
@@ -630,7 +630,7 @@ static void ThumbElementDraw(
Tcl_GetIntFromObj(NULL, sb->gripCountObj, &gripCount);
lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d);
darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d);
-
+
if (orient == TTK_ORIENT_HORIZONTAL) {
dx = 1; dy = 0;
x1 = x2 = b.x + b.width / 2 - gripCount;
@@ -710,12 +710,12 @@ static void PbarElementDraw(
Drawable d, Ttk_Box b, unsigned state)
{
ScrollbarElement *sb = elementRecord;
-
+
b = Ttk_PadBox(b, Ttk_UniformPadding(2));
if (b.width > 4 && b.height > 4) {
DrawSmoothBorder(tkwin, d, b,
sb->borderColorObj, sb->lightColorObj, sb->darkColorObj);
- XFillRectangle(Tk_Display(tkwin), d,
+ XFillRectangle(Tk_Display(tkwin), d,
BackgroundGC(tkwin, sb->backgroundObj),
b.x+2, b.y+2, b.width-4, b.height-4);
}
@@ -780,8 +780,8 @@ static Ttk_ElementSpec ArrowElementSpec = {
/*------------------------------------------------------------------------
* +++ Notebook elements.
- *
- * Note: Tabs, except for the rightmost, overlap the neighbor to
+ *
+ * Note: Tabs, except for the rightmost, overlap the neighbor to
* their right by one pixel.
*/
diff --git a/generic/ttk/ttkClassicTheme.c b/generic/ttk/ttkClassicTheme.c
index 2fbcd76..117d928 100644
--- a/generic/ttk/ttkClassicTheme.c
+++ b/generic/ttk/ttkClassicTheme.c
@@ -5,7 +5,7 @@
*
*/
-#include <tk.h>
+#include "tkInt.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "ttkTheme.h"
@@ -68,7 +68,7 @@ static Ttk_ElementSpec HighlightElementSpec =
/*------------------------------------------------------------------------
* +++ Button Border element:
- *
+ *
* The Motif-style button border on X11 consists of (from outside-in):
*
* + focus indicator (controlled by -highlightcolor and -highlightthickness),
@@ -85,13 +85,13 @@ typedef struct {
static Ttk_ElementOptionSpec ButtonBorderElementOptions[] =
{
- { "-background", TK_OPTION_BORDER,
+ { "-background", TK_OPTION_BORDER,
Tk_Offset(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND },
- { "-borderwidth", TK_OPTION_PIXELS,
+ { "-borderwidth", TK_OPTION_PIXELS,
Tk_Offset(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
- { "-relief", TK_OPTION_RELIEF,
+ { "-relief", TK_OPTION_RELIEF,
Tk_Offset(ButtonBorderElement,reliefObj), "flat" },
- { "-default", TK_OPTION_ANY,
+ { "-default", TK_OPTION_ANY,
Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" },
{ NULL, 0, 0, NULL }
};
@@ -115,7 +115,7 @@ static void ButtonBorderElementSize(
/*
* (@@@ Note: ButtonBorderElement still still still buggy:
- * padding for default ring is drawn in the wrong color
+ * padding for default ring is drawn in the wrong color
* when the button is active.)
*/
static void ButtonBorderElementDraw(
@@ -281,19 +281,19 @@ static Ttk_ElementSpec ArrowElementSpec =
/*------------------------------------------------------------------------
* +++ Sash element (for ttk::panedwindow)
*
- * NOTES:
+ * NOTES:
*
* panedwindows with -orient horizontal use vertical sashes, and vice versa.
*
* Interpretation of -sashrelief 'groove' and 'ridge' are
* swapped wrt. the core panedwindow, which (I think) has them backwards.
*
- * Default -sashrelief is sunken; the core panedwindow has default
+ * Default -sashrelief is sunken; the core panedwindow has default
* -sashrelief raised, but that looks wrong to me.
*/
static Ttk_Orient SashClientData[] = {
- TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL
+ TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL
};
typedef struct {
@@ -306,13 +306,13 @@ typedef struct {
} SashElement;
static Ttk_ElementOptionSpec SashOptions[] = {
- { "-background", TK_OPTION_BORDER,
+ { "-background", TK_OPTION_BORDER,
Tk_Offset(SashElement,borderObj), DEFAULT_BACKGROUND },
- { "-sashrelief", TK_OPTION_RELIEF,
+ { "-sashrelief", TK_OPTION_RELIEF,
Tk_Offset(SashElement,sashReliefObj), "sunken" },
{ "-sashthickness", TK_OPTION_PIXELS,
Tk_Offset(SashElement,sashThicknessObj), "6" },
- { "-sashpad", TK_OPTION_PIXELS,
+ { "-sashpad", TK_OPTION_PIXELS,
Tk_Offset(SashElement,sashPadObj), "2" },
{ "-handlesize", TK_OPTION_PIXELS,
Tk_Offset(SashElement,handleSizeObj), "8" },
@@ -367,10 +367,10 @@ static void SashElementDraw(
gc1 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
break;
- case TK_RELIEF_SOLID:
+ case TK_RELIEF_SOLID:
gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
break;
- case TK_RELIEF_FLAT:
+ case TK_RELIEF_FLAT:
default:
gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
break;
@@ -398,7 +398,7 @@ static void SashElementDraw(
hb = Ttk_StickBox(b, handleSize, handleSize, TTK_STICK_N);
hb.y += handlePad;
}
- Tk_Fill3DRectangle(tkwin, d, border,
+ Tk_Fill3DRectangle(tkwin, d, border,
hb.x, hb.y, hb.width, hb.height, 1, TK_RELIEF_RAISED);
}
}
@@ -495,7 +495,7 @@ MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
Ttk_RegisterElement(interp, theme, "arrow",
&ArrowElementSpec, &ArrowElements[0]);
- Ttk_RegisterElement(interp, theme, "hsash",
+ Ttk_RegisterElement(interp, theme, "hsash",
&SashElementSpec, &SashClientData[0]);
Ttk_RegisterElement(interp, theme, "vsash",
&SashElementSpec, &SashClientData[1]);
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
index 81f8126..2118704 100644
--- a/generic/ttk/ttkDefaultTheme.c
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -4,10 +4,7 @@
* Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme
*/
-#include <math.h>
-#include <string.h>
-
-#include <tkInt.h>
+#include "tkInt.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "ttkTheme.h"
@@ -209,6 +206,9 @@ void TtkFillArrow(
ArrowPoints(b, dir, points);
XFillPolygon(display, d, gc, points, 3, Convex, CoordModeOrigin);
XDrawLines(display, d, gc, points, 4, CoordModeOrigin);
+
+ /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */
+ XDrawPoint(display, d, gc, points[2].x, points[2].y);
}
/*public*/
@@ -218,6 +218,9 @@ void TtkDrawArrow(
XPoint points[4];
ArrowPoints(b, dir, points);
XDrawLines(display, d, gc, points, 4, CoordModeOrigin);
+
+ /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */
+ XDrawPoint(display, d, gc, points[2].x, points[2].y);
}
/*
@@ -680,7 +683,7 @@ typedef struct {
Tcl_Obj *colorObj;
} MenubuttonArrowElement;
-static const char *directionStrings[] = { /* See also: button.c */
+static const char *const directionStrings[] = { /* See also: button.c */
"above", "below", "left", "right", "flush", NULL
};
enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH };
diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c
index 5c95dba..4dd2adb 100644
--- a/generic/ttk/ttkElements.c
+++ b/generic/ttk/ttkElements.c
@@ -5,9 +5,7 @@
*
*/
-#include <tcl.h>
-#include <tk.h>
-#include <string.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c
index f395649..e5268e7 100644
--- a/generic/ttk/ttkEntry.c
+++ b/generic/ttk/ttkEntry.c
@@ -8,9 +8,7 @@
* Copyright (c) 2004 Joe English
*/
-#include <string.h>
-#include <stdio.h>
-#include <tkInt.h>
+#include "tkInt.h"
#include <X11/Xatom.h>
#include "ttkTheme.h"
@@ -73,6 +71,7 @@ static const char *const validateReasonStrings[] = {
/* Style parameters:
*/
typedef struct {
+ Tcl_Obj *placeholderForegroundObj;/* Foreground color for placeholder text */
Tcl_Obj *foregroundObj; /* Foreground color for normal text */
Tcl_Obj *backgroundObj; /* Entry widget background color */
Tcl_Obj *selBorderObj; /* Border and background for selection */
@@ -118,6 +117,8 @@ typedef struct {
Tcl_Obj *stateObj; /* Compatibility option -- see CheckStateObj */
+ Tcl_Obj *placeholderObj; /* Text to display for placeholder text */
+
/*
* Derived resources:
*/
@@ -147,12 +148,13 @@ typedef struct {
/*
* Default option values:
*/
-#define DEF_SELECT_BG "#000000"
-#define DEF_SELECT_FG "#ffffff"
-#define DEF_INSERT_BG "black"
-#define DEF_ENTRY_WIDTH "20"
-#define DEF_ENTRY_FONT "TkTextFont"
-#define DEF_LIST_HEIGHT "10"
+#define DEF_SELECT_BG "#000000"
+#define DEF_SELECT_FG "#ffffff"
+#define DEF_PLACEHOLDER_FG "#b3b3b3"
+#define DEF_INSERT_BG "black"
+#define DEF_ENTRY_WIDTH "20"
+#define DEF_ENTRY_FONT "TkTextFont"
+#define DEF_LIST_HEIGHT "10"
static Tk_OptionSpec EntryOptionSpecs[] = {
{TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
@@ -167,6 +169,9 @@ static Tk_OptionSpec EntryOptionSpecs[] = {
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
"left", -1, Tk_Offset(Entry, entry.justify),
0, 0, GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
+ NULL, Tk_Offset(Entry, entry.placeholderObj), -1,
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-show", "show", "Show",
NULL, -1, Tk_Offset(Entry, entry.showChar),
TK_OPTION_NULL_OK, 0, 0},
@@ -191,11 +196,15 @@ static Tk_OptionSpec EntryOptionSpecs[] = {
/* EntryStyleData options:
*/
+ {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
+ NULL, Tk_Offset(Entry, entry.styleData.backgroundObj), -1,
+ TK_OPTION_NULL_OK,0,0},
{TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
NULL, Tk_Offset(Entry, entry.styleData.foregroundObj), -1,
TK_OPTION_NULL_OK,0,0},
- {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
- NULL, Tk_Offset(Entry, entry.styleData.backgroundObj), -1,
+ {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
+ "PlaceholderForeground", NULL,
+ Tk_Offset(Entry, entry.styleData.placeholderForegroundObj), -1,
TK_OPTION_NULL_OK,0,0},
WIDGET_TAKEFOCUS_TRUE,
@@ -216,6 +225,7 @@ static void EntryInitStyleDefaults(EntryStyleData *es)
#define INIT(member, value) \
es->member = Tcl_NewStringObj(value, -1); \
Tcl_IncrRefCount(es->member);
+ INIT(placeholderForegroundObj, DEF_PLACEHOLDER_FG)
INIT(foregroundObj, DEFAULT_FOREGROUND)
INIT(selBorderObj, DEF_SELECT_BG)
INIT(selForegroundObj, DEF_SELECT_FG)
@@ -227,6 +237,7 @@ static void EntryInitStyleDefaults(EntryStyleData *es)
static void EntryFreeStyleDefaults(EntryStyleData *es)
{
+ Tcl_DecrRefCount(es->placeholderForegroundObj);
Tcl_DecrRefCount(es->foregroundObj);
Tcl_DecrRefCount(es->selBorderObj);
Tcl_DecrRefCount(es->selForegroundObj);
@@ -253,6 +264,7 @@ static void EntryInitStyleData(Entry *entryPtr, EntryStyleData *es)
# define INIT(member, name) \
if ((tmp=Ttk_QueryOption(entryPtr->core.layout,name,state))) \
es->member=tmp;
+ INIT(placeholderForegroundObj, "-placeholderforeground");
INIT(foregroundObj, "-foreground");
INIT(selBorderObj, "-selectbackground")
INIT(selBorderWidthObj, "-selectborderwidth")
@@ -263,6 +275,7 @@ static void EntryInitStyleData(Entry *entryPtr, EntryStyleData *es)
/* Reacquire color & border resources from resource cache.
*/
+ es->placeholderForegroundObj = Ttk_UseColor(cache, tkwin, es->placeholderForegroundObj);
es->foregroundObj = Ttk_UseColor(cache, tkwin, es->foregroundObj);
es->selForegroundObj = Ttk_UseColor(cache, tkwin, es->selForegroundObj);
es->insertColorObj = Ttk_UseColor(cache, tkwin, es->insertColorObj);
@@ -282,15 +295,16 @@ static char *EntryDisplayString(const char *showChar, int numChars)
{
char *displayString, *p;
int size;
- Tcl_UniChar ch;
- char buf[TCL_UTF_MAX];
+ int ch;
+ char buf[6];
- Tcl_UtfToUniChar(showChar, &ch);
- size = Tcl_UniCharToUtf(ch, buf);
+ TkUtfToUniChar(showChar, &ch);
+ size = TkUniCharToUtf(ch, buf);
p = displayString = ckalloc(numChars * size + 1);
while (numChars--) {
- p += Tcl_UniCharToUtf(ch, p);
+ memcpy(p, buf, size);
+ p += size;
}
*p = '\0';
@@ -303,12 +317,23 @@ static char *EntryDisplayString(const char *showChar, int numChars)
*/
static void EntryUpdateTextLayout(Entry *entryPtr)
{
+ size_t length;
+ char *text;
Tk_FreeTextLayout(entryPtr->entry.textLayout);
- entryPtr->entry.textLayout = Tk_ComputeTextLayout(
+ if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) {
+ entryPtr->entry.textLayout = Tk_ComputeTextLayout(
Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
entryPtr->entry.displayString, entryPtr->entry.numChars,
0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
&entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
+ } else {
+ text = TkGetStringFromObj(entryPtr->entry.placeholderObj, &length);
+ entryPtr->entry.textLayout = Tk_ComputeTextLayout(
+ Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj),
+ text, length,
+ 0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES,
+ &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight);
+ }
}
/* EntryEditable --
@@ -336,7 +361,8 @@ EntryFetchSelection(
const char *string;
const char *selStart, *selEnd;
- if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) {
+ if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection)
+ || Tcl_IsSafe(entryPtr->core.interp)) {
return -1;
}
string = entryPtr->entry.displayString;
@@ -371,11 +397,12 @@ static void EntryLostSelection(ClientData clientData)
/* EntryOwnSelection --
* Assert ownership of the PRIMARY selection,
- * if -exportselection set and selection is present.
+ * if -exportselection set and selection is present and interp is unsafe.
*/
static void EntryOwnSelection(Entry *entryPtr)
{
if (entryPtr->entry.exportSelection
+ && (!Tcl_IsSafe(entryPtr->core.interp))
&& !(entryPtr->core.flags & GOT_SELECTION)) {
Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection,
(ClientData) entryPtr);
@@ -405,7 +432,7 @@ ExpandPercents(
int number, length;
const char *string;
int stringLength;
- Tcl_UniChar ch;
+ int ch;
char numStorage[2*TCL_INTEGER_SPACE];
while (*template) {
@@ -429,7 +456,7 @@ ExpandPercents(
*/
++template; /* skip over % */
if (*template != '\0') {
- template += Tcl_UtfToUniChar(template, &ch);
+ template += TkUtfToUniChar(template, &ch);
} else {
ch = '%';
}
@@ -479,7 +506,7 @@ ExpandPercents(
string = Tk_PathName(entryPtr->core.tkwin);
break;
default:
- length = Tcl_UniCharToUtf(ch, numStorage);
+ length = TkUniCharToUtf(ch, numStorage);
numStorage[length] = '\0';
string = numStorage;
break;
@@ -558,7 +585,7 @@ static int EntryNeedsValidation(VMODE vmode, VREASON reason)
* Returns:
* TCL_OK if the change is accepted
* TCL_BREAK if the change is rejected
- * TCL_ERROR if any errors occured
+ * TCL_ERROR if any errors occurred
*
* The change will be rejected if -validatecommand returns 0,
* or if -validatecommand or -invalidcommand modifies the value.
@@ -998,7 +1025,8 @@ static int EntryConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
/* Claim the selection, in case we've suddenly started exporting it.
*/
- if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) {
+ if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1)
+ && (!Tcl_IsSafe(entryPtr->core.interp))) {
EntryOwnSelection(entryPtr);
}
@@ -1174,6 +1202,7 @@ static void EntryDisplay(void *clientData, Drawable d)
Ttk_Box textarea;
TkRegion clipRegion;
XRectangle rect;
+ Tcl_Obj *foregroundObj;
EntryInitStyleData(entryPtr, &es);
@@ -1240,6 +1269,7 @@ static void EntryDisplay(void *clientData, Drawable d)
/* Draw cursor:
*/
if (showCursor) {
+ Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field");
int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos),
cursorY = entryPtr->entry.layoutY,
cursorHeight = entryPtr->entry.layoutHeight,
@@ -1253,16 +1283,36 @@ static void EntryDisplay(void *clientData, Drawable d)
/* @@@ should: maybe: SetCaretPos even when blinked off */
Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight);
- gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion);
+ cursorX -= cursorWidth/2;
+ if (cursorX < field.x) {
+ cursorX = field.x;
+ } else if (cursorX + cursorWidth > field.x + field.width) {
+ cursorX = field.x + field.width - cursorWidth;
+ }
+
+ gc = EntryGetGC(entryPtr, es.insertColorObj, None);
XFillRectangle(Tk_Display(tkwin), d, gc,
- cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight);
- XSetClipMask(Tk_Display(tkwin), gc, None);
+ cursorX, cursorY, cursorWidth, cursorHeight);
Tk_FreeGC(Tk_Display(tkwin), gc);
}
/* Draw the text:
*/
- gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion);
+ if ((*(entryPtr->entry.displayString) == '\0')
+ && (entryPtr->entry.placeholderObj != NULL)) {
+ /* No text displayed, but -placeholder is given */
+ if (Tcl_GetCharLength(es.placeholderForegroundObj) > 0) {
+ foregroundObj = es.placeholderForegroundObj;
+ } else {
+ foregroundObj = es.foregroundObj;
+ }
+ /* Use placeholder text width */
+ leftIndex = 0;
+ Tcl_GetStringFromObj(entryPtr->entry.placeholderObj,&rightIndex);
+ } else {
+ foregroundObj = es.foregroundObj;
+ }
+ gc = EntryGetGC(entryPtr, foregroundObj, clipRegion);
Tk_DrawTextLayout(
Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
entryPtr->entry.layoutX, entryPtr->entry.layoutY,
@@ -1314,8 +1364,8 @@ EntryIndex(
int *indexPtr) /* Return value */
{
# define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
- const char *string = Tcl_GetString(indexObj);
- size_t length = indexObj->length;
+ size_t length;
+ const char *string = TkGetStringFromObj(indexObj, &length);
if (strncmp(string, "end", length) == 0) {
*indexPtr = entryPtr->entry.numChars;
diff --git a/generic/ttk/ttkFrame.c b/generic/ttk/ttkFrame.c
index 3e50a7f..10106eb 100644
--- a/generic/ttk/ttkFrame.c
+++ b/generic/ttk/ttkFrame.c
@@ -4,8 +4,7 @@
* ttk::frame and ttk::labelframe widgets.
*/
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"
diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl
deleted file mode 100644
index 56ba2fa..0000000
--- a/generic/ttk/ttkGenStubs.tcl
+++ /dev/null
@@ -1,965 +0,0 @@
-# ttkGenStubs.tcl --
-#
-# This script generates a set of stub files for a given
-# interface.
-#
-#
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# SOURCE: tcl/tools/genStubs.tcl, revision 1.44
-#
-# CHANGES:
-# + Second argument to "declare" is used as a status guard
-# instead of a platform guard.
-# + Allow trailing semicolon in function declarations
-#
-
-package require Tcl 8.4
-
-namespace eval genStubs {
- # libraryName --
- #
- # The name of the entire library. This value is used to compute
- # the USE_*_STUBS macro and the name of the init file.
-
- variable libraryName "UNKNOWN"
-
- # interfaces --
- #
- # An array indexed by interface name that is used to maintain
- # the set of valid interfaces. The value is empty.
-
- array set interfaces {}
-
- # curName --
- #
- # The name of the interface currently being defined.
-
- variable curName "UNKNOWN"
-
- # scspec --
- #
- # Storage class specifier for external function declarations.
- # Normally "EXTERN", may be set to something like XYZAPI
- #
- variable scspec "EXTERN"
-
- # epoch, revision --
- #
- # The epoch and revision numbers of the interface currently being defined.
- # (@@@TODO: should be an array mapping interface names -> numbers)
- #
-
- variable epoch {}
- variable revision 0
-
- # hooks --
- #
- # An array indexed by interface name that contains the set of
- # subinterfaces that should be defined for a given interface.
-
- array set hooks {}
-
- # stubs --
- #
- # This three dimensional array is indexed first by interface name,
- # second by field name, and third by a numeric offset or the
- # constant "lastNum". The lastNum entry contains the largest
- # numeric offset used for a given interface.
- #
- # Field "decl,$i" contains the C function specification that
- # should be used for the given entry in the stub table. The spec
- # consists of a list in the form returned by parseDecl.
- # Other fields TBD later.
-
- array set stubs {}
-
- # outDir --
- #
- # The directory where the generated files should be placed.
-
- variable outDir .
-}
-
-# genStubs::library --
-#
-# This function is used in the declarations file to set the name
-# of the library that the interfaces are associated with (e.g. "tcl").
-# This value will be used to define the inline conditional macro.
-#
-# Arguments:
-# name The library name.
-#
-# Results:
-# None.
-
-proc genStubs::library {name} {
- variable libraryName $name
-}
-
-# genStubs::interface --
-#
-# This function is used in the declarations file to set the name
-# of the interface currently being defined.
-#
-# Arguments:
-# name The name of the interface.
-#
-# Results:
-# None.
-
-proc genStubs::interface {name} {
- variable curName $name
- variable interfaces
- variable stubs
-
- set interfaces($name) {}
- set stubs($name,lastNum) 0
- return
-}
-
-# genStubs::scspec --
-#
-# Define the storage class macro used for external function declarations.
-# Typically, this will be a macro like XYZAPI or EXTERN that
-# expands to either DLLIMPORT or DLLEXPORT, depending on whether
-# -DBUILD_XYZ has been set.
-#
-proc genStubs::scspec {value} {
- variable scspec $value
-}
-
-# genStubs::epoch --
-#
-# Define the epoch number for this library. The epoch
-# should be incrememented when a release is made that
-# contains incompatible changes to the public API.
-#
-proc genStubs::epoch {value} {
- variable epoch $value
-}
-
-# genStubs::hooks --
-#
-# This function defines the subinterface hooks for the current
-# interface.
-#
-# Arguments:
-# names The ordered list of interfaces that are reachable through the
-# hook vector.
-#
-# Results:
-# None.
-
-proc genStubs::hooks {names} {
- variable curName
- variable hooks
-
- set hooks($curName) $names
- return
-}
-
-# genStubs::declare --
-#
-# This function is used in the declarations file to declare a new
-# interface entry.
-#
-# Arguments:
-# index The index number of the interface.
-# status Status of the interface: one of "current",
-# "deprecated", or "obsolete".
-# decl The C function declaration, or {} for an undefined
-# entry.
-#
-# Results:
-# None.
-
-proc genStubs::declare {args} {
- variable stubs
- variable curName
- variable revision
-
- incr revision
- if {[llength $args] == 2} {
- lassign $args index decl
- set status current
- } elseif {[llength $args] == 3} {
- lassign $args index status decl
- } else {
- puts stderr "wrong # args: declare $args"
- return
- }
-
- # Check for duplicate declarations, then add the declaration and
- # bump the lastNum counter if necessary.
-
- if {[info exists stubs($curName,decl,$index)]} {
- puts stderr "Duplicate entry: $index"
- }
- regsub -all "\[ \t\n\]+" [string trim $decl] " " decl
- set decl [parseDecl $decl]
-
- set stubs($curName,status,$index) $status
- set stubs($curName,decl,$index) $decl
-
- if {$index > $stubs($curName,lastNum)} {
- set stubs($curName,lastNum) $index
- }
- return
-}
-
-# genStubs::export --
-#
-# This function is used in the declarations file to declare a symbol
-# that is exported from the library but is not in the stubs table.
-#
-# Arguments:
-# decl The C function declaration, or {} for an undefined
-# entry.
-#
-# Results:
-# None.
-
-proc genStubs::export {args} {
- if {[llength $args] != 1} {
- puts stderr "wrong # args: export $args"
- }
- return
-}
-
-# genStubs::rewriteFile --
-#
-# This function replaces the machine generated portion of the
-# specified file with new contents. It looks for the !BEGIN! and
-# !END! comments to determine where to place the new text.
-#
-# Arguments:
-# file The name of the file to modify.
-# text The new text to place in the file.
-#
-# Results:
-# None.
-
-proc genStubs::rewriteFile {file text} {
- if {![file exists $file]} {
- puts stderr "Cannot find file: $file"
- return
- }
- set in [open ${file} r]
- set out [open ${file}.new w]
- fconfigure $out -translation lf
-
- while {![eof $in]} {
- set line [gets $in]
- if {[string match "*!BEGIN!*" $line]} {
- break
- }
- puts $out $line
- }
- puts $out "/* !BEGIN!: Do not edit below this line. */"
- puts $out $text
- while {![eof $in]} {
- set line [gets $in]
- if {[string match "*!END!*" $line]} {
- break
- }
- }
- puts $out "/* !END!: Do not edit above this line. */"
- puts -nonewline $out [read $in]
- close $in
- close $out
- file rename -force ${file}.new ${file}
- return
-}
-
-# genStubs::addPlatformGuard --
-#
-# Wrap a string inside a platform #ifdef.
-#
-# Arguments:
-# plat Platform to test.
-#
-# Results:
-# Returns the original text inside an appropriate #ifdef.
-
-proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} {
- set text ""
- switch $plat {
- win {
- append text "#ifdef _WIN32 /* WIN */\n${iftxt}"
- if {$eltxt ne ""} {
- append text "#else /* WIN */\n${eltxt}"
- }
- append text "#endif /* WIN */\n"
- }
- unix {
- append text "#if !defined(_WIN32) && !defined(MAC_OSX_TCL)\
- /* UNIX */\n${iftxt}"
- if {$eltxt ne ""} {
- append text "#else /* UNIX */\n${eltxt}"
- }
- append text "#endif /* UNIX */\n"
- }
- macosx {
- append text "#ifdef MAC_OSX_TCL /* MACOSX */\n${iftxt}"
- if {$eltxt ne ""} {
- append text "#else /* MACOSX */\n${eltxt}"
- }
- append text "#endif /* MACOSX */\n"
- }
- aqua {
- append text "#ifdef MAC_OSX_TK /* AQUA */\n${iftxt}"
- if {$eltxt ne ""} {
- append text "#else /* AQUA */\n${eltxt}"
- }
- append text "#endif /* AQUA */\n"
- }
- x11 {
- append text "#if !(defined(_WIN32) || defined(MAC_OSX_TK))\
- /* X11 */\n${iftxt}"
- if {$eltxt ne ""} {
- append text "#else /* X11 */\n${eltxt}"
- }
- append text "#endif /* X11 */\n"
- }
- default {
- append text "${iftxt}${eltxt}"
- }
- }
- return $text
-}
-
-# genStubs::emitSlots --
-#
-# Generate the stub table slots for the given interface. If there
-# are no generic slots, then one table is generated for each
-# platform, otherwise one table is generated for all platforms.
-#
-# Arguments:
-# name The name of the interface being emitted.
-# textVar The variable to use for output.
-#
-# Results:
-# None.
-
-proc genStubs::emitSlots {name textVar} {
- upvar $textVar text
-
- forAllStubs $name makeSlot noGuard text {" void (*reserved$i)(void);\n"}
- return
-}
-
-# genStubs::parseDecl --
-#
-# Parse a C function declaration into its component parts.
-#
-# Arguments:
-# decl The function declaration.
-#
-# Results:
-# Returns a list of the form {returnType name args}. The args
-# element consists of a list of type/name pairs, or a single
-# element "void". If the function declaration is malformed
-# then an error is displayed and the return value is {}.
-
-proc genStubs::parseDecl {decl} {
- if {![regexp {^(.*)\((.*)\);?$} $decl all prefix args]} {
- set prefix $decl
- set args {}
- }
- set prefix [string trim $prefix]
- if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} {
- puts stderr "Bad return type: $decl"
- return
- }
- set rtype [string trim $rtype]
- if {$args eq ""} {
- return [list $rtype $fname {}]
- }
- foreach arg [split $args ,] {
- lappend argList [string trim $arg]
- }
- if {![string compare [lindex $argList end] "..."]} {
- set args TCL_VARARGS
- foreach arg [lrange $argList 0 end-1] {
- set argInfo [parseArg $arg]
- if {[llength $argInfo] == 2 || [llength $argInfo] == 3} {
- lappend args $argInfo
- } else {
- puts stderr "Bad argument: '$arg' in '$decl'"
- return
- }
- }
- } else {
- set args {}
- foreach arg $argList {
- set argInfo [parseArg $arg]
- if {![string compare $argInfo "void"]} {
- lappend args "void"
- break
- } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} {
- lappend args $argInfo
- } else {
- puts stderr "Bad argument: '$arg' in '$decl'"
- return
- }
- }
- }
- return [list $rtype $fname $args]
-}
-
-# genStubs::parseArg --
-#
-# This function parses a function argument into a type and name.
-#
-# Arguments:
-# arg The argument to parse.
-#
-# Results:
-# Returns a list of type and name with an optional third array
-# indicator. If the argument is malformed, returns "".
-
-proc genStubs::parseArg {arg} {
- if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} {
- if {$arg eq "void"} {
- return $arg
- } else {
- return
- }
- }
- set result [list [string trim $type] $name]
- if {$array ne ""} {
- lappend result $array
- }
- return $result
-}
-
-# genStubs::makeDecl --
-#
-# Generate the prototype for a function.
-#
-# Arguments:
-# name The interface name.
-# decl The function declaration.
-# index The slot index for this function.
-#
-# Results:
-# Returns the formatted declaration string.
-
-proc genStubs::makeDecl {name decl index} {
- variable scspec
- lassign $decl rtype fname args
-
- append text "/* $index */\n"
- set line "$scspec $rtype"
- set count [expr {2 - ([string length $line] / 8)}]
- append line [string range "\t\t\t" 0 $count]
- set pad [expr {24 - [string length $line]}]
- if {$pad <= 0} {
- append line " "
- set pad 0
- }
- if {$args eq ""} {
- append line $fname
- append text $line
- append text ";\n"
- return $text
- }
- append line $fname
-
- set arg1 [lindex $args 0]
- switch -exact $arg1 {
- void {
- append line "(void)"
- }
- TCL_VARARGS {
- set sep "("
- foreach arg [lrange $args 1 end] {
- append line $sep
- set next {}
- append next [lindex $arg 0]
- if {[string index $next end] ne "*"} {
- append next " "
- }
- append next [lindex $arg 1] [lindex $arg 2]
- if {[string length $line] + [string length $next] \
- + $pad > 76} {
- append text [string trimright $line] \n
- set line "\t\t\t\t"
- set pad 28
- }
- append line $next
- set sep ", "
- }
- append line ", ...)"
- }
- default {
- set sep "("
- foreach arg $args {
- append line $sep
- set next {}
- append next [lindex $arg 0]
- if {[string index $next end] ne "*"} {
- append next " "
- }
- append next [lindex $arg 1] [lindex $arg 2]
- if {[string length $line] + [string length $next] \
- + $pad > 76} {
- append text [string trimright $line] \n
- set line "\t\t\t\t"
- set pad 28
- }
- append line $next
- set sep ", "
- }
- append line ")"
- }
- }
- return "$text$line;\n"
-}
-
-# genStubs::makeMacro --
-#
-# Generate the inline macro for a function.
-#
-# Arguments:
-# name The interface name.
-# decl The function declaration.
-# index The slot index for this function.
-#
-# Results:
-# Returns the formatted macro definition.
-
-proc genStubs::makeMacro {name decl index} {
- lassign $decl rtype fname args
-
- set lfname [string tolower [string index $fname 0]]
- append lfname [string range $fname 1 end]
-
- set text "#define $fname \\\n\t("
- if {$args eq ""} {
- append text "*"
- }
- append text "${name}StubsPtr->$lfname)"
- append text " /* $index */\n"
- return $text
-}
-
-# genStubs::makeSlot --
-#
-# Generate the stub table entry for a function.
-#
-# Arguments:
-# name The interface name.
-# decl The function declaration.
-# index The slot index for this function.
-#
-# Results:
-# Returns the formatted table entry.
-
-proc genStubs::makeSlot {name decl index} {
- lassign $decl rtype fname args
-
- set lfname [string tolower [string index $fname 0]]
- append lfname [string range $fname 1 end]
-
- set text " "
- if {$args eq ""} {
- append text $rtype " *" $lfname "; /* $index */\n"
- return $text
- }
- if {[string range $rtype end-8 end] eq "__stdcall"} {
- append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") "
- } else {
- append text $rtype " (*" $lfname ") "
- }
- set arg1 [lindex $args 0]
- switch -exact $arg1 {
- void {
- append text "(void)"
- }
- TCL_VARARGS {
- set sep "("
- foreach arg [lrange $args 1 end] {
- append text $sep [lindex $arg 0]
- if {[string index $text end] ne "*"} {
- append text " "
- }
- append text [lindex $arg 1] [lindex $arg 2]
- set sep ", "
- }
- append text ", ...)"
- }
- default {
- set sep "("
- foreach arg $args {
- append text $sep [lindex $arg 0]
- if {[string index $text end] ne "*"} {
- append text " "
- }
- append text [lindex $arg 1] [lindex $arg 2]
- set sep ", "
- }
- append text ")"
- }
- }
-
- append text "; /* $index */\n"
- return $text
-}
-
-# genStubs::makeInit --
-#
-# Generate the prototype for a function.
-#
-# Arguments:
-# name The interface name.
-# decl The function declaration.
-# index The slot index for this function.
-#
-# Results:
-# Returns the formatted declaration string.
-
-proc genStubs::makeInit {name decl index} {
- if {[lindex $decl 2] eq ""} {
- append text " &" [lindex $decl 1] ", /* " $index " */\n"
- } else {
- append text " " [lindex $decl 1] ", /* " $index " */\n"
- }
- return $text
-}
-
-# genStubs::forAllStubs --
-#
-# This function iterates over all of the slots and invokes
-# a callback for each slot. The result of the callback is then
-# placed inside appropriate guards.
-#
-# Arguments:
-# name The interface name.
-# slotProc The proc to invoke to handle the slot. It will
-# have the interface name, the declaration, and
-# the index appended.
-# guardProc The proc to invoke to add guards. It will have
-# the slot status and text appended.
-# textVar The variable to use for output.
-# skipString The string to emit if a slot is skipped. This
-# string will be subst'ed in the loop so "$i" can
-# be used to substitute the index value.
-#
-# Results:
-# None.
-
-proc genStubs::forAllStubs {name slotProc guardProc textVar
- {skipString {"/* Slot $i is reserved */\n"}}} {
- variable stubs
- upvar $textVar text
-
- set lastNum $stubs($name,lastNum)
-
- for {set i 0} {$i <= $lastNum} {incr i} {
- if {[info exists stubs($name,decl,$i)]} {
- append text [$guardProc $stubs($name,status,$i) \
- [$slotProc $name $stubs($name,decl,$i) $i]]
- } else {
- eval {append text} $skipString
- }
- }
-}
-
-proc genStubs::noGuard {status text} { return $text }
-
-proc genStubs::addGuard {status text} {
- variable libraryName
- set upName [string toupper $libraryName]
-
- switch -- $status {
- current {
- # No change
- }
- deprecated {
- set text [ifdeffed "${upName}_DEPRECATED" $text]
- }
- obsolete {
- set text ""
- }
- default {
- puts stderr "Unrecognized status code $status"
- }
- }
- return $text
-}
-
-proc genStubs::ifdeffed {macro text} {
- join [list "#ifdef $macro" $text "#endif" ""] \n
-}
-
-# genStubs::emitDeclarations --
-#
-# This function emits the function declarations for this interface.
-#
-# Arguments:
-# name The interface name.
-# textVar The variable to use for output.
-#
-# Results:
-# None.
-
-proc genStubs::emitDeclarations {name textVar} {
- upvar $textVar text
-
- append text "\n/*\n * Exported function declarations:\n */\n\n"
- forAllStubs $name makeDecl noGuard text
- return
-}
-
-# genStubs::emitMacros --
-#
-# This function emits the inline macros for an interface.
-#
-# Arguments:
-# name The name of the interface being emitted.
-# textVar The variable to use for output.
-#
-# Results:
-# None.
-
-proc genStubs::emitMacros {name textVar} {
- variable libraryName
- upvar $textVar text
-
- set upName [string toupper $libraryName]
- append text "\n#if defined(USE_${upName}_STUBS)\n"
- append text "\n/*\n * Inline function declarations:\n */\n\n"
-
- forAllStubs $name makeMacro addGuard text
-
- append text "\n#endif /* defined(USE_${upName}_STUBS) */\n"
- return
-}
-
-# genStubs::emitHeader --
-#
-# This function emits the body of the <name>Decls.h file for
-# the specified interface.
-#
-# Arguments:
-# name The name of the interface being emitted.
-#
-# Results:
-# None.
-
-proc genStubs::emitHeader {name} {
- variable outDir
- variable hooks
- variable epoch
- variable revision
-
- set capName [string toupper [string index $name 0]]
- append capName [string range $name 1 end]
-
- if {$epoch ne ""} {
- set CAPName [string toupper $name]
- append text "\n"
- append text "#define ${CAPName}_STUBS_EPOCH $epoch\n"
- append text "#define ${CAPName}_STUBS_REVISION $revision\n"
- }
-
- append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
-
- emitDeclarations $name text
-
- if {[info exists hooks($name)]} {
- append text "\ntypedef struct {\n"
- foreach hook $hooks($name) {
- set capHook [string toupper [string index $hook 0]]
- append capHook [string range $hook 1 end]
- append text " const struct ${capHook}Stubs *${hook}Stubs;\n"
- }
- append text "} ${capName}StubHooks;\n"
- }
- append text "\ntypedef struct ${capName}Stubs {\n"
- append text " int magic;\n"
- if {$epoch ne ""} {
- append text " int epoch;\n"
- append text " int revision;\n"
- }
- if {[info exists hooks($name)]} {
- append text " const ${capName}StubHooks *hooks;\n\n"
- } else {
- append text " void *hooks;\n\n"
- }
-
- emitSlots $name text
-
- append text "} ${capName}Stubs;\n\n"
-
- append text "extern const ${capName}Stubs *${name}StubsPtr;\n\n"
- append text "#ifdef __cplusplus\n}\n#endif\n"
-
- emitMacros $name text
-
- rewriteFile [file join $outDir ${name}Decls.h] $text
- return
-}
-
-# genStubs::emitInit --
-#
-# Generate the table initializers for an interface.
-#
-# Arguments:
-# name The name of the interface to initialize.
-# textVar The variable to use for output.
-#
-# Results:
-# Returns the formatted output.
-
-proc genStubs::emitInit {name textVar} {
- variable hooks
- variable interfaces
- variable epoch
- upvar $textVar text
- set root 1
-
- set capName [string toupper [string index $name 0]]
- append capName [string range $name 1 end]
-
- if {[info exists hooks($name)]} {
- append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n"
- set sep " "
- foreach sub $hooks($name) {
- append text $sep "&${sub}Stubs"
- set sep ",\n "
- }
- append text "\n\};\n"
- }
- foreach intf [array names interfaces] {
- if {[info exists hooks($intf)]} {
- if {[lsearch -exact $hooks($intf) $name] >= 0} {
- set root 0
- break
- }
- }
- }
-
- append text "\n"
- if {!$root} {
- append text "static "
- }
- append text "const ${capName}Stubs ${name}Stubs = \{\n TCL_STUB_MAGIC,\n"
- if {$epoch ne ""} {
- set CAPName [string toupper $name]
- append text " ${CAPName}_STUBS_EPOCH,\n"
- append text " ${CAPName}_STUBS_REVISION,\n"
- }
- if {[info exists hooks($name)]} {
- append text " &${name}StubHooks,\n"
- } else {
- append text " 0,\n"
- }
-
- forAllStubs $name makeInit noGuard text {" 0, /* $i */\n"}
-
- append text "\};\n"
- return
-}
-
-# genStubs::emitInits --
-#
-# This function emits the body of the <name>StubInit.c file for
-# the specified interface.
-#
-# Arguments:
-# name The name of the interface being emitted.
-#
-# Results:
-# None.
-
-proc genStubs::emitInits {} {
- variable hooks
- variable outDir
- variable libraryName
- variable interfaces
-
- # Assuming that dependencies only go one level deep, we need to emit
- # all of the leaves first to avoid needing forward declarations.
-
- set leaves {}
- set roots {}
- foreach name [lsort [array names interfaces]] {
- if {[info exists hooks($name)]} {
- lappend roots $name
- } else {
- lappend leaves $name
- }
- }
- foreach name $leaves {
- emitInit $name text
- }
- foreach name $roots {
- emitInit $name text
- }
-
- rewriteFile [file join $outDir ${libraryName}StubInit.c] $text
-}
-
-# genStubs::init --
-#
-# This is the main entry point.
-#
-# Arguments:
-# None.
-#
-# Results:
-# None.
-
-proc genStubs::init {} {
- global argv argv0
- variable outDir
- variable interfaces
-
- if {[llength $argv] < 2} {
- puts stderr "usage: $argv0 outDir declFile ?declFile...?"
- exit 1
- }
-
- set outDir [lindex $argv 0]
-
- foreach file [lrange $argv 1 end] {
- source $file
- }
-
- foreach name [lsort [array names interfaces]] {
- puts "Emitting $name"
- emitHeader $name
- }
-
- emitInits
-}
-
-# lassign --
-#
-# This function emulates the TclX lassign command.
-#
-# Arguments:
-# valueList A list containing the values to be assigned.
-# args The list of variables to be assigned.
-#
-# Results:
-# Returns any values that were not assigned to variables.
-
-if {[string length [namespace which lassign]] == 0} {
- proc lassign {valueList args} {
- if {[llength $args] == 0} {
- error "wrong # args: should be \"lassign list varName ?varName ...?\""
- }
- uplevel [list foreach $args $valueList {break}]
- return [lrange $valueList [llength $args] end]
- }
-}
-
-genStubs::init
diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c
index a5a3a52..002a753 100644
--- a/generic/ttk/ttkImage.c
+++ b/generic/ttk/ttkImage.c
@@ -10,8 +10,7 @@
* [style map].
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -25,6 +24,8 @@ struct TtkImageSpec {
int mapCount; /* #state-specific overrides */
Ttk_StateSpec *states; /* array[mapCount] of states ... */
Tk_Image *images; /* ... per-state images to use */
+ Tk_ImageChangedProc *imageChanged;
+ ClientData imageChangedClientData;
};
/* NullImageChanged --
@@ -34,15 +35,41 @@ static void NullImageChanged(ClientData clientData,
int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */ }
+/* ImageSpecImageChanged --
+ * Image changes should trigger a repaint.
+ */
+static void ImageSpecImageChanged(ClientData clientData,
+ int x, int y, int width, int height, int imageWidth, int imageHeight)
+{
+ Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData;
+ if (imageSpec->imageChanged != NULL) {
+ imageSpec->imageChanged(imageSpec->imageChangedClientData,
+ x, y, width, height,
+ imageWidth, imageHeight);
+ }
+}
+
/* TtkGetImageSpec --
* Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
* Result must be released using TtkFreeImageSpec.
*
- * TODO: Need a variant of this that takes a user-specified ImageChanged proc
*/
Ttk_ImageSpec *
TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
{
+ return TtkGetImageSpecEx(interp, tkwin, objPtr, NULL, NULL);
+}
+
+/* TtkGetImageSpecEx --
+ * Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
+ * Result must be released using TtkFreeImageSpec.
+ * imageChangedProc will be called when not NULL when
+ * the image changes to allow widgets to repaint.
+ */
+Ttk_ImageSpec *
+TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr,
+ Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData)
+{
Ttk_ImageSpec *imageSpec = 0;
int i = 0, n = 0, objc;
Tcl_Obj **objv;
@@ -52,6 +79,8 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
imageSpec->mapCount = 0;
imageSpec->states = 0;
imageSpec->images = 0;
+ imageSpec->imageChanged = imageChangedProc;
+ imageSpec->imageChangedClientData = imageChangedClientData;
if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
goto error;
@@ -74,7 +103,7 @@ TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr)
/* Get base image:
*/
imageSpec->baseImage = Tk_GetImage(
- interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL);
+ interp, tkwin, Tcl_GetString(objv[0]), ImageSpecImageChanged, imageSpec);
if (!imageSpec->baseImage) {
goto error;
}
@@ -315,7 +344,7 @@ Ttk_CreateImageElement(
const char *elementName,
int objc, Tcl_Obj *const objv[])
{
- static const char *optionStrings[] =
+ static const char *const optionStrings[] =
{ "-border","-height","-padding","-sticky","-width",NULL };
enum { O_BORDER, O_HEIGHT, O_PADDING, O_STICKY, O_WIDTH };
diff --git a/generic/ttk/ttkInit.c b/generic/ttk/ttkInit.c
index dc6e994..60e3b6f 100644
--- a/generic/ttk/ttkInit.c
+++ b/generic/ttk/ttkInit.c
@@ -4,8 +4,7 @@
* Ttk package: initialization routine and miscellaneous utilities.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -62,7 +61,7 @@ int Ttk_GetOrientFromObj(
* Recognized values for the -state compatibility option.
* Other options are accepted and interpreted as synonyms for "normal".
*/
-static const char *ttkStateStrings[] = {
+static const char *const ttkStateStrings[] = {
"normal", "readonly", "disabled", "active", NULL
};
enum {
diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c
index 1037840..91be033 100644
--- a/generic/ttk/ttkLabel.c
+++ b/generic/ttk/ttkLabel.c
@@ -6,8 +6,7 @@
*
*/
-#include <tcl.h>
-#include <tkInt.h>
+#include "tkInt.h"
#include "ttkTheme.h"
/*----------------------------------------------------------------------
@@ -139,7 +138,7 @@ static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b)
gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin));
gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues);
- /*
+ /*
* Place text according to -anchor:
*/
Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor);
@@ -342,15 +341,15 @@ static void ImageDraw(
Tk_RedrawImage(image->tkimg, 0,0, width, height, d, b.x, b.y);
- /* If we're disabled there's no state-specific 'disabled' image,
+ /* If we're disabled there's no state-specific 'disabled' image,
* stipple the image.
* @@@ Possibly: Don't do disabled-stippling at all;
* @@@ it's ugly and out of fashion.
- * Do not stipple at all under Aqua, just draw the image: it shows up
+ * Do not stipple at all under Aqua, just draw the image: it shows up
* as a white rectangle otherwise.
*/
-
+
if (state & TTK_STATE_DISABLED) {
if (TtkSelectImage(image->imageSpec, 0ul) == image->tkimg) {
#ifndef MAC_OSX_TK
@@ -577,7 +576,7 @@ static void LabelElementSize(
if (label->compound != TTK_COMPOUND_IMAGE)
textReqWidth = TextReqWidth(&label->text);
- switch (label->compound)
+ switch (label->compound)
{
case TTK_COMPOUND_TEXT:
*widthPtr = textReqWidth;
@@ -588,11 +587,11 @@ static void LabelElementSize(
case TTK_COMPOUND_TOP:
case TTK_COMPOUND_BOTTOM:
case TTK_COMPOUND_CENTER:
- *widthPtr = MAX(label->image.width, textReqWidth);
+ *widthPtr = MAX(label->image.width, textReqWidth);
break;
case TTK_COMPOUND_LEFT:
case TTK_COMPOUND_RIGHT:
- *widthPtr = label->image.width + textReqWidth + label->space;
+ *widthPtr = label->image.width + textReqWidth + label->space;
break;
case TTK_COMPOUND_NONE:
break; /* Can't happen */
diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c
index ba24589..795ffb5 100644
--- a/generic/ttk/ttkLayout.c
+++ b/generic/ttk/ttkLayout.c
@@ -6,8 +6,7 @@
* Copyright (c) 2003 Joe English. Freely redistributable.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkThemeInt.h"
#define MAX(a,b) (a > b ? a : b)
@@ -604,13 +603,13 @@ Ttk_InstantiateLayout(Ttk_Theme theme, Ttk_TemplateNode *op)
*/
/* NB: This must match bit definitions TTK_PACK_LEFT etc. */
-static const char *packSideStrings[] =
+static const char *const packSideStrings[] =
{ "left", "right", "top", "bottom", NULL };
Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN };
- static const char *optStrings[] = {
+ static const char *const optStrings[] = {
"-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 };
int i = 0, objc;
@@ -702,6 +701,8 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
if (childSpec) {
tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
if (!tail->child) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value"));
+ Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL);
goto error;
}
}
diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c
index 24a0fb1..bf93699 100644
--- a/generic/ttk/ttkManager.c
+++ b/generic/ttk/ttkManager.c
@@ -4,8 +4,7 @@
* Support routines for geometry managers.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkManager.h"
/*------------------------------------------------------------------------
@@ -320,7 +319,7 @@ void Ttk_GeometryRequestProc(ClientData clientData, Tk_Window slaveWindow)
int reqHeight= Tk_ReqHeight(slaveWindow);
if (mgr->managerSpec->SlaveRequest(
- mgr->managerData, slaveIndex, reqWidth, reqHeight))
+ mgr->managerData, slaveIndex, reqWidth, reqHeight))
{
ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}
diff --git a/generic/ttk/ttkManager.h b/generic/ttk/ttkManager.h
index d22ff98..07fcea1 100644
--- a/generic/ttk/ttkManager.h
+++ b/generic/ttk/ttkManager.h
@@ -22,7 +22,7 @@ typedef struct TtkManager_ Ttk_Manager;
* SlaveRemoved() is called immediately before a slave is removed.
* NB: the associated slave window may have been destroyed when this
* routine is called.
- *
+ *
* SlaveRequest() is called when a slave requests a size change.
* It should return 1 if the request should propagate, 0 otherwise.
*/
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
index 81a8b64..0625af8 100644
--- a/generic/ttk/ttkNotebook.c
+++ b/generic/ttk/ttkNotebook.c
@@ -2,11 +2,7 @@
* Copyright (c) 2004, Joe English
*/
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
#include "ttkManager.h"
@@ -221,7 +217,7 @@ static int ConfigureTab(
Tk_SavedOptions savedOptions;
int mask = 0;
- if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable,
+ if (Tk_SetOptions(interp, tab, nb->notebook.paneOptionTable,
objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
{
return TCL_ERROR;
@@ -288,13 +284,14 @@ static void ActivateTab(Notebook *nb, int index)
* TabState --
* Return the state of the specified tab, based on
* notebook state, currentIndex, activeIndex, and user-specified tab state.
- * The USER1 bit is set for the leftmost tab, and USER2
- * is set for the rightmost tab.
+ * The USER1 bit is set for the leftmost visible tab, and USER2
+ * is set for the rightmost visible tab.
*/
static Ttk_State TabState(Notebook *nb, int index)
{
Ttk_State state = nb->core.state;
Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index);
+ int i = 0;
if (index == nb->notebook.currentIndex) {
state |= TTK_STATE_SELECTED;
@@ -305,11 +302,25 @@ static Ttk_State TabState(Notebook *nb, int index)
if (index == nb->notebook.activeIndex) {
state |= TTK_STATE_ACTIVE;
}
- if (index == 0) {
- state |= TTK_STATE_USER1;
+ for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER1;
+ }
+ break;
}
- if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) {
- state |= TTK_STATE_USER2;
+ for (i = Ttk_NumberSlaves(nb->notebook.mgr) - 1; i >= 0; --i) {
+ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i);
+ if (tab->state == TAB_STATE_HIDDEN) {
+ continue;
+ }
+ if (index == i) {
+ state |= TTK_STATE_USER2;
+ }
+ break;
}
if (tab->state == TAB_STATE_DISABLED) {
state |= TTK_STATE_DISABLED;
@@ -325,6 +336,8 @@ static Ttk_State TabState(Notebook *nb, int index)
/* TabrowSize --
* Compute max height and total width of all tabs (horizontal layouts)
* or total height and max width (vertical layouts).
+ * The -mintabwidth style option is taken into account (for the width
+ * only).
*
* Side effects:
* Sets width and height fields for all tabs.
@@ -334,7 +347,7 @@ static Ttk_State TabState(Notebook *nb, int index)
* (max height/width) but not parallel (total width/height).
*/
static void TabrowSize(
- Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr)
+ Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr)
{
Ttk_Layout tabLayout = nb->notebook.tabLayout;
int tabrowWidth = 0, tabrowHeight = 0;
@@ -346,6 +359,7 @@ static void TabrowSize(
Ttk_RebindSublayout(tabLayout, tab);
Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height);
+ tab->width = MAX(tab->width, minTabWidth);
if (orient == TTK_ORIENT_HORIZONTAL) {
tabrowHeight = MAX(tabrowHeight, tab->height);
@@ -406,7 +420,7 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* Tab row:
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins);
tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins);
@@ -436,47 +450,30 @@ static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
/* SqueezeTabs --
* Squeeze or stretch tabs to fit within the tab area parcel.
+ * This happens independently of the -mintabwidth style option.
*
- * All tabs are adjusted by an equal amount, but will not be made
- * smaller than the minimum width. (If all the tabs still do
- * not fit in the available space, the rightmost ones will
- * be further squozen by PlaceTabs()).
- *
- * The algorithm does not always yield an optimal layout, but does
- * have the important property that decreasing the available width
- * by one pixel will cause at most one tab to shrink by one pixel;
- * this means that tabs resize "smoothly" when the window shrinks
- * and grows.
+ * All tabs are adjusted by an equal amount.
*
* @@@ <<NOTE-TABPOSITION>> bug: only works for horizontal orientations
* @@@ <<NOTE-SQUEEZE-HIDDEN>> does not account for hidden tabs.
*/
static void SqueezeTabs(
- Notebook *nb, int needed, int available, int minTabWidth)
+ Notebook *nb, int needed, int available)
{
int nTabs = Ttk_NumberSlaves(nb->notebook.mgr);
if (nTabs > 0) {
- int difference = available - needed,
- delta = difference / nTabs,
- remainder = difference % nTabs,
- slack = 0;
+ int difference = available - needed;
+ double delta = (double)difference / needed;
+ double slack = 0;
int i;
- if (remainder < 0) { remainder += nTabs; --delta; }
-
for (i = 0; i < nTabs; ++i) {
Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i);
- int adj = delta + (i < remainder) + slack;
-
- if (tab->width + adj >= minTabWidth) {
- tab->width += adj;
- slack = 0;
- } else {
- slack = adj - (minTabWidth - tab->width);
- tab->width = minTabWidth;
- }
+ double ad = slack + tab->width * delta;
+ tab->width += (int)ad;
+ slack = ad - (int)ad;
}
}
}
@@ -539,8 +536,13 @@ static void NotebookDoLayout(void *recordPtr)
Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin));
/* Place tabs:
+ * Note: TabrowSize() takes into account -mintabwidth, but the tabs will
+ * actually have this minimum size when displayed only if there is enough
+ * space to draw the tabs with this width. Otherwise some of the tabs can
+ * be squeezed to a size smaller than -mintabwidth because we prefer
+ * displaying all tabs than than honoring -mintabwidth for all of them.
*/
- TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight);
+ TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight);
tabrowBox = Ttk_PadBox(
Ttk_PositionBox(&cavity,
tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins),
@@ -548,7 +550,7 @@ static void NotebookDoLayout(void *recordPtr)
nbstyle.tabPosition),
nbstyle.tabMargins);
- SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth);
+ SqueezeTabs(nb, tabrowWidth, tabrowBox.width);
PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement);
/* Layout for client area frame:
@@ -621,9 +623,12 @@ static void SelectTab(Notebook *nb, int index)
Ttk_UnmapSlave(nb->notebook.mgr, currentIndex);
}
- NotebookPlaceSlave(nb, index);
-
+ /* Must be set before calling NotebookPlaceSlave(), otherwise it may
+ * happen that NotebookPlaceSlaves(), triggered by an interveaning
+ * geometry request, will swap to old index. */
nb->notebook.currentIndex = index;
+
+ NotebookPlaceSlave(nb, index);
TtkRedisplayWidget(&nb->core);
TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
@@ -1044,7 +1049,7 @@ static int NotebookHideCommand(
static int NotebookIdentifyCommand(
void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
- static const char *whatTable[] = { "element", "tab", NULL };
+ static const char *const whatTable[] = { "element", "tab", NULL };
enum { IDENTIFY_ELEMENT, IDENTIFY_TAB };
int what = IDENTIFY_ELEMENT;
Notebook *nb = recordPtr;
diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c
index adc2aef..8f8094e 100644
--- a/generic/ttk/ttkPanedwindow.c
+++ b/generic/ttk/ttkPanedwindow.c
@@ -6,8 +6,7 @@
* TODO: track active/pressed sash.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkManager.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -148,7 +147,7 @@ static int ConfigurePane(
Tk_SavedOptions savedOptions;
int mask = 0;
- if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
+ if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable,
objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK)
{
return TCL_ERROR;
@@ -715,7 +714,7 @@ static int PanedForgetCommand(
static int PanedIdentifyCommand(
void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
- static const char *whatTable[] = { "element", "sash", NULL };
+ static const char *const whatTable[] = { "element", "sash", NULL };
enum { IDENTIFY_ELEMENT, IDENTIFY_SASH };
int what = IDENTIFY_SASH;
Paned *pw = recordPtr;
diff --git a/generic/ttk/ttkProgress.c b/generic/ttk/ttkProgress.c
index 4dc50a2..b805357 100644
--- a/generic/ttk/ttkProgress.c
+++ b/generic/ttk/ttkProgress.c
@@ -4,9 +4,7 @@
* ttk::progressbar widget.
*/
-#include <math.h>
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -23,13 +21,19 @@ static const char *const ProgressbarModeStrings[] = {
};
typedef struct {
- Tcl_Obj *orientObj;
+ Tcl_Obj *anchorObj;
+ Tcl_Obj *fontObj;
+ Tcl_Obj *foregroundObj;
+ Tcl_Obj *justifyObj;
Tcl_Obj *lengthObj;
- Tcl_Obj *modeObj;
- Tcl_Obj *variableObj;
Tcl_Obj *maximumObj;
- Tcl_Obj *valueObj;
+ Tcl_Obj *modeObj;
+ Tcl_Obj *orientObj;
Tcl_Obj *phaseObj;
+ Tcl_Obj *textObj;
+ Tcl_Obj *valueObj;
+ Tcl_Obj *variableObj;
+ Tcl_Obj *wrapLengthObj;
int mode;
Ttk_TraceHandle *variableTrace; /* Trace handle for -variable option */
@@ -46,28 +50,46 @@ typedef struct {
static Tk_OptionSpec ProgressbarOptionSpecs[] =
{
- {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
- "horizontal", Tk_Offset(Progressbar,progress.orientObj), -1,
- 0, (ClientData)ttkOrientStrings, STYLE_CHANGED },
+ {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
+ "w", Tk_Offset(Progressbar,progress.anchorObj), -1,
+ TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED},
+ {TK_OPTION_FONT, "-font", "font", "Font",
+ DEFAULT_FONT, Tk_Offset(Progressbar,progress.fontObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
+ {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
+ "black", Tk_Offset(Progressbar,progress.foregroundObj), -1,
+ TK_OPTION_NULL_OK,0,0 },
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ "left", Tk_Offset(Progressbar,progress.justifyObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
{TK_OPTION_PIXELS, "-length", "length", "Length",
DEF_PROGRESSBAR_LENGTH, Tk_Offset(Progressbar,progress.lengthObj), -1,
0, 0, GEOMETRY_CHANGED },
+ {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
+ "100", Tk_Offset(Progressbar,progress.maximumObj), -1,
+ 0, 0, 0 },
{TK_OPTION_STRING_TABLE, "-mode", "mode", "ProgressMode", "determinate",
Tk_Offset(Progressbar,progress.modeObj),
Tk_Offset(Progressbar,progress.mode),
0, (ClientData)ProgressbarModeStrings, 0 },
- {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
- "100", Tk_Offset(Progressbar,progress.maximumObj), -1,
+ {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
+ "horizontal", Tk_Offset(Progressbar,progress.orientObj), -1,
+ 0, (ClientData)ttkOrientStrings, STYLE_CHANGED },
+ {TK_OPTION_INT, "-phase", "phase", "Phase",
+ "0", Tk_Offset(Progressbar,progress.phaseObj), -1,
0, 0, 0 },
- {TK_OPTION_STRING, "-variable", "variable", "Variable",
- NULL, Tk_Offset(Progressbar,progress.variableObj), -1,
- TK_OPTION_NULL_OK, 0, 0 },
+ {TK_OPTION_STRING, "-text", "text", "Text", "",
+ Tk_Offset(Progressbar,progress.textObj), -1,
+ 0,0,GEOMETRY_CHANGED },
{TK_OPTION_DOUBLE, "-value", "value", "Value",
"0.0", Tk_Offset(Progressbar,progress.valueObj), -1,
0, 0, 0 },
- {TK_OPTION_INT, "-phase", "phase", "Phase",
- "0", Tk_Offset(Progressbar,progress.phaseObj), -1,
- 0, 0, 0 },
+ {TK_OPTION_STRING, "-variable", "variable", "Variable",
+ NULL, Tk_Offset(Progressbar,progress.variableObj), -1,
+ TK_OPTION_NULL_OK, 0, 0 },
+ {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
+ "0", Tk_Offset(Progressbar, progress.wrapLengthObj), -1,
+ TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED},
WIDGET_TAKEFOCUS_FALSE,
WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
@@ -398,7 +420,7 @@ static int ProgressbarStepCommand(
{
Progressbar *pb = recordPtr;
double value = 0.0, stepAmount = 1.0;
- Tcl_Obj *newValueObj;
+ Tcl_Obj *newValueObj;
if (objc == 3) {
if (Tcl_GetDoubleFromObj(interp, objv[2], &stepAmount) != TCL_OK) {
@@ -421,21 +443,23 @@ static int ProgressbarStepCommand(
}
newValueObj = Tcl_NewDoubleObj(value);
+ Tcl_IncrRefCount(newValueObj);
TtkRedisplayWidget(&pb->core);
- /* Update value by setting the linked -variable, if there is one:
+ /* Update value by setting the linked -variable, if there is one:
*/
if (pb->progress.variableTrace) {
- return Tcl_ObjSetVar2(
- interp, pb->progress.variableObj, 0, newValueObj,
- TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
- ? TCL_OK : TCL_ERROR;
+ int result = Tcl_ObjSetVar2(
+ interp, pb->progress.variableObj, 0, newValueObj,
+ TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
+ ? TCL_OK : TCL_ERROR;
+ Tcl_DecrRefCount(newValueObj);
+ return result;
}
/* Otherwise, change the -value directly:
*/
- Tcl_IncrRefCount(newValueObj);
Tcl_DecrRefCount(pb->progress.valueObj);
pb->progress.valueObj = newValueObj;
CheckAnimation(pb);
@@ -444,7 +468,7 @@ static int ProgressbarStepCommand(
}
/* $sb start|stop ?args? --
- * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...]
+ * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...]
* and pass to interpreter.
*/
static int ProgressbarStartStopCommand(
@@ -522,7 +546,8 @@ TTK_END_LAYOUT
TTK_BEGIN_LAYOUT(HorizontalProgressbarLayout)
TTK_GROUP("Horizontal.Progressbar.trough", TTK_FILL_BOTH,
- TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y))
+ TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y)
+ TTK_NODE("Horizontal.Progressbar.text", TTK_PACK_LEFT))
TTK_END_LAYOUT
/*
diff --git a/generic/ttk/ttkScale.c b/generic/ttk/ttkScale.c
index 69753d1..458bccd 100644
--- a/generic/ttk/ttkScale.c
+++ b/generic/ttk/ttkScale.c
@@ -4,9 +4,7 @@
* ttk::scale widget.
*/
-#include <tk.h>
-#include <string.h>
-#include <stdio.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -15,6 +13,10 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
+/* Bit fields for OptionSpec mask field:
+ */
+#define STATE_CHANGED (0x100) /* -state option changed */
+
/*
* Scale widget record
*/
@@ -35,6 +37,11 @@ typedef struct
/* internal state */
Ttk_TraceHandle *variableTrace;
+ /*
+ * Compatibility/legacy options:
+ */
+ Tcl_Obj *stateObj;
+
} ScalePart;
typedef struct
@@ -46,14 +53,14 @@ typedef struct
static Tk_OptionSpec ScaleOptionSpecs[] =
{
{TK_OPTION_STRING, "-command", "command", "Command", "",
- Tk_Offset(Scale,scale.commandObj), -1,
+ Tk_Offset(Scale,scale.commandObj), -1,
TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-variable", "variable", "Variable", "",
- Tk_Offset(Scale,scale.variableObj), -1,
+ Tk_Offset(Scale,scale.variableObj), -1,
0,0,0},
{TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
Tk_Offset(Scale,scale.orientObj),
- Tk_Offset(Scale,scale.orient), 0,
+ Tk_Offset(Scale,scale.orient), 0,
(ClientData)ttkOrientStrings, STYLE_CHANGED },
{TK_OPTION_DOUBLE, "-from", "from", "From", "0",
@@ -63,9 +70,13 @@ static Tk_OptionSpec ScaleOptionSpecs[] =
{TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
Tk_Offset(Scale,scale.valueObj), -1, 0, 0, 0},
{TK_OPTION_PIXELS, "-length", "length", "Length",
- DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0,
+ DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0,
GEOMETRY_CHANGED},
+ {TK_OPTION_STRING, "-state", "state", "State",
+ "normal", Tk_Offset(Scale,scale.stateObj), -1,
+ 0,0,STATE_CHANGED},
+
WIDGET_TAKEFOCUS_TRUE,
WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};
@@ -76,7 +87,7 @@ static double PointToValue(Scale *scalePtr, int x, int y);
/* ScaleVariableChanged --
* Variable trace procedure for scale -variable;
* Updates the scale's value.
- * If the linked variable is not a valid double,
+ * If the linked variable is not a valid double,
* sets the 'invalid' state.
*/
static void ScaleVariableChanged(void *recordPtr, const char *value)
@@ -139,6 +150,10 @@ static int ScaleConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
}
scale->scale.variableTrace = vt;
+ if (mask & STATE_CHANGED) {
+ TtkCheckStateOption(&scale->core, scale->scale.stateObj);
+ }
+
return TCL_OK;
}
@@ -172,7 +187,7 @@ static int ScalePostConfigure(
/* ScaleGetLayout --
* getLayout hook.
*/
-static Ttk_Layout
+static Ttk_Layout
ScaleGetLayout(Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr)
{
Scale *scalePtr = recordPtr;
@@ -236,7 +251,7 @@ static double ScaleFraction(Scale *scalePtr, double value)
}
/* $scale get ?x y? --
- * Returns the current value of the scale widget, or if $x and
+ * Returns the current value of the scale widget, or if $x and
* $y are specified, the value represented by point @x,y.
*/
static int
diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c
index 2bd3ddb..184f5f2 100644
--- a/generic/ttk/ttkScroll.c
+++ b/generic/ttk/ttkScroll.c
@@ -34,7 +34,7 @@
* TtkScrollbarUpdateRequired, which will invoke step (5) (@@@ Fix this)
*/
-#include <tkInt.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
diff --git a/generic/ttk/ttkScrollbar.c b/generic/ttk/ttkScrollbar.c
index 5b0c212..f304ea9 100644
--- a/generic/ttk/ttkScrollbar.c
+++ b/generic/ttk/ttkScrollbar.c
@@ -4,8 +4,7 @@
* ttk::scrollbar widget.
*/
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -22,7 +21,7 @@ typedef struct
double first; /* top fraction */
double last; /* bottom fraction */
- Ttk_Box troughBox; /* trough parcel */
+ Ttk_Box troughBox; /* trough parcel */
int minSize; /* minimum size of thumb */
} ScrollbarPart;
@@ -50,7 +49,7 @@ static Tk_OptionSpec ScrollbarOptionSpecs[] =
* +++ Widget hooks.
*/
-static void
+static void
ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr)
{
Scrollbar *sb = recordPtr;
@@ -241,7 +240,7 @@ ScrollbarDeltaCommand(
/* $sb fraction $x $y --
* Returns a real number between 0 and 1 indicating where the
- * point given by x and y lies in the trough area of the scrollbar.
+ * point given by x and y lies in the trough area of the scrollbar.
*/
static int
ScrollbarFractionCommand(
diff --git a/generic/ttk/ttkSeparator.c b/generic/ttk/ttkSeparator.c
index b52e6f4..dae6d69 100644
--- a/generic/ttk/ttkSeparator.c
+++ b/generic/ttk/ttkSeparator.c
@@ -4,8 +4,7 @@
* ttk::separator and ttk::sizegrip widgets.
*/
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
diff --git a/generic/ttk/ttkSquare.c b/generic/ttk/ttkSquare.c
index d002f2f..5302eb7 100644
--- a/generic/ttk/ttkSquare.c
+++ b/generic/ttk/ttkSquare.c
@@ -3,7 +3,7 @@
* Minimal sample ttk widget.
*/
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -56,24 +56,24 @@ static Tk_OptionSpec SquareOptionSpecs[] =
{TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
DEFAULT_BACKGROUND, Tk_Offset(Square,square.foregroundObj),
-1, 0, 0, 0},
-
+
{TK_OPTION_PIXELS, "-width", "width", "Width",
"50", Tk_Offset(Square,square.widthObj), -1, 0, 0,
GEOMETRY_CHANGED},
{TK_OPTION_PIXELS, "-height", "height", "Height",
"50", Tk_Offset(Square,square.heightObj), -1, 0, 0,
GEOMETRY_CHANGED},
-
+
{TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
- Tk_Offset(Square,square.paddingObj), -1,
+ Tk_Offset(Square,square.paddingObj), -1,
TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
-
+
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
NULL, Tk_Offset(Square,square.reliefObj), -1, TK_OPTION_NULL_OK, 0, 0},
-
+
{TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
NULL, Tk_Offset(Square,square.anchorObj), -1, TK_OPTION_NULL_OK, 0, 0},
-
+
WIDGET_TAKEFOCUS_TRUE,
WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};
@@ -138,7 +138,7 @@ static const Ttk_Ensemble SquareCommands[] = {
};
/*
- * The Widget specification structure holds all the implementation
+ * The Widget specification structure holds all the implementation
* information about this widget and this is what must be registered
* with Tk in the package initialization code (see bottom).
*/
@@ -159,7 +159,7 @@ static WidgetSpec SquareWidgetSpec =
TtkWidgetDisplay /* displayProc */
};
-/* ----------------------------------------------------------------------
+/* ----------------------------------------------------------------------
* Square element
*
* In this section we demonstrate what is required to create a new themed
@@ -176,7 +176,7 @@ typedef struct
Tcl_Obj *heightObj;
} SquareElement;
-static Ttk_ElementOptionSpec SquareElementOptions[] =
+static Ttk_ElementOptionSpec SquareElementOptions[] =
{
{ "-background", TK_OPTION_BORDER, Tk_Offset(SquareElement,borderObj),
DEFAULT_BACKGROUND },
@@ -248,7 +248,7 @@ static Ttk_ElementSpec SquareElementSpec =
* engine is similar to the Tk pack geometry manager. Read the documentation
* for the details. In this example we just need to have the square element
* that has been defined for this widget placed on a background. We will
- * also need some padding to keep it away from the edges.
+ * also need some padding to keep it away from the edges.
*/
TTK_BEGIN_LAYOUT(SquareLayout)
@@ -257,12 +257,12 @@ TTK_BEGIN_LAYOUT(SquareLayout)
TTK_NODE("Square.square", 0))
TTK_END_LAYOUT
-/* ----------------------------------------------------------------------
+/* ----------------------------------------------------------------------
*
* Widget initialization.
*
* This file defines a new element and a new widget. We need to register
- * the element with the themes that will need it. In this case we will
+ * the element with the themes that will need it. In this case we will
* register with the default theme that is the root of the theme inheritance
* tree. This means all themes will find this element.
* We then need to register the widget class style. This is the layout
@@ -287,10 +287,10 @@ TtkSquareWidget_Init(Tcl_Interp *interp)
/* register the new elements for this theme engine */
Ttk_RegisterElement(interp, theme, "square", &SquareElementSpec, NULL);
-
+
/* register the layout for this theme */
Ttk_RegisterLayout(theme, "TSquare", SquareLayout);
-
+
/* register the widget */
RegisterWidget(interp, "ttk::square", &SquareWidgetSpec);
diff --git a/generic/ttk/ttkState.c b/generic/ttk/ttkState.c
index c34b900..7ac6740 100644
--- a/generic/ttk/ttkState.c
+++ b/generic/ttk/ttkState.c
@@ -5,9 +5,7 @@
*
*/
-#include <string.h>
-
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
/*
@@ -130,7 +128,8 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr)
unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
unsigned int mask = onbits | offbits;
Tcl_DString result;
- int i, len;
+ int i;
+ size_t len;
Tcl_DStringInit(&result);
@@ -146,9 +145,9 @@ static void StateSpecUpdateString(Tcl_Obj *objPtr)
len = Tcl_DStringLength(&result);
if (len) {
/* 'len' includes extra trailing ' ' */
- objPtr->bytes = Tcl_Alloc((unsigned)len);
+ objPtr->bytes = Tcl_Alloc(len);
objPtr->length = len-1;
- strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1);
+ strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1);
objPtr->bytes[len-1] = '\0';
} else {
/* empty string */
diff --git a/generic/ttk/ttkStubLib.c b/generic/ttk/ttkStubLib.c
index 2c07b9d..c17f1e9 100644
--- a/generic/ttk/ttkStubLib.c
+++ b/generic/ttk/ttkStubLib.c
@@ -67,7 +67,7 @@ error:
"Error loading ", packageName, " package",
" (requested version '", version,
"', loaded version '", actualVersion, "'): ",
- errMsg,
+ errMsg,
NULL);
return NULL;
}
diff --git a/generic/ttk/ttkTagSet.c b/generic/ttk/ttkTagSet.c
index f2108b9..f0354d8 100644
--- a/generic/ttk/ttkTagSet.c
+++ b/generic/ttk/ttkTagSet.c
@@ -4,10 +4,7 @@
* Copyright (C) 2005, Joe English. Freely redistributable.
*/
-#include <string.h> /* for memset() */
-#include <tcl.h>
-#include <tk.h>
-
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -188,7 +185,7 @@ int Ttk_TagSetAdd(Ttk_TagSet tagset, Ttk_Tag tag)
return 0;
}
}
- tagset->tags = ckrealloc(tagset->tags,
+ tagset->tags = ckrealloc(tagset->tags,
(tagset->nTags+1)*sizeof(tagset->tags[0]));
tagset->tags[tagset->nTags++] = tag;
return 1;
diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c
index 2f95962..f98cc26 100644
--- a/generic/ttk/ttkTheme.c
+++ b/generic/ttk/ttkTheme.c
@@ -10,10 +10,7 @@
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <stdlib.h>
-#include <string.h>
-#include <tk.h>
-#include <tkInt.h>
+#include "tkInt.h"
#include "ttkThemeInt.h"
#define PKG_ASSOC_KEY "Ttk"
@@ -145,7 +142,7 @@ static const Tk_OptionSpec *TTKGetOptionSpec(
/* Make sure widget option has a Tcl_Obj* entry:
*/
- if (optionSpec->objOffset < 0) {
+ if (optionSpec->objOffset == TCL_AUTO_LENGTH) {
return 0;
}
@@ -973,12 +970,12 @@ static
int InitializeElementRecord(
Ttk_ElementClass *eclass, /* Element instance to initialize */
Ttk_Style style, /* Style table */
- char *widgetRecord, /* Source of widget option values */
+ void *widgetRecord, /* Source of widget option values */
Tk_OptionTable optionTable, /* Option table describing widget record */
Tk_Window tkwin, /* Corresponding window */
Ttk_State state) /* Widget or element state */
{
- char *elementRecord = eclass->elementRecord;
+ void *elementRecord = eclass->elementRecord;
OptionMap optionMap = GetOptionMap(eclass,optionTable);
int nResources = eclass->nResources;
Ttk_ResourceCache cache = style->cache;
@@ -987,7 +984,7 @@ int InitializeElementRecord(
int i;
for (i=0; i<nResources; ++i, ++elementOption) {
Tcl_Obj **dest = (Tcl_Obj **)
- (elementRecord + elementOption->offset);
+ ((char *)elementRecord + elementOption->offset);
const char *optionName = elementOption->optionName;
Tcl_Obj *dynamicSetting = Ttk_StyleMap(style, optionName, state);
Tcl_Obj *widgetValue = 0;
@@ -995,7 +992,7 @@ int InitializeElementRecord(
if (optionMap[i]) {
widgetValue = *(Tcl_Obj **)
- (widgetRecord + optionMap[i]->objOffset);
+ ((char *)widgetRecord + optionMap[i]->objOffset);
}
if (widgetValue) {
@@ -1067,7 +1064,7 @@ void
Ttk_ElementSize(
Ttk_ElementClass *eclass, /* Element to query */
Ttk_Style style, /* Style settings */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_OptionTable optionTable, /* Description of widget record */
Tk_Window tkwin, /* The widget window. */
Ttk_State state, /* Current widget state */
@@ -1097,7 +1094,7 @@ void
Ttk_DrawElement(
Ttk_ElementClass *eclass, /* Element instance */
Ttk_Style style, /* Style settings */
- char *recordPtr, /* The widget record. */
+ void *recordPtr, /* The widget record. */
Tk_OptionTable optionTable, /* Description of option table */
Tk_Window tkwin, /* The widget window. */
Drawable d, /* Where to draw element. */
@@ -1377,7 +1374,7 @@ static int StyleThemeCreateCmd(
ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
StylePackageData *pkgPtr = clientData;
- static const char *optStrings[] =
+ static const char *const optStrings[] =
{ "-parent", "-settings", NULL };
enum { OP_PARENT, OP_SETTINGS };
Ttk_Theme parentTheme = pkgPtr->defaultTheme, newTheme;
diff --git a/generic/ttk/ttkTheme.h b/generic/ttk/ttkTheme.h
index 7bf2a7f..f087ce3 100644
--- a/generic/ttk/ttkTheme.h
+++ b/generic/ttk/ttkTheme.h
@@ -234,11 +234,19 @@ typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord,
typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord,
Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);
+#ifndef TkSizeT
+# if TCL_MAJOR_VERSION > 8
+# define TkSizeT size_t
+# else
+# define TkSizeT int
+# endif
+#endif
+
typedef struct Ttk_ElementOptionSpec
{
const char *optionName; /* Command-line name of the widget option */
Tk_OptionType type; /* Accepted option types */
- int offset; /* Offset of Tcl_Obj* field in element record */
+ TkSizeT offset; /* Offset of Tcl_Obj* field in element record */
const char *defaultValue; /* Default value to used if resource missing */
} Ttk_ElementOptionSpec;
@@ -372,6 +380,8 @@ MODULE_SCOPE void Ttk_RegisterNamedColor(Ttk_ResourceCache, const char *, XColor
typedef struct TtkImageSpec Ttk_ImageSpec;
TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
+TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *,
+ Tk_ImageChangedProc *, ClientData);
TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State);
diff --git a/generic/ttk/ttkThemeInt.h b/generic/ttk/ttkThemeInt.h
index 3aaada8..25a5fdf 100644
--- a/generic/ttk/ttkThemeInt.h
+++ b/generic/ttk/ttkThemeInt.h
@@ -15,11 +15,11 @@ MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name);
MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *);
MODULE_SCOPE void Ttk_ElementSize(
- Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable,
+ Ttk_ElementClass *, Ttk_Style, void *recordPtr, Tk_OptionTable,
Tk_Window tkwin, Ttk_State state,
int *widthPtr, int *heightPtr, Ttk_Padding*);
MODULE_SCOPE void Ttk_DrawElement(
- Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable,
+ Ttk_ElementClass *, Ttk_Style, void *recordPtr, Tk_OptionTable,
Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);
MODULE_SCOPE Tcl_Obj *Ttk_QueryStyle(
diff --git a/generic/ttk/ttkTrace.c b/generic/ttk/ttkTrace.c
index ba66db4..51006f8 100644
--- a/generic/ttk/ttkTrace.c
+++ b/generic/ttk/ttkTrace.c
@@ -3,11 +3,11 @@
*
* Simplified interface to Tcl_TraceVariable.
*
- * PROBLEM: Can't distinguish "variable does not exist" (which is OK)
+ * PROBLEM: Can't distinguish "variable does not exist" (which is OK)
* from other errors (which are not).
*/
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -26,8 +26,8 @@ static char *
VarTraceProc(
ClientData clientData, /* Widget record pointer */
Tcl_Interp *interp, /* Interpreter containing variable. */
- const char *name1, /* (unused) */
- const char *name2, /* (unused) */
+ const char *name1, /* Name of variable. */
+ const char *name2, /* Second part of variable name. */
int flags) /* Information about what happened. */
{
Ttk_TraceHandle *tracePtr = clientData;
@@ -38,6 +38,17 @@ VarTraceProc(
return NULL;
}
+ /*
+ * See ticket [5d991b82].
+ */
+
+ if (tracePtr->varnameObj == NULL) {
+ Tcl_UntraceVar2(interp, name1, name2,
+ TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ VarTraceProc, clientData);
+ return NULL;
+ }
+
name = Tcl_GetString(tracePtr->varnameObj);
/*
diff --git a/generic/ttk/ttkTrack.c b/generic/ttk/ttkTrack.c
index 396b073..fa2a7e0 100644
--- a/generic/ttk/ttkTrack.c
+++ b/generic/ttk/ttkTrack.c
@@ -23,7 +23,7 @@
* TODO: Handle "chords" properly (e.g., <B1-ButtonPress-2>)
*/
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c
index d957ad2..7aad8ae 100644
--- a/generic/ttk/ttkTreeview.c
+++ b/generic/ttk/ttkTreeview.c
@@ -4,9 +4,7 @@
* ttk::treeview widget implementation.
*/
-#include <string.h>
-#include <stdio.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -321,14 +319,14 @@ static Tk_OptionSpec HeadingOptionSpecs[] = {
#define DEFAULT_SHOW "tree headings"
-static const char *showStrings[] = {
+static const char *const showStrings[] = {
"tree", "headings", NULL
};
static int GetEnumSetFromObj(
Tcl_Interp *interp,
Tcl_Obj *objPtr,
- const char *table[],
+ const char *const table[],
unsigned *resultPtr)
{
unsigned result = 0;
@@ -435,7 +433,7 @@ typedef struct {
#define SCROLLCMD_CHANGED (USER_MASK<<2)
#define SHOW_CHANGED (USER_MASK<<3)
-static const char *SelectModeStrings[] = { "none", "browse", "extended", NULL };
+static const char *const SelectModeStrings[] = { "none", "browse", "extended", NULL };
static Tk_OptionSpec TreeviewOptionSpecs[] = {
{TK_OPTION_STRING, "-columns", "columns", "Columns",
@@ -1131,7 +1129,7 @@ static int ConfigureItem(
Ttk_ImageSpec *newImageSpec = NULL;
Ttk_TagSet newTagSet = NULL;
- if (Tk_SetOptions(interp, (ClientData)item, tv->tree.itemOptionTable,
+ if (Tk_SetOptions(interp, item, tv->tree.itemOptionTable,
objc, objv, tv->core.tkwin, &savedOptions, &mask)
!= TCL_OK)
{
@@ -1211,7 +1209,7 @@ static int ConfigureColumn(
Tk_SavedOptions savedOptions;
int mask;
- if (Tk_SetOptions(interp, (ClientData)column,
+ if (Tk_SetOptions(interp, column,
tv->tree.columnOptionTable, objc, objv, tv->core.tkwin,
&savedOptions,&mask) != TCL_OK)
{
@@ -1257,7 +1255,7 @@ static int ConfigureHeading(
Tk_SavedOptions savedOptions;
int mask;
- if (Tk_SetOptions(interp, (ClientData)column,
+ if (Tk_SetOptions(interp, column,
tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
&savedOptions,&mask) != TCL_OK)
{
@@ -1503,7 +1501,7 @@ typedef enum {
REGION_CELL
} TreeRegion;
-static const char *regionStrings[] = {
+static const char *const regionStrings[] = {
"nothing", "heading", "separator", "tree", "cell", 0
};
@@ -1825,7 +1823,7 @@ static int DrawSubtree(
static int DrawForest(
Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
- while (item && row <= tv->tree.yscroll.last) {
+ while (item && row < tv->tree.yscroll.last) {
row = DrawSubtree(tv, item, d, depth, row);
item = item->next;
}
@@ -2266,7 +2264,7 @@ done:
static int TreeviewIdentifyCommand(
void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
- static const char *submethodStrings[] =
+ static const char *const submethodStrings[] =
{ "region", "item", "column", "row", "element", NULL };
enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT };
@@ -2932,7 +2930,7 @@ static int TreeviewSelectionCommand(
enum {
SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE
};
- static const char *selopStrings[] = {
+ static const char *const selopStrings[] = {
"set", "add", "remove", "toggle", NULL
};
diff --git a/generic/ttk/ttkWidget.c b/generic/ttk/ttkWidget.c
index c50efc5..c2f8d60 100644
--- a/generic/ttk/ttkWidget.c
+++ b/generic/ttk/ttkWidget.c
@@ -4,8 +4,7 @@
* Core widget utilities.
*/
-#include <string.h>
-#include <tk.h>
+#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -757,7 +756,7 @@ int TtkWidgetIdentifyCommand(
{
WidgetCore *corePtr = recordPtr;
Ttk_Element element;
- static const char *whatTable[] = { "element", NULL };
+ static const char *const whatTable[] = { "element", NULL };
int x, y, what;
if (objc < 4 || objc > 5) {
diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h
index e4dd712..798bcce 100644
--- a/generic/ttk/ttkWidget.h
+++ b/generic/ttk/ttkWidget.h
@@ -111,8 +111,8 @@ MODULE_SCOPE int TtkWidgetConstructorObjCmd(
/* WIDGET_TAKEFOCUS_TRUE --
* WIDGET_TAKEFOCUS_FALSE --
- * Add one or the other of these to each OptionSpecs table
- * to indicate whether the widget should take focus
+ * Add one or the other of these to each OptionSpecs table
+ * to indicate whether the widget should take focus
* during keyboard traversal.
*/
#define WIDGET_TAKEFOCUS_TRUE \