summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2016-03-04 15:41:59 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2016-03-04 15:41:59 (GMT)
commit42e3af0d0ae489a65f7f3ce98429a394c0926c32 (patch)
tree0149222f25fa8bd0c3a1cb50b3e71a5419cf6021 /generic
parent3fa224a2450a99a43c66f5f85951bcadb65430c2 (diff)
parent2fd9fcf08d73f688888ef8784be0c5493b80d818 (diff)
downloadtk-42e3af0d0ae489a65f7f3ce98429a394c0926c32.zip
tk-42e3af0d0ae489a65f7f3ce98429a394c0926c32.tar.gz
tk-42e3af0d0ae489a65f7f3ce98429a394c0926c32.tar.bz2
merge trunktip_415
Diffstat (limited to 'generic')
-rw-r--r--generic/default.h3
-rw-r--r--generic/tk.decls7
-rw-r--r--generic/tk.h41
-rw-r--r--generic/tk3d.c4
-rw-r--r--generic/tkBind.c62
-rw-r--r--generic/tkBitmap.c2
-rw-r--r--generic/tkBusy.c18
-rw-r--r--generic/tkButton.c38
-rw-r--r--generic/tkCanvArc.c14
-rw-r--r--generic/tkCanvLine.c5
-rw-r--r--generic/tkCanvPoly.c5
-rw-r--r--generic/tkCanvPs.c14
-rw-r--r--generic/tkCanvUtil.c2
-rw-r--r--generic/tkCanvas.c39
-rw-r--r--generic/tkCmds.c34
-rw-r--r--generic/tkColor.c4
-rw-r--r--generic/tkConfig.c184
-rw-r--r--generic/tkConsole.c26
-rw-r--r--generic/tkDecls.h22
-rw-r--r--generic/tkEntry.c221
-rw-r--r--generic/tkEvent.c10
-rw-r--r--generic/tkFocus.c4
-rw-r--r--generic/tkFont.c96
-rw-r--r--generic/tkFrame.c14
-rw-r--r--generic/tkGrab.c4
-rw-r--r--generic/tkGrid.c40
-rw-r--r--generic/tkImage.c8
-rw-r--r--generic/tkImgBmap.c8
-rw-r--r--generic/tkImgGIF.c24
-rw-r--r--generic/tkImgPNG.c65
-rw-r--r--generic/tkImgPPM.c58
-rw-r--r--generic/tkImgPhInstance.c22
-rw-r--r--generic/tkImgPhoto.c78
-rw-r--r--generic/tkImgPhoto.h2
-rw-r--r--generic/tkInt.decls22
-rw-r--r--generic/tkInt.h23
-rw-r--r--generic/tkIntDecls.h34
-rw-r--r--generic/tkIntPlatDecls.h48
-rw-r--r--generic/tkIntXlibDecls.h16
-rw-r--r--generic/tkListbox.c209
-rw-r--r--generic/tkMain.c42
-rw-r--r--generic/tkMenu.c187
-rw-r--r--generic/tkMenu.h16
-rw-r--r--generic/tkMenubutton.c20
-rw-r--r--generic/tkMessage.c20
-rw-r--r--generic/tkObj.c49
-rw-r--r--generic/tkOldConfig.c12
-rw-r--r--generic/tkOldTest.c54
-rw-r--r--generic/tkOption.c60
-rw-r--r--generic/tkPack.c46
-rw-r--r--generic/tkPanedWindow.c111
-rw-r--r--generic/tkPlace.c4
-rw-r--r--generic/tkPlatDecls.h16
-rw-r--r--generic/tkPointer.c2
-rw-r--r--generic/tkRectOval.c4
-rw-r--r--generic/tkScale.c27
-rw-r--r--generic/tkScale.h6
-rw-r--r--generic/tkScrollbar.c226
-rw-r--r--generic/tkSelect.c2
-rw-r--r--generic/tkSquare.c12
-rw-r--r--generic/tkStubInit.c39
-rw-r--r--generic/tkStubLib.c107
-rw-r--r--generic/tkStyle.c16
-rw-r--r--generic/tkTest.c292
-rw-r--r--generic/tkText.c319
-rw-r--r--generic/tkText.h8
-rw-r--r--generic/tkTextBTree.c21
-rw-r--r--generic/tkTextDisp.c866
-rw-r--r--generic/tkTextImage.c8
-rw-r--r--generic/tkTextIndex.c140
-rw-r--r--generic/tkTextMark.c22
-rw-r--r--generic/tkTextTag.c22
-rw-r--r--generic/tkTextWind.c32
-rw-r--r--generic/tkUndo.c2
-rw-r--r--generic/tkUtil.c9
-rw-r--r--generic/tkWindow.c91
-rw-r--r--generic/ttk/ttkButton.c4
-rw-r--r--generic/ttk/ttkCache.c4
-rw-r--r--generic/ttk/ttkClamTheme.c2
-rw-r--r--generic/ttk/ttkDecls.h12
-rw-r--r--generic/ttk/ttkDefaultTheme.c6
-rw-r--r--generic/ttk/ttkElements.c4
-rw-r--r--generic/ttk/ttkEntry.c20
-rw-r--r--generic/ttk/ttkGenStubs.tcl29
-rw-r--r--generic/ttk/ttkImage.c6
-rw-r--r--generic/ttk/ttkInit.c25
-rw-r--r--generic/ttk/ttkLabel.c3
-rw-r--r--generic/ttk/ttkLayout.c8
-rw-r--r--generic/ttk/ttkManager.c2
-rw-r--r--generic/ttk/ttkNotebook.c7
-rw-r--r--generic/ttk/ttkPanedwindow.c5
-rw-r--r--generic/ttk/ttkScroll.c24
-rw-r--r--generic/ttk/ttkTheme.c11
-rw-r--r--generic/ttk/ttkTrace.c10
-rw-r--r--generic/ttk/ttkTreeview.c17
-rw-r--r--generic/ttk/ttkWidget.c8
-rw-r--r--generic/ttk/ttkWidget.h2
97 files changed, 2783 insertions, 1866 deletions
diff --git a/generic/default.h b/generic/default.h
index 6156f4d..e6ef132 100644
--- a/generic/default.h
+++ b/generic/default.h
@@ -14,8 +14,7 @@
#ifndef _DEFAULT
#define _DEFAULT
-#if defined(__WIN32__) || defined(_WIN32) || \
- defined(__MINGW32__)
+#ifdef _WIN32
# include "tkWinDefault.h"
#else
# if defined(MAC_OSX_TK)
diff --git a/generic/tk.decls b/generic/tk.decls
index 11b4f87..9ceb3af 100644
--- a/generic/tk.decls
+++ b/generic/tk.decls
@@ -1069,13 +1069,6 @@ declare 273 {
void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}
-declare 274 {
- void reserved274(void)
-}
-declare 275 {
- void reserved275(void)
-}
-
# Define the platform specific public Tk interface. These functions are
# only available on the designated platform.
diff --git a/generic/tk.h b/generic/tk.h
index add2822..6abb05e 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -18,9 +18,34 @@
#include <tcl.h>
#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6)
-# error Tk 8.6 must be compiled with tcl.h from Tcl 8.6 or better
+# 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
+
+/*
+ * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
+ * quotation marks), JOIN joins two arguments.
+ */
+
+#ifndef STRINGIFY
+# define STRINGIFY(x) STRINGIFY1(x)
+# define STRINGIFY1(x) #x
+#endif
+#ifndef JOIN
+# define JOIN(a,b) JOIN1(a,b)
+# define JOIN1(a,b) a##b
+#endif
+
/*
* For C++ compilers, use extern "C"
*/
@@ -48,12 +73,12 @@ extern "C" {
*/
#define TK_MAJOR_VERSION 8
-#define TK_MINOR_VERSION 6
-#define TK_RELEASE_LEVEL TCL_BETA_RELEASE
-#define TK_RELEASE_SERIAL 3
+#define TK_MINOR_VERSION 7
+#define TK_RELEASE_LEVEL TCL_ALPHA_RELEASE
+#define TK_RELEASE_SERIAL 0
-#define TK_VERSION "8.6"
-#define TK_PATCH_LEVEL "8.6b3"
+#define TK_VERSION "8.7"
+#define TK_PATCH_LEVEL "8.7a0"
/*
* A special definition used to allow this header file to be included from
@@ -1471,7 +1496,7 @@ typedef struct Tk_ElementSpec {
#define Tk_Release Tcl_Release
/* Removed Tk_Main, use macro instead */
-#if defined(__WIN32__) || defined(__CYGWIN__)
+#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
diff --git a/generic/tk3d.c b/generic/tk3d.c
index dd7ab2f..87ddf76 100644
--- a/generic/tk3d.c
+++ b/generic/tk3d.c
@@ -624,8 +624,8 @@ Tk_GetReliefFromObj(
* from. */
int *resultPtr) /* Where to place the answer. */
{
- return Tcl_GetIndexFromObj(interp, objPtr, reliefStrings, "relief", 0,
- resultPtr);
+ return Tcl_GetIndexFromObjStruct(interp, objPtr, reliefStrings,
+ sizeof(char *), "relief", 0, resultPtr);
}
/*
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 7126e24..9cd3b7b 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -14,11 +14,11 @@
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
-#endif
-
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* UNIX */
+#elif defined(MAC_OSX_TK)
+#include "tkMacOSXInt.h"
+#else
#include "tkUnixInt.h"
#endif
@@ -167,7 +167,7 @@ typedef struct {
* button (0 means any buttons are OK). For
* virtual events, specifies the Tk_Uid of the
* virtual event name (never 0). */
-} Pattern;
+} TkPattern;
/*
* The following structure defines a pattern sequence, which consists of one
@@ -209,7 +209,7 @@ typedef struct PatSeq {
* for end of list). Needed to implement
* Tk_DeleteAllBindings. In a virtual event
* table, always NULL. */
- Pattern pats[1]; /* Array of "numPats" patterns. Only one
+ TkPattern pats[1]; /* Array of "numPats" patterns. Only one
* element is declared here but in actuality
* enough space will be allocated for
* "numPats" patterns. To match, pats[0] must
@@ -612,7 +612,8 @@ static int DeleteVirtualEvent(Tcl_Interp *interp,
const char *eventString);
static void DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void ExpandPercents(TkWindow *winPtr, const char *before,
- XEvent *eventPtr,KeySym keySym,Tcl_DString *dsPtr);
+ XEvent *eventPtr,KeySym keySym,
+ unsigned int scriptCount, Tcl_DString *dsPtr);
static PatSeq * FindSequence(Tcl_Interp *interp,
Tcl_HashTable *patternTablePtr, ClientData object,
const char *eventString, int create,
@@ -635,7 +636,7 @@ static PatSeq * MatchPatterns(TkDisplay *dispPtr,
static int NameToWindow(Tcl_Interp *interp, Tk_Window main,
Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static int ParseEventDescription(Tcl_Interp *interp,
- const char **eventStringPtr, Pattern *patPtr,
+ const char **eventStringPtr, TkPattern *patPtr,
unsigned long *eventMaskPtr);
static void DoWarp(ClientData clientData);
@@ -1221,6 +1222,7 @@ Tk_BindEvent(
XEvent *ringPtr;
PatSeq *vMatchDetailList, *vMatchNoDetailList;
int flags, oldScreen;
+ unsigned int scriptCount;
Tcl_Interp *interp;
Tcl_DString scripts;
Tcl_InterpState interpState;
@@ -1372,6 +1374,7 @@ Tk_BindEvent(
* each object.
*/
+ scriptCount = 0;
Tcl_DStringInit(&scripts);
for ( ; numObjects > 0; numObjects--, objectPtr++) {
@@ -1421,7 +1424,7 @@ Tk_BindEvent(
if (matchPtr != NULL) {
ExpandPercents(winPtr, sourcePtr->script, eventPtr,
- detail.keySym, &scripts);
+ detail.keySym, scriptCount++, &scripts);
/*
* A "" is added to the scripts string to separate the various
@@ -1601,7 +1604,7 @@ MatchPatterns(
for ( ; psPtr != NULL; psPtr = psPtr->nextSeqPtr) {
XEvent *eventPtr = &bindPtr->eventRing[bindPtr->curEvent];
Detail *detailPtr = &bindPtr->detailRing[bindPtr->curEvent];
- Pattern *patPtr = psPtr->pats;
+ TkPattern *patPtr = psPtr->pats;
Window window = eventPtr->xany.window;
int patCount, ringCount, flags, state, modMask, i;
@@ -1815,7 +1818,7 @@ MatchPatterns(
*/
if (bestPtr != NULL) {
- Pattern *patPtr2;
+ TkPattern *patPtr2;
if (matchPtr->numPats != bestPtr->numPats) {
if (bestPtr->numPats > matchPtr->numPats) {
@@ -1903,6 +1906,8 @@ ExpandPercents(
* in % replacements. */
KeySym keySym, /* KeySym: only relevant for KeyPress and
* KeyRelease events). */
+ unsigned int scriptCount, /* The number of script-based binding patterns
+ * matched so far for this event. */
Tcl_DString *dsPtr) /* Dynamic string in which to append new
* command. */
{
@@ -2184,6 +2189,9 @@ ExpandPercents(
}
}
goto doString;
+ case 'M':
+ number = scriptCount;
+ goto doNumber;
case 'N':
if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
number = (int) keySym;
@@ -2297,7 +2305,7 @@ ChangeScreen(
int code;
Tcl_IncrRefCount(cmdObj);
- code = Tcl_GlobalEvalObj(interp, cmdObj);
+ code = Tcl_EvalObjEx(interp, cmdObj, TCL_EVAL_GLOBAL);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (changing screen in event binding)");
@@ -2349,8 +2357,8 @@ Tk_EventObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -2643,7 +2651,7 @@ DeleteVirtualEvent(
eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL,
eventString, 0, 0, &eventMask);
if (eventPSPtr == NULL) {
- const char *string = Tcl_GetStringResult(interp);
+ const char *string = Tcl_GetString(Tcl_GetObjResult(interp));
return (string[0] != '\0') ? TCL_ERROR : TCL_OK;
}
@@ -2879,7 +2887,7 @@ HandleEventGenerate(
const char *name, *windowName;
int count, flags, synch, i, number, warp;
Tcl_QueuePosition pos;
- Pattern pat;
+ TkPattern pat;
Tk_Window tkwin, tkwin2;
TkWindow *mainPtr;
unsigned long eventMask;
@@ -3006,8 +3014,8 @@ HandleEventGenerate(
optionPtr = objv[i];
valuePtr = objv[i + 1];
- if (Tcl_GetIndexFromObj(interp, optionPtr, fieldStrings, "option",
- TCL_EXACT, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
+ sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
}
if (objc & 1) {
@@ -3618,10 +3626,10 @@ FindSequence(
unsigned long *maskPtr) /* *maskPtr is filled in with the event types
* on which this pattern sequence depends. */
{
- Pattern pats[EVENT_BUFFER_SIZE];
+ TkPattern pats[EVENT_BUFFER_SIZE];
int numPats, virtualFound;
const char *p;
- Pattern *patPtr;
+ TkPattern *patPtr;
PatSeq *psPtr;
Tcl_HashEntry *hPtr;
int flags, count, isNew;
@@ -3707,7 +3715,7 @@ FindSequence(
key.type = patPtr->eventType;
key.detail = patPtr->detail;
hPtr = Tcl_CreateHashEntry(patternTablePtr, (char *) &key, &isNew);
- sequenceSize = numPats*sizeof(Pattern);
+ sequenceSize = numPats*sizeof(TkPattern);
if (!isNew) {
for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = psPtr->nextSeqPtr) {
@@ -3733,7 +3741,7 @@ FindSequence(
return NULL;
}
- psPtr = ckalloc(sizeof(PatSeq) + (numPats-1)*sizeof(Pattern));
+ psPtr = ckalloc(sizeof(PatSeq) + (numPats-1)*sizeof(TkPattern));
psPtr->numPats = numPats;
psPtr->script = NULL;
psPtr->flags = flags;
@@ -3777,7 +3785,7 @@ ParseEventDescription(
const char **eventStringPtr,/* On input, holds a pointer to start of event
* string. On exit, gets pointer to rest of
* string after parsed event. */
- Pattern *patPtr, /* Filled with the pattern parsed from the
+ TkPattern *patPtr, /* Filled with the pattern parsed from the
* event string. */
unsigned long *eventMaskPtr)/* Filled with event mask of matched event. */
{
@@ -4065,7 +4073,7 @@ static Tcl_Obj *
GetPatternObj(
PatSeq *psPtr)
{
- Pattern *patPtr;
+ TkPattern *patPtr;
int patsLeft, needMods;
const ModInfo *modPtr;
const EventInfo *eiPtr;
@@ -4113,15 +4121,15 @@ GetPatternObj(
Tcl_AppendToObj(patternObj, "<", 1);
if ((psPtr->flags & PAT_NEARBY) && (patsLeft > 1)
- && (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
+ && (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) {
patsLeft--;
patPtr--;
if ((patsLeft > 1) &&
- (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
+ (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) {
patsLeft--;
patPtr--;
if ((patsLeft > 1) &&
- (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
+ (memcmp(patPtr, patPtr-1, sizeof(TkPattern)) == 0)) {
patsLeft--;
patPtr--;
Tcl_AppendToObj(patternObj, "Quadruple-", 10);
diff --git a/generic/tkBitmap.c b/generic/tkBitmap.c
index 729fff4..88f3e2b 100644
--- a/generic/tkBitmap.c
+++ b/generic/tkBitmap.c
@@ -305,7 +305,7 @@ GetBitmap(
TkBitmap *bitmapPtr, *existingBitmapPtr;
TkPredefBitmap *predefPtr;
Pixmap bitmap;
- int isNew, width, height, dummy2;
+ int isNew, width = 0, height = 0, dummy2;
TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
ThreadSpecificData *tsdPtr =
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
diff --git a/generic/tkBusy.c b/generic/tkBusy.c
index 8f73d80..65248a2 100644
--- a/generic/tkBusy.c
+++ b/generic/tkBusy.c
@@ -43,7 +43,7 @@ static void BusyCustodyProc(ClientData clientData,
static int ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
int objc, Tcl_Obj *const objv[]);
static Busy * CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
-static void DestroyBusy(char *dataPtr);
+static void DestroyBusy(void *dataPtr);
static void DoConfigureNotify(Tk_FakeWin *winPtr);
static inline Tk_Window FirstChild(Tk_Window parent);
static Busy * GetBusy(Tcl_Interp *interp,
@@ -136,7 +136,7 @@ BusyCustodyProc(
busyPtr);
TkpHideBusyWindow(busyPtr);
busyPtr->tkBusy = NULL;
- Tcl_EventuallyFree(busyPtr, DestroyBusy);
+ Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}
/*
@@ -262,7 +262,7 @@ RefWinEventProc(
* Arrange for the busy structure to be removed at a proper time.
*/
- Tcl_EventuallyFree(busyPtr, DestroyBusy);
+ Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
break;
case ConfigureNotify:
@@ -333,9 +333,9 @@ RefWinEventProc(
static void
DestroyBusy(
- char *data) /* Busy window structure record */
+ void *data) /* Busy window structure record */
{
- register Busy *busyPtr = (Busy *) data;
+ register Busy *busyPtr = data;
if (busyPtr->hashPtr != NULL) {
Tcl_DeleteHashEntry(busyPtr->hashPtr);
@@ -383,7 +383,7 @@ BusyEventProc(
if (eventPtr->type == DestroyNotify) {
busyPtr->tkBusy = NULL;
- Tcl_EventuallyFree(busyPtr, DestroyBusy);
+ Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}
}
@@ -816,8 +816,8 @@ Tk_BusyObjCmd(
return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2);
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum options) index) {
@@ -895,7 +895,7 @@ Tk_BusyObjCmd(
return TCL_ERROR;
}
TkpHideBusyWindow(busyPtr);
- Tcl_EventuallyFree(busyPtr, DestroyBusy);
+ Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
return TCL_OK;
case BUSY_HOLD:
diff --git a/generic/tkButton.c b/generic/tkButton.c
index e2c754e..b7e314e 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -797,8 +797,8 @@ ButtonWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- result = Tcl_GetIndexFromObj(interp, objv[1], commandNames[butPtr->type],
- "option", 0, &index);
+ result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames[butPtr->type],
+ sizeof(char *), "option", 0, &index);
if (result != TCL_OK) {
return result;
}
@@ -962,8 +962,8 @@ DestroyButton(
Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd);
if (butPtr->textVarNamePtr != NULL) {
- Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, butPtr);
}
if (butPtr->image != NULL) {
@@ -997,8 +997,8 @@ DestroyButton(
Tk_FreeTextLayout(butPtr->textLayout);
}
if (butPtr->selVarNamePtr != NULL) {
- Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, butPtr);
}
Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable,
@@ -1045,13 +1045,13 @@ ConfigureButton(
*/
if (butPtr->textVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, butPtr);
}
if (butPtr->selVarNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, butPtr);
}
@@ -1297,13 +1297,13 @@ ConfigureButton(
*/
if (butPtr->textVarNamePtr != NULL) {
- Tcl_TraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, butPtr);
}
if (butPtr->selVarNamePtr != NULL) {
- Tcl_TraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, butPtr);
}
@@ -1618,8 +1618,8 @@ ButtonVarProc(
if (flags & TCL_TRACE_UNSETS) {
butPtr->flags &= ~(SELECTED | TRISTATED);
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_TraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(butPtr->selVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonVarProc, clientData);
}
goto redisplay;
@@ -1643,7 +1643,7 @@ ButtonVarProc(
}
butPtr->flags |= SELECTED;
butPtr->flags &= ~TRISTATED;
- } else if (butPtr->offValuePtr
+ } else if (butPtr->offValuePtr
&& strcmp(value, Tcl_GetString(butPtr->offValuePtr)) == 0) {
if (!(butPtr->flags & (SELECTED | TRISTATED))) {
return NULL;
@@ -1712,8 +1712,8 @@ ButtonTextVarProc(
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
Tcl_ObjSetVar2(interp, butPtr->textVarNamePtr, NULL,
butPtr->textPtr, TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(butPtr->textVarNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ButtonTextVarProc, clientData);
}
return NULL;
diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c
index dfa0671..ef2ef72 100644
--- a/generic/tkCanvArc.c
+++ b/generic/tkCanvArc.c
@@ -300,7 +300,7 @@ CreateArc(
arcPtr->fillGC = None;
arcPtr->height = 0;
-
+
/*
* Process the arguments to fill in the item record.
*/
@@ -392,7 +392,7 @@ ArcCoords(
arcPtr->startPoint[1] = arcPtr->bbox[1];
arcPtr->endPoint[0] = arcPtr->bbox[2];
arcPtr->endPoint[1] = arcPtr->bbox[3];
-
+
ComputeArcBbox(canvas, arcPtr);
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -474,7 +474,7 @@ ConfigureArc(
ComputeArcFromHeight(arcPtr);
ComputeArcBbox(canvas, arcPtr);
}
-
+
i = (int) (arcPtr->start/360.0);
arcPtr->start -= i*360.0;
if (arcPtr->start < 0) {
@@ -499,7 +499,7 @@ ConfigureArc(
} else if (flags & TK_OFFSET_BOTTOM) {
tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
}
-
+
mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
if (mask) {
gcValues.cap_style = CapButt;
@@ -606,14 +606,14 @@ ComputeArcFromHeight(
ArcItem* arcPtr)
{
double chordLen, chordDir[2], chordCen[2], arcCen[2], d, radToDeg, radius;
-
+
/* The chord */
chordLen = hypot(arcPtr->endPoint[1]-arcPtr->startPoint[1], arcPtr->startPoint[0]-arcPtr->endPoint[0]);
chordDir[0] = (arcPtr->endPoint[0]-arcPtr->startPoint[0])/chordLen;
chordDir[1] = (arcPtr->endPoint[1]-arcPtr->startPoint[1])/chordLen;
chordCen[0] = (arcPtr->startPoint[0]+arcPtr->endPoint[0])/2;
chordCen[1] = (arcPtr->startPoint[1]+arcPtr->endPoint[1])/2;
-
+
/* Calculate the radius (assumes height != 0) */
radius = (4*pow(arcPtr->height,2) + pow(chordLen,2))/(8*arcPtr->height);
@@ -640,7 +640,7 @@ ComputeArcFromHeight(
/* Set the height to 0 so that itemcget -height returns 0 */
arcPtr->height = 0;
-
+
}
/*
diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c
index 9d68c37..087aa56 100644
--- a/generic/tkCanvLine.c
+++ b/generic/tkCanvLine.c
@@ -1743,11 +1743,10 @@ GetLineIndex(
int *indexPtr) /* Where to store converted index. */
{
LineItem *linePtr = (LineItem *) itemPtr;
- int length;
- const char *string = Tcl_GetStringFromObj(obj, &length);
+ const char *string = Tcl_GetString(obj);
if (string[0] == 'e') {
- if (strncmp(string, "end", (unsigned) length) == 0) {
+ if (strncmp(string, "end", obj->length) == 0) {
*indexPtr = 2*linePtr->numPoints;
} else {
goto badIndex;
diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c
index f8ea42b..b4ef098 100644
--- a/generic/tkCanvPoly.c
+++ b/generic/tkCanvPoly.c
@@ -1673,11 +1673,10 @@ GetPolygonIndex(
int *indexPtr) /* Where to store converted index. */
{
PolygonItem *polyPtr = (PolygonItem *) itemPtr;
- int length;
- const char *string = Tcl_GetStringFromObj(obj, &length);
+ const char *string = Tcl_GetString(obj);
if (string[0] == 'e') {
- if (strncmp(string, "end", (unsigned)length) != 0) {
+ if (strncmp(string, "end", obj->length) != 0) {
goto badIndex;
}
*indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c
index 0c7b0dd..c6470dd 100644
--- a/generic/tkCanvPs.c
+++ b/generic/tkCanvPs.c
@@ -193,7 +193,7 @@ TkCanvPostscriptCmd(
* such.
*/
- result = Tcl_Eval(interp, "::tk::ensure_psenc_is_loaded");
+ result = Tcl_EvalEx(interp, "::tk::ensure_psenc_is_loaded", -1, 0);
if (result != TCL_OK) {
return result;
}
@@ -1168,7 +1168,7 @@ GetPostscriptPoints(
*--------------------------------------------------------------
*/
-#ifdef WIN32
+#ifdef _WIN32
#include <windows.h>
/*
@@ -1178,15 +1178,15 @@ GetPostscriptPoints(
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
*/
-#else /* !WIN32 */
+#else /* !_WIN32 */
#define GetRValue(rgb) ((rgb & cdata->red_mask) >> cdata->red_shift)
#define GetGValue(rgb) ((rgb & cdata->green_mask) >> cdata->green_shift)
#define GetBValue(rgb) ((rgb & cdata->blue_mask) >> cdata->blue_shift)
-#endif /* WIN32 */
+#endif /* _WIN32 */
-#if defined(WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32) || defined(MAC_OSX_TK)
static void
TkImageGetColor(
TkColormapData *cdata, /* Colormap data */
@@ -1198,7 +1198,7 @@ TkImageGetColor(
*green = (double) GetGValue(pixel) / 255.0;
*blue = (double) GetBValue(pixel) / 255.0;
}
-#else /* ! (WIN32 || MAC_OSX_TK) */
+#else /* ! (_WIN32 || MAC_OSX_TK) */
static void
TkImageGetColor(
TkColormapData *cdata, /* Colormap data */
@@ -1220,7 +1220,7 @@ TkImageGetColor(
*blue = cdata->colors[pixel].blue / 65535.0;
}
}
-#endif /* WIN32 || MAC_OSX_TK */
+#endif /* _WIN32 || MAC_OSX_TK */
/*
*--------------------------------------------------------------
diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c
index 23c73e5..cbbc2b4 100644
--- a/generic/tkCanvUtil.c
+++ b/generic/tkCanvUtil.c
@@ -1432,7 +1432,7 @@ Tk_CanvasPsOutline(
char *p = ptr;
converted = Tcl_ObjPrintf("%d", *p++ & 0xff);
- for (i = dash->number-1 ; i>=0 ; i--) {
+ for (i = dash->number-1 ; i>0 ; i--) {
Tcl_AppendPrintfToObj(converted, " %d", *p++ & 0xff);
}
Tcl_AppendObjToObj(psObj, converted);
diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c
index 07f1cfe..9c4d60a 100644
--- a/generic/tkCanvas.c
+++ b/generic/tkCanvas.c
@@ -1047,7 +1047,7 @@ CanvasWidgetCmd(
command = Tk_GetBinding(interp, canvasPtr->bindingTable,
object, Tcl_GetString(objv[3]));
if (command == NULL) {
- const char *string = Tcl_GetStringResult(interp);
+ const char *string = Tcl_GetString(Tcl_GetObjResult(interp));
/*
* Ignore missing binding errors. This is a special hack that
@@ -1242,14 +1242,15 @@ CanvasWidgetCmd(
int isNew = 0;
Tcl_HashEntry *entryPtr;
const char *arg;
- int length;
+ size_t length;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
result = TCL_ERROR;
goto done;
}
- arg = Tcl_GetStringFromObj(objv[2], &length);
+ arg = Tcl_GetString(objv[2]);
+ length = objv[2]->length;
c = arg[0];
/*
@@ -1261,7 +1262,7 @@ CanvasWidgetCmd(
Tcl_MutexLock(&typeListMutex);
for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr){
if ((c == typePtr->name[0])
- && (!strncmp(arg, typePtr->name, (unsigned)length))) {
+ && (!strncmp(arg, typePtr->name, length))) {
if (matchPtr != NULL) {
Tcl_MutexUnlock(&typeListMutex);
goto badType;
@@ -2446,6 +2447,19 @@ DisplayCanvas(
goto done;
}
+#ifdef MAC_OSX_TK
+ /*
+ * If drawing is disabled, all we need to do is
+ * clear the REDRAW_PENDING flag.
+ */
+ TkWindow *winPtr = (TkWindow *)(canvasPtr->tkwin);
+ MacDrawable *macWin = winPtr->privatePtr;
+ if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
+ canvasPtr->flags &= ~REDRAW_PENDING;
+ return;
+ }
+#endif
+
/*
* Choose a new current item if that is needed (this could cause event
* handlers to be invoked).
@@ -5539,6 +5553,7 @@ CanvasUpdateScrollbars(
int xOrigin, yOrigin, inset, width, height;
int scrollX1, scrollX2, scrollY1, scrollY2;
char *xScrollCmd, *yScrollCmd;
+ Tcl_DString buf;
/*
* Save all the relevant values from the canvasPtr, because it might be
@@ -5569,8 +5584,12 @@ CanvasUpdateScrollbars(
Tcl_Obj *fractions = ScrollFractions(xOrigin + inset,
xOrigin + width - inset, scrollX1, scrollX2);
- result = Tcl_VarEval(interp, xScrollCmd," ",Tcl_GetString(fractions),
- NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, xScrollCmd, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
+ result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
Tcl_DecrRefCount(fractions);
if (result != TCL_OK) {
Tcl_BackgroundException(interp, result);
@@ -5583,8 +5602,12 @@ CanvasUpdateScrollbars(
Tcl_Obj *fractions = ScrollFractions(yOrigin + inset,
yOrigin + height - inset, scrollY1, scrollY2);
- result = Tcl_VarEval(interp, yScrollCmd," ",Tcl_GetString(fractions),
- NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, yScrollCmd, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, Tcl_GetString(fractions), -1);
+ result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
Tcl_DecrRefCount(fractions);
if (result != TCL_OK) {
Tcl_BackgroundException(interp, result);
diff --git a/generic/tkCmds.c b/generic/tkCmds.c
index 4e9494b..6196b17 100644
--- a/generic/tkCmds.c
+++ b/generic/tkCmds.c
@@ -14,7 +14,7 @@
#include "tkInt.h"
-#if defined(WIN32)
+#if defined(_WIN32)
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
@@ -49,7 +49,7 @@ static int WindowingsystemCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
+#if defined(_WIN32) || defined(MAC_OSX_TK)
MODULE_SCOPE const TkEnsemble tkFontchooserEnsemble[];
#else
#define tkFontchooserEnsemble NULL
@@ -109,8 +109,8 @@ Tk_BellObjCmd(
}
for (i = 1; i < objc; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], bellOptions, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], bellOptions,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum options) index) {
@@ -452,7 +452,7 @@ TkFreeBindingTags(
* have to be freed.
*/
- ckfree(p);
+ ckfree((char *)p);
}
}
ckfree(winPtr->tagPtr);
@@ -649,7 +649,7 @@ TkInitTkCmd(
ClientData clientData)
{
TkMakeEnsemble(interp, "::", "tk", clientData, tkCmdMap);
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
+#if defined(_WIN32) || defined(MAC_OSX_TK)
TkInitFontchooser(interp, clientData);
#endif
return TCL_OK;
@@ -914,7 +914,7 @@ WindowingsystemCmd(
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
-#if defined(WIN32)
+#if defined(_WIN32)
windowingsystem = "win32";
#elif defined(MAC_OSX_TK)
windowingsystem = "aqua";
@@ -1018,8 +1018,8 @@ Tk_TkwaitObjCmd(
switch ((enum options) index) {
case TKWAIT_VARIABLE:
- if (Tcl_TraceVar(interp, Tcl_GetString(objv[2]),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ if (Tcl_TraceVar2(interp, Tcl_GetString(objv[2]),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
WaitVariableProc, &done) != TCL_OK) {
return TCL_ERROR;
}
@@ -1031,8 +1031,8 @@ Tk_TkwaitObjCmd(
}
Tcl_DoOneEvent(0);
}
- Tcl_UntraceVar(interp, Tcl_GetString(objv[2]),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(interp, Tcl_GetString(objv[2]),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
WaitVariableProc, &done);
break;
@@ -2094,7 +2094,7 @@ TkGetDisplayOf(
/*
*----------------------------------------------------------------------
*
- * TkDeadAppCmd --
+ * TkDeadAppObjCmd --
*
* If an application has been deleted then all Tk commands will be
* re-bound to this function.
@@ -2111,15 +2111,15 @@ TkGetDisplayOf(
/* ARGSUSED */
int
-TkDeadAppCmd(
+TkDeadAppObjCmd(
ClientData clientData, /* Dummy. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't invoke \"%s\" command: application has been destroyed",
- argv[0]));
+ "can't invoke \"%s\" command: application has been destroyed",
+ Tcl_GetString(objv[0])));
return TCL_ERROR;
}
diff --git a/generic/tkColor.c b/generic/tkColor.c
index e4fa3f7..9abb448 100644
--- a/generic/tkColor.c
+++ b/generic/tkColor.c
@@ -829,7 +829,7 @@ TkDebugColor(
return resultPtr;
}
-#ifndef __WIN32__
+#ifndef _WIN32
/* This function is not necessary for Win32,
* since XParseColor already does the right thing */
@@ -937,7 +937,7 @@ TkParseColor(
done:
return XParseColor(display, map, name, color);
}
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
/*
* Local Variables:
* mode: c
diff --git a/generic/tkConfig.c b/generic/tkConfig.c
index b3e76d2..9c159e6 100644
--- a/generic/tkConfig.c
+++ b/generic/tkConfig.c
@@ -27,11 +27,16 @@
#include "tkFont.h"
/*
- * The following definition is an AssocData key used to keep track of all of
- * the option tables that have been created for an interpreter.
+ * The following definition keeps track of all of
+ * the option tables that have been created for a thread.
*/
-#define OPTION_HASH_KEY "TkOptionTable"
+typedef struct ThreadSpecificData {
+ int initialized; /* 0 means table below needs initializing. */
+ Tcl_HashTable hashTable;
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
/*
* The following two structures are used along with Tk_OptionSpec structures
@@ -100,8 +105,6 @@ typedef struct OptionTable {
* chain. */
int numOptions; /* The number of items in the options array
* below. */
- int refCount2; /* Reference counter for controlling the freeing
- * of the memory occupied by this OptionTable */
Option options[1]; /* Information about the individual options in
* the table. This must be the last field in
* the structure: the actual size of the array
@@ -115,8 +118,6 @@ typedef struct OptionTable {
static int DoObjConfig(Tcl_Interp *interp, char *recordPtr,
Option *optionPtr, Tcl_Obj *valuePtr,
Tk_Window tkwin, Tk_SavedOption *savePtr);
-static void DestroyOptionHashTable(ClientData clientData,
- Tcl_Interp *interp);
static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
char *internalPtr, Tk_Window tkwin);
static Tcl_Obj * GetConfigList(char *recordPtr,
@@ -128,7 +129,7 @@ static Option * GetOptionFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, OptionTable *tablePtr);
static int ObjectIsEmpty(Tcl_Obj *objPtr);
static void FreeOptionInternalRep(Tcl_Obj *objPtr);
-static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *);
/*
* The structure below defines an object type that is used to cache the result
@@ -140,9 +141,9 @@ static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static const Tcl_ObjType optionObjType = {
"option", /* name */
FreeOptionInternalRep, /* freeIntRepProc */
- NULL, /* dupIntRepProc */
+ DupOptionInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetOptionFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
/*
@@ -171,30 +172,26 @@ Tk_CreateOptionTable(
/* Static information about the configuration
* options. */
{
- Tcl_HashTable *hashTablePtr;
Tcl_HashEntry *hashEntryPtr;
int newEntry;
OptionTable *tablePtr;
const Tk_OptionSpec *specPtr, *specPtr2;
Option *optionPtr;
int numOptions, i;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
- * We use an AssocData value in the interpreter to keep a hash table of
- * all the option tables we've created for this application. This is used
- * for two purposes. First, it allows us to share the tables (e.g. in
- * several chains) and second, we use the deletion callback for the
- * AssocData to delete all the option tables when the interpreter is
- * deleted. The code below finds the hash table or creates a new one if it
+ * We use an TSD in the thread to keep a hash table of
+ * all the option tables we've created for this application. This is
+ * used for allowing us to share the tables (e.g. in several chains).
+ * The code below finds the hash table or creates a new one if it
* doesn't already exist.
*/
- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
- if (hashTablePtr == NULL) {
- hashTablePtr = ckalloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS);
- Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable,
- hashTablePtr);
+ if (!tsdPtr->initialized) {
+ Tcl_InitHashTable(&tsdPtr->hashTable, TCL_ONE_WORD_KEYS);
+ tsdPtr->initialized = 1;
}
/*
@@ -202,7 +199,7 @@ Tk_CreateOptionTable(
* reuse the existing table.
*/
- hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr,
+ hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->hashTable, (char *) templatePtr,
&newEntry);
if (!newEntry) {
tablePtr = Tcl_GetHashValue(hashEntryPtr);
@@ -221,7 +218,6 @@ Tk_CreateOptionTable(
}
tablePtr = ckalloc(sizeof(OptionTable) + (numOptions * sizeof(Option)));
tablePtr->refCount = 1;
- tablePtr->refCount2 = 1;
tablePtr->hashEntryPtr = hashEntryPtr;
tablePtr->nextPtr = NULL;
tablePtr->numOptions = numOptions;
@@ -357,62 +353,7 @@ Tk_DeleteOptionTable(
}
}
Tcl_DeleteHashEntry(tablePtr->hashEntryPtr);
- tablePtr->refCount2--;
- if (tablePtr->refCount2 <= 0) {
- ckfree(tablePtr);
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DestroyOptionHashTable --
- *
- * This function is the deletion callback associated with the AssocData
- * entry created by Tk_CreateOptionTable. It is invoked when an
- * interpreter is deleted, and deletes all of the option tables
- * associated with that interpreter.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The option hash table is destroyed along with all of the OptionTable
- * structures that it refers to.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-DestroyOptionHashTable(
- ClientData clientData, /* The hash table we are destroying */
- Tcl_Interp *interp) /* The interpreter we are destroying */
-{
- Tcl_HashTable *hashTablePtr = clientData;
- Tcl_HashSearch search;
- Tcl_HashEntry *hashEntryPtr;
-
- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
- hashEntryPtr != NULL;
- hashEntryPtr = Tcl_NextHashEntry(&search)) {
- OptionTable *tablePtr = Tcl_GetHashValue(hashEntryPtr);
-
- /*
- * The following statements do two tricky things:
- * 1. They ensure that the option table is deleted, even if there are
- * outstanding references to it.
- * 2. They ensure that Tk_DeleteOptionTable doesn't delete other
- * tables chained from this one; we'll do it when we come across
- * the hash table entry for the chained table (in fact, the chained
- * table may already have been deleted).
- */
-
- tablePtr->refCount = 1;
- tablePtr->nextPtr = NULL;
- Tk_DeleteOptionTable((Tk_OptionTable) tablePtr);
- }
- Tcl_DeleteHashTable(hashTablePtr);
- ckfree(hashTablePtr);
+ ckfree(tablePtr);
}
/*
@@ -737,8 +678,8 @@ DoObjConfig(
case TK_OPTION_STRING_TABLE: {
int newValue;
- if (Tcl_GetIndexFromObj(interp, valuePtr,
- optionPtr->specPtr->clientData,
+ if (Tcl_GetIndexFromObjStruct(interp, valuePtr,
+ optionPtr->specPtr->clientData, sizeof(char *),
optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
return TCL_ERROR;
}
@@ -1004,7 +945,7 @@ ObjectIsEmpty(
if (objPtr->bytes != NULL) {
return (objPtr->length == 0);
}
- Tcl_GetStringFromObj(objPtr, &length);
+ (void)Tcl_GetStringFromObj(objPtr, &length);
return (length == 0);
}
@@ -1152,7 +1093,7 @@ GetOptionFromObj(
objPtr->internalRep.twoPtrValue.ptr1 = (void *) tablePtr;
objPtr->internalRep.twoPtrValue.ptr2 = (void *) bestPtr;
objPtr->typePtr = &optionObjType;
- tablePtr->refCount2++;
+ tablePtr->refCount++;
return bestPtr;
error:
@@ -1204,38 +1145,6 @@ TkGetOptionSpec(
/*
*----------------------------------------------------------------------
*
- * SetOptionFromAny --
- *
- * This function is called to convert a Tcl object to option internal
- * form. However, this doesn't make sense (need to have a table of
- * options in order to do the conversion) so the function always
- * generates an error.
- *
- * Results:
- * The return value is always TCL_ERROR, and an error message is left in
- * interp's result if interp isn't NULL.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-SetOptionFromAny(
- Tcl_Interp *interp, /* Used for error reporting if not NULL. */
- register Tcl_Obj *objPtr) /* The object to convert. */
-{
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't convert value to option except via GetOptionFromObj API",
- -1));
- Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
- return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* FreeOptionInternalRep --
*
* Part of the option Tcl object type implementation. Frees the storage
@@ -1257,18 +1166,37 @@ static void
FreeOptionInternalRep(
register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
{
- register OptionTable *tablePtr = (OptionTable *) objPtr->internalRep.twoPtrValue.ptr1;
+ register Tk_OptionTable tablePtr = (Tk_OptionTable) objPtr->internalRep.twoPtrValue.ptr1;
- tablePtr->refCount2--;
- if (tablePtr->refCount2 <= 0) {
- ckfree(tablePtr);
- }
+ Tk_DeleteOptionTable(tablePtr);
objPtr->typePtr = NULL;
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
}
/*
+ *---------------------------------------------------------------------------
+ *
+ * DupOptionInternalRep --
+ *
+ * When a cached option object is duplicated, this is called to update the
+ * internal reps.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+DupOptionInternalRep(
+ Tcl_Obj *srcObjPtr, /* The object we are copying from. */
+ Tcl_Obj *dupObjPtr) /* The object we are copying to. */
+{
+ register OptionTable *tablePtr = (OptionTable *) srcObjPtr->internalRep.twoPtrValue.ptr1;
+ tablePtr->refCount++;
+ dupObjPtr->typePtr = srcObjPtr->typePtr;
+ dupObjPtr->internalRep = srcObjPtr->internalRep;
+}
+
+/*
*--------------------------------------------------------------
*
* Tk_SetOptions --
@@ -1347,7 +1275,7 @@ Tk_SetOptions(
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"value for \"%s\" missing",
- Tcl_GetStringFromObj(*objv, NULL)));
+ Tcl_GetString(*objv)));
Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL);
goto error;
}
@@ -1372,7 +1300,7 @@ Tk_SetOptions(
: NULL) != TCL_OK) {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (processing \"%.40s\" option)",
- Tcl_GetStringFromObj(*objv, NULL)));
+ Tcl_GetString(*objv)));
goto error;
}
if (savePtr != NULL) {
@@ -2146,14 +2074,14 @@ TkDebugConfig(
* interpreter anymore. */
{
OptionTable *tablePtr = (OptionTable *) table;
- Tcl_HashTable *hashTablePtr;
Tcl_HashEntry *hashEntryPtr;
Tcl_HashSearch search;
Tcl_Obj *objPtr;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
objPtr = Tcl_NewObj();
- hashTablePtr = Tcl_GetAssocData(interp, OPTION_HASH_KEY, NULL);
- if (hashTablePtr == NULL) {
+ if (!tablePtr || !tsdPtr->initialized) {
return objPtr;
}
@@ -2162,7 +2090,7 @@ TkDebugConfig(
* want still is valid.
*/
- for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search);
+ for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
hashEntryPtr != NULL;
hashEntryPtr = Tcl_NextHashEntry(&search)) {
if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
diff --git a/generic/tkConsole.c b/generic/tkConsole.c
index 434350a..8bfbe9b 100644
--- a/generic/tkConsole.c
+++ b/generic/tkConsole.c
@@ -84,7 +84,7 @@ static const Tcl_ChannelType consoleChannelType = {
NULL
};
-#ifdef __WIN32__
+#ifdef _WIN32
#include <windows.h>
/*
@@ -220,11 +220,10 @@ Tk_InitConsoleChannels(
Tcl_Channel consoleChannel;
/*
- * Ensure that we are getting a compatible version of Tcl. This is really
- * only an issue when Tk is loaded dynamically.
+ * Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
return;
}
@@ -439,7 +438,8 @@ Tk_CreateConsoleWindow(
}
Tcl_Preserve(consoleInterp);
- result = Tcl_GlobalEval(consoleInterp, "source $tk_library/console.tcl");
+ result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
+ -1, TCL_EVAL_GLOBAL);
if (result == TCL_ERROR) {
Tcl_SetReturnOptions(interp,
Tcl_GetReturnOptions(consoleInterp, result));
@@ -531,7 +531,7 @@ ConsoleOutput(
Tcl_DStringFree(&ds);
Tcl_IncrRefCount(cmd);
- Tcl_GlobalEvalObj(consoleInterp, cmd);
+ Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
Tcl_DecrRefCount(cmd);
}
}
@@ -697,8 +697,8 @@ ConsoleObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -741,7 +741,7 @@ ConsoleObjCmd(
Tcl_IncrRefCount(cmd);
if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
Tcl_Preserve(consoleInterp);
- result = Tcl_GlobalEvalObj(consoleInterp, cmd);
+ result = Tcl_EvalObjEx(consoleInterp, cmd, TCL_EVAL_GLOBAL);
Tcl_SetReturnOptions(interp,
Tcl_GetReturnOptions(consoleInterp, result));
Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
@@ -787,8 +787,8 @@ InterpreterObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option arg");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -807,7 +807,7 @@ InterpreterObjCmd(
Tcl_Preserve(otherInterp);
switch ((enum option) index) {
case OTHER_EVAL:
- result = Tcl_GlobalEvalObj(otherInterp, objv[2]);
+ result = Tcl_EvalObjEx(otherInterp, objv[2], TCL_EVAL_GLOBAL);
/*
* TODO: Should exceptions be filtered here?
@@ -946,7 +946,7 @@ ConsoleEventProc(
Tcl_Interp *consoleInterp = info->consoleInterp;
if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) {
- Tcl_GlobalEval(consoleInterp, "tk::ConsoleExit");
+ Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL);
}
if (--info->refCount <= 0) {
diff --git a/generic/tkDecls.h b/generic/tkDecls.h
index d080e93..64c32cd 100644
--- a/generic/tkDecls.h
+++ b/generic/tkDecls.h
@@ -25,6 +25,10 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -860,12 +864,8 @@ EXTERN void Tk_CreateOldImageType(const Tk_ImageType *typePtr);
/* 273 */
EXTERN void Tk_CreateOldPhotoImageFormat(
const Tk_PhotoImageFormat *formatPtr);
-/* 274 */
-EXTERN void reserved274(void);
-/* 275 */
-EXTERN void reserved275(void);
-typedef struct TkStubHooks {
+typedef struct {
const struct TkPlatStubs *tkPlatStubs;
const struct TkIntStubs *tkIntStubs;
const struct TkIntPlatStubs *tkIntPlatStubs;
@@ -874,7 +874,7 @@ typedef struct TkStubHooks {
typedef struct TkStubs {
int magic;
- const struct TkStubHooks *hooks;
+ const TkStubHooks *hooks;
void (*tk_MainLoop) (void); /* 0 */
XColor * (*tk_3DBorderColor) (Tk_3DBorder border); /* 1 */
@@ -1150,14 +1150,10 @@ typedef struct TkStubs {
Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
void (*tk_CreateOldImageType) (const Tk_ImageType *typePtr); /* 272 */
void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */
- void (*reserved274) (void); /* 274 */
- void (*reserved275) (void); /* 275 */
} TkStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TkStubs *tkStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -1714,10 +1710,6 @@ extern const TkStubs *tkStubsPtr;
(tkStubsPtr->tk_CreateOldImageType) /* 272 */
#define Tk_CreateOldPhotoImageFormat \
(tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
-#define reserved274 \
- (tkStubsPtr->reserved274) /* 274 */
-#define reserved275 \
- (tkStubsPtr->reserved275) /* 275 */
#endif /* defined(USE_TK_STUBS) */
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index d78f396..ea8d7f1 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -133,7 +133,7 @@ static const Tk_OptionSpec entryOptSpec[] = {
0, DEF_ENTRY_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
- TK_CONFIG_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING, "-show", "show", "Show",
DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
TK_OPTION_NULL_OK, 0, 0},
@@ -279,23 +279,23 @@ static const Tk_OptionSpec sbOptSpec[] = {
0, DEF_ENTRY_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
- TK_CONFIG_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
0, stateStrings, 0},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_DOUBLE, "-to", "to", "To",
DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
0, validateStrings, 0},
{TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
- NULL, -1, Tk_Offset(Entry, validateCmd), TK_CONFIG_NULL_OK, 0, 0},
+ NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-values", "values", "Values",
DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
TK_OPTION_NULL_OK, 0, 0},
@@ -307,7 +307,7 @@ static const Tk_OptionSpec sbOptSpec[] = {
DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 0, 0, 0},
{TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
@@ -390,9 +390,9 @@ static const char *const selElementNames[] = {
*/
static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
- int objc, Tcl_Obj *const objv[], int flags);
-static void DeleteChars(Entry *entryPtr, int index, int count);
-static void DestroyEntry(char *memPtr);
+ int objc, Tcl_Obj *const objv[]);
+static int DeleteChars(Entry *entryPtr, int index, int count);
+static void DestroyEntry(void *memPtr);
static void DisplayEntry(ClientData clientData);
static void EntryBlinkProc(ClientData clientData);
static void EntryCmdDeletedProc(ClientData clientData);
@@ -417,7 +417,7 @@ static int EntryValidateChange(Entry *entryPtr, const char *change,
static void ExpandPercents(Entry *entryPtr, const char *before,
const char *change, const char *newStr, int index,
int type, Tcl_DString *dsPtr);
-static void EntryValueChanged(Entry *entryPtr,
+static int EntryValueChanged(Entry *entryPtr,
const char *newValue);
static void EntryVisibleRange(Entry *entryPtr,
double *firstPtr, double *lastPtr);
@@ -427,7 +427,7 @@ static int EntryWidgetObjCmd(ClientData clientData,
static void EntryWorldChanged(ClientData instanceData);
static int GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
const char *string, int *indexPtr);
-static void InsertChars(Entry *entryPtr, int index, const char *string);
+static int InsertChars(Entry *entryPtr, int index, const char *string);
/*
* These forward declarations are the spinbox specific ones:
@@ -554,7 +554,7 @@ Tk_EntryObjCmd(
if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
!= TCL_OK) ||
- (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK)) {
+ (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
Tk_DestroyWindow(entryPtr->tkwin);
return TCL_ERROR;
}
@@ -659,12 +659,12 @@ EntryWidgetObjCmd(
}
Tcl_SetObjResult(interp, objPtr);
} else {
- result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
}
break;
case COMMAND_DELETE: {
- int first, last;
+ int first, last, code;
if ((objc < 3) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
@@ -681,7 +681,10 @@ EntryWidgetObjCmd(
goto error;
}
if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
- DeleteChars(entryPtr, first, last - first);
+ code = DeleteChars(entryPtr, first, last - first);
+ if (code != TCL_OK) {
+ goto error;
+ }
}
break;
}
@@ -722,7 +725,7 @@ EntryWidgetObjCmd(
}
case COMMAND_INSERT: {
- int index;
+ int index, code;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "index text");
@@ -733,7 +736,10 @@ EntryWidgetObjCmd(
goto error;
}
if (entryPtr->state == STATE_NORMAL) {
- InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
+ code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
+ if (code != TCL_OK) {
+ goto error;
+ }
}
break;
}
@@ -1010,19 +1016,19 @@ EntryWidgetObjCmd(
static void
DestroyEntry(
- char *memPtr) /* Info about entry widget. */
+ void *memPtr) /* Info about entry widget. */
{
- Entry *entryPtr = (Entry *) memPtr;
+ Entry *entryPtr = memPtr;
/*
* Free up all the stuff that requires special handling, then let
* Tk_FreeOptions handle all the standard option-related stuff.
*/
- ckfree(entryPtr->string);
+ ckfree((char *)entryPtr->string);
if (entryPtr->textVarName != NULL) {
- Tcl_UntraceVar(entryPtr->interp, entryPtr->textVarName,
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(entryPtr->interp, entryPtr->textVarName,
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, entryPtr);
entryPtr->flags &= ~ENTRY_VAR_TRACED;
}
@@ -1034,7 +1040,7 @@ DestroyEntry(
}
Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler);
if (entryPtr->displayString != entryPtr->string) {
- ckfree(entryPtr->displayString);
+ ckfree((char *)entryPtr->displayString);
}
if (entryPtr->type == TK_SPINBOX) {
Spinbox *sbPtr = (Spinbox *) entryPtr;
@@ -1082,8 +1088,7 @@ ConfigureEntry(
Entry *entryPtr, /* Information about widget; may or may not
* already have values for some fields. */
int objc, /* Number of valid entries in argv. */
- Tcl_Obj *const objv[], /* Argument objects. */
- int flags) /* Flags to pass to Tk_ConfigureWidget. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_SavedOptions savedOptions;
Tk_3DBorder border;
@@ -1098,6 +1103,7 @@ ConfigureEntry(
int valuesChanged = 0; /* lint initialization */
double oldFrom = 0.0; /* lint initialization */
double oldTo = 0.0; /* lint initialization */
+ int code;
/*
* Eliminate any existing trace on a variable monitored by the entry.
@@ -1105,7 +1111,7 @@ ConfigureEntry(
if ((entryPtr->textVarName != NULL)
&& (entryPtr->flags & ENTRY_VAR_TRACED)) {
- Tcl_UntraceVar(interp, entryPtr->textVarName,
+ Tcl_UntraceVar2(interp, entryPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, entryPtr);
entryPtr->flags &= ~ENTRY_VAR_TRACED;
@@ -1303,8 +1309,19 @@ ConfigureEntry(
if (entryPtr->textVarName != NULL) {
const char *value;
- value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
+
+ /*
+ * Since any trace on the textvariable was eliminated above,
+ * the only possible reason for EntryValueChanged to return
+ * an error is that the textvariable lives in a namespace
+ * that does not (yet) exist. Indeed, namespaces are not
+ * automatically created as needed. Don't trap this error
+ * here, better do it below when attempting to trace the
+ * variable.
+ */
+
EntryValueChanged(entryPtr, NULL);
} else {
EntrySetValue(entryPtr, value);
@@ -1323,7 +1340,13 @@ ConfigureEntry(
*/
Tcl_ListObjIndex(interp, sbPtr->listObj, 0, &objPtr);
- EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
+
+ /*
+ * No check for error return here as well, because any possible
+ * error will be trapped below when attempting tracing.
+ */
+
+ EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
} else if ((sbPtr->valueStr == NULL)
&& !DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)
&& (!DOUBLES_EQ(sbPtr->fromValue, oldFrom)
@@ -1337,7 +1360,7 @@ ConfigureEntry(
double dvalue;
- if (sscanf(entryPtr->string, "%lf", &dvalue) == 0) {
+ if (sscanf(entryPtr->string, "%lf", &dvalue) <= 0) {
/* Scan failure */
dvalue = sbPtr->fromValue;
} else if (dvalue > sbPtr->toValue) {
@@ -1346,6 +1369,12 @@ ConfigureEntry(
dvalue = sbPtr->fromValue;
}
sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
+
+ /*
+ * No check for error return here as well, because any possible
+ * error will be trapped below when attempting tracing.
+ */
+
EntryValueChanged(entryPtr, sbPtr->formatBuf);
}
}
@@ -1357,10 +1386,13 @@ ConfigureEntry(
if ((entryPtr->textVarName != NULL)
&& !(entryPtr->flags & ENTRY_VAR_TRACED)) {
- Tcl_TraceVar(interp, entryPtr->textVarName,
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ code = Tcl_TraceVar2(interp, entryPtr->textVarName,
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, entryPtr);
- entryPtr->flags |= ENTRY_VAR_TRACED;
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ entryPtr->flags |= ENTRY_VAR_TRACED;
}
EntryWorldChanged(entryPtr);
@@ -1680,7 +1712,7 @@ DisplayEntry(
Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
NULL, NULL);
cursorX += entryPtr->layoutX;
- cursorX -= (entryPtr->insertWidth)/2;
+ cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
fm.ascent + fm.descent);
if (entryPtr->insertPos >= entryPtr->leftIndex && cursorX < xBound) {
@@ -1881,7 +1913,7 @@ EntryComputeGeometry(
char *p;
if (entryPtr->displayString != entryPtr->string) {
- ckfree(entryPtr->displayString);
+ ckfree((char *)entryPtr->displayString);
entryPtr->displayString = entryPtr->string;
entryPtr->numDisplayBytes = entryPtr->numBytes;
}
@@ -1993,7 +2025,8 @@ EntryComputeGeometry(
* Add new characters to an entry widget.
*
* Results:
- * None.
+ * A standard Tcl result. If an error occurred then an error message is
+ * left in the interp's result.
*
* Side effects:
* New information gets added to entryPtr; it will be redisplayed soon,
@@ -2002,12 +2035,12 @@ EntryComputeGeometry(
*----------------------------------------------------------------------
*/
-static void
+static int
InsertChars(
Entry *entryPtr, /* Entry that is to get the new elements. */
int index, /* Add the new elements before this character
* index. */
- const char *value) /* New characters to add (NULL-terminated
+ const char *value) /* New characters to add (NULL-terminated
* string). */
{
ptrdiff_t byteIndex;
@@ -2020,7 +2053,7 @@ InsertChars(
byteIndex = Tcl_UtfAtIndex(string, index) - string;
byteCount = strlen(value);
if (byteCount == 0) {
- return;
+ return TCL_OK;
}
newByteCount = entryPtr->numBytes + byteCount + 1;
@@ -2034,10 +2067,10 @@ InsertChars(
EntryValidateChange(entryPtr, value, newStr, index,
VALIDATE_INSERT) != TCL_OK) {
ckfree(newStr);
- return;
+ return TCL_OK;
}
- ckfree(string);
+ ckfree((char *)string);
entryPtr->string = newStr;
/*
@@ -2082,7 +2115,7 @@ InsertChars(
if (entryPtr->insertPos >= index) {
entryPtr->insertPos += charsAdded;
}
- EntryValueChanged(entryPtr, NULL);
+ return EntryValueChanged(entryPtr, NULL);
}
/*
@@ -2093,7 +2126,8 @@ InsertChars(
* Remove one or more characters from an entry widget.
*
* Results:
- * None.
+ * A standard Tcl result. If an error occurred then an error message is
+ * left in the interp's result.
*
* Side effects:
* Memory gets freed, the entry gets modified and (eventually)
@@ -2102,7 +2136,7 @@ InsertChars(
*----------------------------------------------------------------------
*/
-static void
+static int
DeleteChars(
Entry *entryPtr, /* Entry widget to modify. */
int index, /* Index of first character to delete. */
@@ -2116,7 +2150,7 @@ DeleteChars(
count = entryPtr->numChars - index;
}
if (count <= 0) {
- return;
+ return TCL_OK;
}
string = entryPtr->string;
@@ -2138,11 +2172,11 @@ DeleteChars(
VALIDATE_DELETE) != TCL_OK) {
ckfree(newStr);
ckfree(toDelete);
- return;
+ return TCL_OK;
}
ckfree(toDelete);
- ckfree(entryPtr->string);
+ ckfree((char *)entryPtr->string);
entryPtr->string = newStr;
entryPtr->numChars -= count;
entryPtr->numBytes -= byteCount;
@@ -2197,7 +2231,7 @@ DeleteChars(
entryPtr->insertPos = index;
}
}
- EntryValueChanged(entryPtr, NULL);
+ return EntryValueChanged(entryPtr, NULL);
}
/*
@@ -2210,7 +2244,8 @@ DeleteChars(
* is one, and does other bookkeeping such as arranging for redisplay.
*
* Results:
- * None.
+ * A standard Tcl result. If an error occurred then an error message is
+ * left in the interp's result.
*
* Side effects:
* None.
@@ -2218,7 +2253,7 @@ DeleteChars(
*----------------------------------------------------------------------
*/
-static void
+static int
EntryValueChanged(
Entry *entryPtr, /* Entry whose value just changed. */
const char *newValue) /* If this value is not NULL, we first force
@@ -2231,8 +2266,8 @@ EntryValueChanged(
if (entryPtr->textVarName == NULL) {
newValue = NULL;
} else {
- newValue = Tcl_SetVar(entryPtr->interp, entryPtr->textVarName,
- entryPtr->string, TCL_GLOBAL_ONLY);
+ newValue = Tcl_SetVar2(entryPtr->interp, entryPtr->textVarName,
+ NULL, entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
}
if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) {
@@ -2254,6 +2289,19 @@ EntryValueChanged(
EntryComputeGeometry(entryPtr);
EventuallyRedraw(entryPtr);
}
+
+ /*
+ * An error may have happened when setting the textvariable in case there
+ * is a trace on that variable and the trace proc triggered an error.
+ * Another possibility is that the textvariable is in a namespace that
+ * does not (yet) exist.
+ * Signal this error.
+ */
+
+ if ((entryPtr->textVarName != NULL) && (newValue == NULL)) {
+ return TCL_ERROR;
+ }
+ return TCL_OK;
}
/*
@@ -2318,13 +2366,13 @@ EntrySetValue(
if (entryPtr->flags & VALIDATE_ABORT) {
entryPtr->flags &= ~VALIDATE_ABORT;
- ckfree(value);
+ ckfree((char *)value);
return;
}
}
oldSource = entryPtr->string;
- ckfree(entryPtr->string);
+ ckfree((char *)entryPtr->string);
if (malloced) {
entryPtr->string = value;
@@ -2429,7 +2477,7 @@ EntryEventProc(
if (entryPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayEntry, clientData);
}
- Tcl_EventuallyFree(clientData, DestroyEntry);
+ Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyEntry);
}
break;
case ConfigureNotify:
@@ -2560,7 +2608,7 @@ GetEntryIndex(
case '@': {
int x, roundUp, maxWidth;
- if (Tcl_GetInt(interp, string + 1, &x) != TCL_OK) {
+ if (Tcl_GetInt(NULL, string + 1, &x) != TCL_OK) {
goto badIndex;
}
if (x < entryPtr->inset) {
@@ -2589,7 +2637,7 @@ GetEntryIndex(
break;
}
default:
- if (Tcl_GetInt(interp, string, indexPtr) != TCL_OK) {
+ if (Tcl_GetInt(NULL, string, indexPtr) != TCL_OK) {
goto badIndex;
}
if (*indexPtr < 0){
@@ -2939,6 +2987,7 @@ EntryUpdateScrollbar(
int code;
double first, last;
Tcl_Interp *interp;
+ Tcl_DString buf;
if (entryPtr->scrollCmd == NULL) {
return;
@@ -2949,8 +2998,14 @@ EntryUpdateScrollbar(
EntryVisibleRange(entryPtr, &first, &last);
Tcl_PrintDouble(NULL, first, firstStr);
Tcl_PrintDouble(NULL, last, lastStr);
- code = Tcl_VarEval(interp, entryPtr->scrollCmd, " ", firstStr, " ",
- lastStr, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, entryPtr->scrollCmd, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, firstStr, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, lastStr, -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (horizontal scrolling command executed by %s)",
@@ -3095,9 +3150,9 @@ EntryTextVarProc(
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar(interp, entryPtr->textVarName, entryPtr->string,
- TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, entryPtr->textVarName,
+ Tcl_SetVar2(interp, entryPtr->textVarName, NULL,
+ entryPtr->string, TCL_GLOBAL_ONLY);
+ Tcl_TraceVar2(interp, entryPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, clientData);
entryPtr->flags |= ENTRY_VAR_TRACED;
@@ -3111,7 +3166,7 @@ EntryTextVarProc(
* value because we changed it because someone typed in the entry).
*/
- value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
value = "";
}
@@ -3171,7 +3226,7 @@ EntryValidate(
&bool) != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (invalid boolean result from validation command)");
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, TCL_ERROR);
Tcl_ResetResult(interp);
return TCL_ERROR;
}
@@ -3604,7 +3659,7 @@ Tk_SpinboxObjCmd(
Tk_DestroyWindow(entryPtr->tkwin);
return TCL_ERROR;
}
- if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) {
+ if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
goto error;
}
@@ -3712,12 +3767,12 @@ SpinboxWidgetObjCmd(
}
Tcl_SetObjResult(interp, objPtr);
} else {
- result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
}
break;
case SB_CMD_DELETE: {
- int first, last;
+ int first, last, code;
if ((objc < 3) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
@@ -3736,7 +3791,10 @@ SpinboxWidgetObjCmd(
}
}
if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
- DeleteChars(entryPtr, first, last - first);
+ code = DeleteChars(entryPtr, first, last - first);
+ if (code != TCL_OK) {
+ goto error;
+ }
}
break;
}
@@ -3796,7 +3854,7 @@ SpinboxWidgetObjCmd(
}
case SB_CMD_INSERT: {
- int index;
+ int index, code;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 2, objv, "index text");
@@ -3807,7 +3865,10 @@ SpinboxWidgetObjCmd(
goto error;
}
if (entryPtr->state == STATE_NORMAL) {
- InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
+ code = InsertChars(entryPtr, index, Tcl_GetString(objv[3]));
+ if (code != TCL_OK) {
+ goto error;
+ }
}
break;
}
@@ -4017,16 +4078,22 @@ SpinboxWidgetObjCmd(
break;
}
- case SB_CMD_SET:
+ case SB_CMD_SET: {
+ int code = TCL_OK;
+
if (objc > 3) {
Tcl_WrongNumArgs(interp, 2, objv, "?string?");
goto error;
}
if (objc == 3) {
- EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
+ code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2]));
+ if (code != TCL_OK) {
+ goto error;
+ }
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
break;
+ }
case SB_CMD_VALIDATE: {
int code;
@@ -4167,7 +4234,7 @@ GetSpinboxElement(
* TCL_OK.
*
* Side effects:
- * An background error condition may arise when invoking the callback.
+ * A background error condition may arise when invoking the callback.
* The widget value may change.
*
*--------------------------------------------------------------
@@ -4198,6 +4265,7 @@ SpinboxInvoke(
return TCL_OK;
}
+ code = TCL_OK;
if (fabs(sbPtr->increment) > MIN_DBL_VAL) {
if (sbPtr->listObj != NULL) {
Tcl_Obj *objPtr;
@@ -4243,11 +4311,11 @@ SpinboxInvoke(
}
}
Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr);
- EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
+ code = EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
} else if (!DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)) {
double dvalue;
- if (sscanf(entryPtr->string, "%lf", &dvalue) == 0) {
+ if (sscanf(entryPtr->string, "%lf", &dvalue) <= 0) {
/*
* If the string doesn't scan as a double value, just
* use the -from value
@@ -4290,9 +4358,12 @@ SpinboxInvoke(
}
}
sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
- EntryValueChanged(entryPtr, sbPtr->formatBuf);
+ code = EntryValueChanged(entryPtr, sbPtr->formatBuf);
}
}
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
if (sbPtr->command != NULL) {
Tcl_DStringInit(&script);
diff --git a/generic/tkEvent.c b/generic/tkEvent.c
index 463379a..95aeda1 100644
--- a/generic/tkEvent.c
+++ b/generic/tkEvent.c
@@ -356,7 +356,7 @@ CreateXIC(
/* XCreateIC failed. */
return;
}
-
+
/*
* Adjust the window's event mask if the IM requires it.
*/
@@ -2039,6 +2039,12 @@ TkFinalize(
{
ExitHandler *exitPtr;
+#if defined(_WIN32) && !defined(STATIC_BUILD)
+ if (!tclStubsPtr) {
+ return;
+ }
+#endif
+
Tcl_DeleteExitHandler(TkFinalize, NULL);
Tcl_MutexLock(&exitMutex);
@@ -2065,7 +2071,7 @@ TkFinalize(
* TkFinalizeThread --
*
* Runs our private thread exit handlers and removes itself from Tcl.
- * This is benificial should we want to protect from dangling pointers
+ * This is beneficial should we want to protect from dangling pointers
* should the Tk shared library be unloaded prior to Tcl which can happen
* on Windows should the process be forcefully exiting from an exception
* handler.
diff --git a/generic/tkFocus.c b/generic/tkFocus.c
index cfd2216..60f631d 100644
--- a/generic/tkFocus.c
+++ b/generic/tkFocus.c
@@ -162,8 +162,8 @@ Tk_FocusObjCmd(
* We have a subcommand to parse and act upon.
*/
- if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], focusOptions,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
if (objc != 3) {
diff --git a/generic/tkFont.c b/generic/tkFont.c
index 4485df8..102fc6e 100644
--- a/generic/tkFont.c
+++ b/generic/tkFont.c
@@ -421,7 +421,7 @@ TkFontPkgFree(
fontsLeft++;
#ifdef DEBUG_FONTS
fprintf(stderr, "Font %s still in cache.\n",
- Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
+ (char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
}
@@ -600,40 +600,40 @@ Tk_FontObjCmd(
return result;
}
case FONT_CONFIGURE: {
- int result;
- const char *string;
- Tcl_Obj *objPtr;
- NamedFont *nfPtr;
- Tcl_HashEntry *namedHashPtr;
-
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "fontname ?-option value ...?");
- return TCL_ERROR;
- }
- string = Tcl_GetString(objv[2]);
- namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string);
+ int result;
+ const char *string;
+ Tcl_Obj *objPtr;
+ NamedFont *nfPtr;
+ Tcl_HashEntry *namedHashPtr;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fontname ?-option value ...?");
+ return TCL_ERROR;
+ }
+ string = Tcl_GetString(objv[2]);
+ namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string);
nfPtr = NULL; /* lint. */
- if (namedHashPtr != NULL) {
- nfPtr = Tcl_GetHashValue(namedHashPtr);
- }
- if ((namedHashPtr == NULL) || nfPtr->deletePending) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "named font \"%s\" doesn't exist", string));
- Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, NULL);
- return TCL_ERROR;
- }
- if (objc == 3) {
- objPtr = NULL;
- } else if (objc == 4) {
- objPtr = objv[3];
- } else {
- result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3,
- &nfPtr->fa);
- UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
- return result;
- }
- return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr);
- }
+ if (namedHashPtr != NULL) {
+ nfPtr = Tcl_GetHashValue(namedHashPtr);
+ }
+ if ((namedHashPtr == NULL) || nfPtr->deletePending) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "named font \"%s\" doesn't exist", string));
+ Tcl_SetErrorCode(interp, "TK", "LOOKUP", "FONT", string, NULL);
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ objPtr = NULL;
+ } else if (objc == 4) {
+ objPtr = objv[3];
+ } else {
+ result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3,
+ &nfPtr->fa);
+ UpdateDependentFonts(fiPtr, tkwin, namedHashPtr);
+ return result;
+ }
+ return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr);
+ }
case FONT_CREATE: {
int skip = 3, i;
const char *name;
@@ -1093,7 +1093,8 @@ Tk_AllocFontFromObj(
int isNew, descent;
NamedFont *nfPtr;
- if (objPtr->typePtr != &tkFontObjType) {
+ if (objPtr->typePtr != &tkFontObjType
+ || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
SetFontFromAny(interp, objPtr);
}
@@ -1133,6 +1134,7 @@ Tk_AllocFontFromObj(
fontPtr->resourceRefCount++;
fontPtr->objRefCount++;
objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
return (Tk_Font) fontPtr;
}
}
@@ -1243,6 +1245,7 @@ Tk_AllocFontFromObj(
}
objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
return (Tk_Font) fontPtr;
}
@@ -1275,7 +1278,8 @@ Tk_GetFontFromObj(
TkFont *fontPtr;
Tcl_HashEntry *hashPtr;
- if (objPtr->typePtr != &tkFontObjType) {
+ if (objPtr->typePtr != &tkFontObjType
+ || objPtr->internalRep.twoPtrValue.ptr2 != fiPtr) {
SetFontFromAny(NULL, objPtr);
}
@@ -1311,6 +1315,7 @@ Tk_GetFontFromObj(
if (Tk_Screen(tkwin) == fontPtr->screen) {
fontPtr->objRefCount++;
objPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
+ objPtr->internalRep.twoPtrValue.ptr2 = fiPtr;
return (Tk_Font) fontPtr;
}
}
@@ -1356,6 +1361,7 @@ SetFontFromAny(
}
objPtr->typePtr = &tkFontObjType;
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+ objPtr->internalRep.twoPtrValue.ptr2 = NULL;
return TCL_OK;
}
@@ -1517,8 +1523,9 @@ FreeFontObj(
fontPtr->objRefCount--;
if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) {
ckfree(fontPtr);
- objPtr->internalRep.twoPtrValue.ptr1 = NULL;
}
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+ objPtr->internalRep.twoPtrValue.ptr2 = NULL;
}
}
@@ -1549,6 +1556,8 @@ DupFontObjProc(
dupObjPtr->typePtr = srcObjPtr->typePtr;
dupObjPtr->internalRep.twoPtrValue.ptr1 = fontPtr;
+ dupObjPtr->internalRep.twoPtrValue.ptr2
+ = srcObjPtr->internalRep.twoPtrValue.ptr2;
if (fontPtr != NULL) {
fontPtr->objRefCount++;
@@ -2058,14 +2067,14 @@ Tk_ComputeTextLayout(
NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX,
baseline)->numDisplayChars = -1;
start++;
+ curX = newX;
+ flags &= ~TK_AT_LEAST_ONE;
if ((start < end) &&
((wrapLength <= 0) || (newX <= wrapLength))) {
/*
* More chars can still fit on this line.
*/
- curX = newX;
- flags &= ~TK_AT_LEAST_ONE;
continue;
}
} else {
@@ -2985,13 +2994,6 @@ PointInQuadrilateral(
}
static inline int
-sign(
- double value)
-{
- return (value < 0.0) ? -1 : (value > 0.0) ? 1 : 0;
-}
-
-static inline int
SidesIntersect(
double ax1, double ay1, double ax2, double ay2,
double bx1, double by1, double bx2, double by2)
@@ -3366,7 +3368,6 @@ ConfigAttributesObj(
for (i = 0; i < objc; i += 2) {
optionPtr = objv[i];
- valuePtr = objv[i + 1];
if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
&index) != TCL_OK) {
@@ -3387,6 +3388,7 @@ ConfigAttributesObj(
}
return TCL_ERROR;
}
+ valuePtr = objv[i + 1];
switch (index) {
case FONT_FAMILY:
diff --git a/generic/tkFrame.c b/generic/tkFrame.c
index 8bc44ce..057b4b8 100644
--- a/generic/tkFrame.c
+++ b/generic/tkFrame.c
@@ -308,7 +308,7 @@ static int ConfigureFrame(Tcl_Interp *interp, Frame *framePtr,
static int CreateFrame(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const argv[],
enum FrameType type, const char *appName);
-static void DestroyFrame(char *memPtr);
+static void DestroyFrame(void *memPtr);
static void DestroyFramePartly(Frame *framePtr);
static void DisplayFrame(ClientData clientData);
static void FrameCmdDeletedProc(ClientData clientData);
@@ -727,8 +727,8 @@ FrameWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], frameOptions, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
Tcl_Preserve(framePtr);
@@ -834,10 +834,10 @@ FrameWidgetObjCmd(
static void
DestroyFrame(
- char *memPtr) /* Info about frame widget. */
+ void *memPtr) /* Info about frame widget. */
{
- register Frame *framePtr = (Frame *) memPtr;
- register Labelframe *labelframePtr = (Labelframe *) memPtr;
+ register Frame *framePtr = memPtr;
+ register Labelframe *labelframePtr = memPtr;
if (framePtr->type == TYPE_LABELFRAME) {
Tk_FreeTextLayout(labelframePtr->textLayout);
@@ -1656,7 +1656,7 @@ FrameEventProc(
Tcl_CancelIdleCall(DisplayFrame, framePtr);
}
Tcl_CancelIdleCall(MapFrame, framePtr);
- Tcl_EventuallyFree(framePtr, DestroyFrame);
+ Tcl_EventuallyFree(framePtr, (Tcl_FreeProc *) DestroyFrame);
} else if (eventPtr->type == FocusIn) {
if (eventPtr->xfocus.detail != NotifyInferior) {
framePtr->flags |= GOT_FOCUS;
diff --git a/generic/tkGrab.c b/generic/tkGrab.c
index 2df5552..00d4511 100644
--- a/generic/tkGrab.c
+++ b/generic/tkGrab.c
@@ -12,9 +12,9 @@
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
-#elif !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif
diff --git a/generic/tkGrid.c b/generic/tkGrid.c
index 19e4442..2a88b76 100644
--- a/generic/tkGrid.c
+++ b/generic/tkGrid.c
@@ -242,7 +242,7 @@ typedef struct UniformGroup {
* Tk will set its requested size to fit the
* needs of its slaves.
* ALLOCED_MASTER 1 means that Grid has allocated itself as
- * geometry master for this window.
+ * geometry master for this window.
*/
#define REQUESTED_RELAYOUT 1
@@ -262,7 +262,7 @@ static int CheckSlotData(Gridder *masterPtr, int slot,
int slotType, int checkOnly);
static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
int objc, Tcl_Obj *const objv[]);
-static void DestroyGrid(char *memPtr);
+static void DestroyGrid(void *memPtr);
static Gridder * GetGrid(Tk_Window tkwin);
static int GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
@@ -361,8 +361,8 @@ Tk_GridObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -910,7 +910,7 @@ GridPropagateCommand(
if (masterPtr->slavePtr != NULL) {
if (TkSetGeometryMaster(interp, master, "grid") != TCL_OK) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
masterPtr->flags |= ALLOCED_MASTER;
}
@@ -1076,8 +1076,8 @@ GridRowColumnConfigureCommand(
* returned.
*/
- if (Tcl_GetIndexFromObj(interp, objv[4], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[4], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
}
@@ -1175,8 +1175,8 @@ GridRowColumnConfigureCommand(
*/
for (i = 4; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
- "option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
Tcl_DecrRefCount(listCopy);
return TCL_ERROR;
}
@@ -1364,8 +1364,8 @@ GridSlavesCommand(
}
for (i = 3; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, objv[i+1], &value) != TCL_OK) {
@@ -2018,7 +2018,7 @@ ResolveConstraints(
if (slavePtr->numCols > 1) {
slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
layoutPtr[rightEdge].binNextPtr = slavePtr;
- } else {
+ } else if (rightEdge >= 0) {
int size = slavePtr->size + layoutPtr[rightEdge].pad;
if (size > layoutPtr[rightEdge].minSize) {
@@ -2037,7 +2037,7 @@ ResolveConstraints(
if (slavePtr->numRows > 1) {
slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr;
layoutPtr[rightEdge].binNextPtr = slavePtr;
- } else {
+ } else if (rightEdge >= 0) {
int size = slavePtr->size + layoutPtr[rightEdge].pad;
if (size > layoutPtr[rightEdge].minSize) {
@@ -2807,9 +2807,9 @@ Unlink(
static void
DestroyGrid(
- char *memPtr) /* Info about window that is now dead. */
+ void *memPtr) /* Info about window that is now dead. */
{
- register Gridder *gridPtr = (Gridder *) memPtr;
+ register Gridder *gridPtr = memPtr;
if (gridPtr->masterDataPtr != NULL) {
if (gridPtr->masterDataPtr->rowPtr != NULL) {
@@ -2886,7 +2886,7 @@ GridStructureProc(
Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
}
gridPtr->tkwin = NULL;
- Tcl_EventuallyFree(gridPtr, DestroyGrid);
+ Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
} else if (eventPtr->type == MapNotify) {
if ((gridPtr->slavePtr != NULL)
&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
@@ -3058,8 +3058,8 @@ ConfigureSlaves(
*/
for (i = numWindows; i < objc; i += 2) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
if (index == CONF_IN) {
@@ -3161,8 +3161,8 @@ ConfigureSlaves(
*/
for (i = numWindows; i < objc; i += 2) {
- Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0,
- &index);
+ Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &index);
switch ((enum options) index) {
case CONF_COLUMN:
if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK
diff --git a/generic/tkImage.c b/generic/tkImage.c
index ffa6f22..359d6c6 100644
--- a/generic/tkImage.c
+++ b/generic/tkImage.c
@@ -234,8 +234,8 @@ Tk_ImageObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], imageOptions, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum options) index) {
@@ -283,13 +283,11 @@ Tk_ImageObjCmd(
*/
if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
- Tcl_CmdInfo dummy;
-
do {
dispPtr->imageId++;
sprintf(idString, "image%d", dispPtr->imageId);
name = idString;
- } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0);
+ } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
firstOption = 3;
} else {
TkWindow *topWin;
diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c
index cdd57dd..0906673 100644
--- a/generic/tkImgBmap.c
+++ b/generic/tkImgBmap.c
@@ -330,7 +330,7 @@ ImgBmapConfigureMaster(
* None.
*
* Side effects:
- * Generates errors via Tcl_BackgroundError if there are problems in
+ * Generates errors via Tcl_BackgroundException if there are problems in
* setting up the instance.
*
*----------------------------------------------------------------------
@@ -448,7 +448,7 @@ ImgBmapConfigureInstance(
Tcl_AppendObjToErrorInfo(masterPtr->interp, Tcl_ObjPrintf(
"\n (while configuring image \"%s\")", Tk_NameOfImage(
masterPtr->tkMaster)));
- Tcl_BackgroundError(masterPtr->interp);
+ Tcl_BackgroundException(masterPtr->interp, TCL_ERROR);
}
/*
@@ -764,8 +764,8 @@ ImgBmapCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], bmapOptions, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], bmapOptions,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch (index) {
diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c
index fed4da4..1c28b54 100644
--- a/generic/tkImgGIF.c
+++ b/generic/tkImgGIF.c
@@ -393,7 +393,8 @@ FileReadGIF(
* image being read. */
{
int fileWidth, fileHeight, imageWidth, imageHeight;
- int nBytes, index = 0, argc = 0, i, result = TCL_ERROR;
+ unsigned int nBytes;
+ int index = 0, argc = 0, i, result = TCL_ERROR;
Tcl_Obj **objv;
unsigned char buf[100];
unsigned char *trashBuffer = NULL;
@@ -410,6 +411,7 @@ FileReadGIF(
* source and not a file.
*/
+ memset(colorMap, 0, MAXCOLORMAPSIZE*4);
memset(gifConfPtr, 0, sizeof(GIFImageConfig));
if (fileName == INLINE_DATA_BINARY || fileName == INLINE_DATA_BASE64) {
gifConfPtr->fromData = fileName;
@@ -425,8 +427,9 @@ FileReadGIF(
return TCL_ERROR;
}
for (i = 1; i < argc; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option name",
- 0, &nBytes) != TCL_OK) {
+ int optionIdx;
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option name", 0, &optionIdx) != TCL_OK) {
return TCL_ERROR;
}
if (i == (argc-1)) {
@@ -590,8 +593,14 @@ FileReadGIF(
*/
if (trashBuffer == NULL) {
+ if (fileWidth > (int)((UINT_MAX/3)/fileHeight)) {
+ goto error;
+ }
nBytes = fileWidth * fileHeight * 3;
trashBuffer = ckalloc(nBytes);
+ if (trashBuffer) {
+ memset(trashBuffer, 0, nBytes);
+ }
}
/*
@@ -675,9 +684,18 @@ FileReadGIF(
block.offset[1] = 1;
block.offset[2] = 2;
block.offset[3] = (transparent>=0) ? 3 : 0;
+ if (imageWidth > INT_MAX/block.pixelSize) {
+ goto error;
+ }
block.pitch = block.pixelSize * imageWidth;
+ if (imageHeight > (int)(UINT_MAX/block.pitch)) {
+ goto error;
+ }
nBytes = block.pitch * imageHeight;
block.pixelPtr = ckalloc(nBytes);
+ if (block.pixelPtr) {
+ memset(block.pixelPtr, 0, nBytes);
+ }
if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE),
diff --git a/generic/tkImgPNG.c b/generic/tkImgPNG.c
index b159c45..2ee515b 100644
--- a/generic/tkImgPNG.c
+++ b/generic/tkImgPNG.c
@@ -10,6 +10,7 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
+#include "assert.h"
#include "tkInt.h"
#define PNG_INT32(a,b,c,d) \
@@ -334,9 +335,11 @@ InitPNGImage(
if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB,
TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "zlib initialization failed", -1));
- Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "zlib initialization failed", -1));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL);
+ }
if (objPtr) {
Tcl_DecrRefCount(objPtr);
}
@@ -799,7 +802,7 @@ SkipChunk(
/*
* 4.3. Summary of standard chunks
*
- * This table summarizes some properties of the standard chunk types.
+ * This table summarizes some properties of the standard chunk types.
*
* Critical chunks (must appear in this order, except PLTE is optional):
*
@@ -1844,6 +1847,13 @@ DecodeLine(
if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
return TCL_ERROR;
}
+ if (pngPtr->currentLine >= pngPtr->block.height) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "PNG image data overflow"));
+ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "DATA_OVERFLOW", NULL);
+ return TCL_ERROR;
+ }
+
if (pngPtr->interlace) {
switch (pngPtr->phase) {
@@ -2173,10 +2183,13 @@ ReadIDAT(
/*
* Try to read another line of pixels out of the buffer
- * immediately.
+ * immediately, but don't allow write past end of block.
*/
- goto getNextLine;
+ if (pngPtr->currentLine < pngPtr->block.height) {
+ goto getNextLine;
+ }
+
}
/*
@@ -2281,10 +2294,10 @@ ParseFormat(
Tcl_Obj **objv = NULL;
int objc = 0;
static const char *const fmtOptions[] = {
- "png", "-alpha", NULL
+ "-alpha", NULL
};
enum fmtOptions {
- OPT_PNG, OPT_ALPHA
+ OPT_ALPHA
};
/*
@@ -2297,33 +2310,30 @@ ParseFormat(
}
for (; objc>0 ; objc--, objv++) {
- int optIndex;
-
- if (Tcl_GetIndexFromObj(interp, objv[0], fmtOptions, "option", 0,
- &optIndex) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ int optIndex;
/*
* Ignore the "png" part of the format specification.
*/
- if (OPT_PNG == optIndex) {
+ if (!strcasecmp(Tcl_GetString(objv[0]), "png")) {
continue;
}
- if (objc < 2) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions,
+ sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "value");
return TCL_ERROR;
- }
+ }
objc--;
objv++;
switch ((enum fmtOptions) optIndex) {
- case OPT_PNG:
- break;
-
case OPT_ALPHA:
if (Tcl_GetDoubleFromObj(interp, objv[0],
&pngPtr->alpha) == TCL_ERROR) {
@@ -2667,11 +2677,8 @@ FileMatchPNG(
{
PNGImage png;
int match = 0;
- Tcl_SavedResult sya;
-
- Tcl_SaveResult(interp, &sya);
- InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);
+ InitPNGImage(NULL, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);
if (ReadIHDR(interp, &png) == TCL_OK) {
*widthPtr = png.block.width;
@@ -2680,7 +2687,6 @@ FileMatchPNG(
}
CleanupPNGImage(&png);
- Tcl_RestoreResult(interp, &sya);
return match;
}
@@ -2759,10 +2765,8 @@ StringMatchPNG(
{
PNGImage png;
int match = 0;
- Tcl_SavedResult sya;
- Tcl_SaveResult(interp, &sya);
- InitPNGImage(interp, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE);
+ InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE);
png.strDataBuf = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen);
@@ -2773,7 +2777,6 @@ StringMatchPNG(
}
CleanupPNGImage(&png);
- Tcl_RestoreResult(interp, &sya);
return match;
}
@@ -3163,7 +3166,7 @@ WriteIDAT(
*destPtr++ = srcPtr[blockPtr->offset[0]];
- /*
+ /*
* If not grayscale, copy the green and blue channels.
*/
@@ -3353,7 +3356,7 @@ EncodePNG(
pngPtr->colorType = PNG_COLOR_RGBA;
pngPtr->bytesPerPixel = 4;
} else {
- pngPtr->colorType = PNG_COLOR_RGBA;
+ pngPtr->colorType = PNG_COLOR_RGB;
pngPtr->bytesPerPixel = 3;
}
} else {
diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c
index edd1b71..6f084f0 100644
--- a/generic/tkImgPPM.c
+++ b/generic/tkImgPPM.c
@@ -141,7 +141,7 @@ FileReadPPM(
* image being read. */
{
int fileWidth, fileHeight, maxIntensity;
- int nLines, nBytes, h, type, count;
+ int nLines, nBytes, h, type, count, bytesPerChannel = 1;
unsigned char *pixelPtr;
Tk_PhotoImageBlock block;
@@ -158,12 +158,14 @@ FileReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
return TCL_ERROR;
}
- if ((maxIntensity <= 0) || (maxIntensity >= 256)) {
+ if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"PPM image file \"%s\" has bad maximum intensity value %d",
fileName, maxIntensity));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);
return TCL_ERROR;
+ } else if (maxIntensity > 0x00ff) {
+ bytesPerChannel = 2;
}
if ((srcX + width) > fileWidth) {
@@ -173,20 +175,20 @@ FileReadPPM(
height = fileHeight - srcY;
}
if ((width <= 0) || (height <= 0)
- || (srcX >= fileWidth) || (srcY >= fileHeight)) {
+ || (srcX >= fileWidth) || (srcY >= fileHeight)) {
return TCL_OK;
}
if (type == PGM) {
- block.pixelSize = 1;
+ block.pixelSize = 1 * bytesPerChannel;
block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
} else {
- block.pixelSize = 3;
+ block.pixelSize = 3 * bytesPerChannel;
block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
+ block.offset[1] = 1 * bytesPerChannel;
+ block.offset[2] = 2 * bytesPerChannel;
}
block.offset[3] = 0;
block.width = width;
@@ -228,12 +230,21 @@ FileReadPPM(
ckfree(pixelPtr);
return TCL_ERROR;
}
- if (maxIntensity != 255) {
+ if (maxIntensity < 0x00ff) {
unsigned char *p;
for (p = pixelPtr; count > 0; count--, p++) {
*p = (((int) *p) * 255)/maxIntensity;
}
+ } else if (maxIntensity > 0x00ff) {
+ unsigned char *p;
+ unsigned int value;
+
+ for (p = pixelPtr; count > 0; count--, p += 2) {
+ value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
+ value = value * 255 / maxIntensity;
+ p[0] = p[1] = (unsigned char) value;
+ }
}
block.height = nLines;
if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
@@ -478,7 +489,7 @@ StringReadPPM(
* image being read. */
{
int fileWidth, fileHeight, maxIntensity;
- int nLines, nBytes, h, type, count, dataSize;
+ int nLines, nBytes, h, type, count, dataSize, bytesPerChannel = 1;
unsigned char *pixelPtr, *dataBuffer;
Tk_PhotoImageBlock block;
@@ -496,12 +507,14 @@ StringReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
return TCL_ERROR;
}
- if ((maxIntensity <= 0) || (maxIntensity >= 256)) {
+ if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"PPM image data has bad maximum intensity value %d",
maxIntensity));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);
return TCL_ERROR;
+ } else if (maxIntensity > 0x00ff) {
+ bytesPerChannel = 2;
}
if ((srcX + width) > fileWidth) {
@@ -516,15 +529,15 @@ StringReadPPM(
}
if (type == PGM) {
- block.pixelSize = 1;
+ block.pixelSize = 1 * bytesPerChannel;
block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
} else {
- block.pixelSize = 3;
+ block.pixelSize = 3 * bytesPerChannel;
block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
+ block.offset[1] = 1 * bytesPerChannel;
+ block.offset[2] = 2 * bytesPerChannel;
}
block.offset[3] = 0;
block.width = width;
@@ -535,7 +548,7 @@ StringReadPPM(
dataSize -= srcY * block.pitch;
}
- if (maxIntensity == 255) {
+ if (maxIntensity == 0x00ff) {
/*
* We have all the data in memory, so write everything in one go.
*/
@@ -582,8 +595,19 @@ StringReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
return TCL_ERROR;
}
- for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
- *p = (((int) *dataBuffer) * 255)/maxIntensity;
+ if (maxIntensity < 0x00ff) {
+ for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
+ *p = (((int) *dataBuffer) * 255)/maxIntensity;
+ }
+ } else {
+ unsigned char *p;
+ unsigned int value;
+
+ for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2) {
+ value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
+ value = value * 255 / maxIntensity;
+ p[0] = p[1] = (unsigned char) value;
+ }
}
dataSize -= nBytes;
block.height = nLines;
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index 3097489..666a9b0 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -64,7 +64,7 @@ static int imgPhotoColorHashInitialized;
* None.
*
* Side effects:
- * Generates errors via Tcl_BackgroundError if there are problems in
+ * Generates errors via Tcl_BackgroundException if there are problems in
* setting up the instance.
*
*----------------------------------------------------------------------
@@ -407,7 +407,7 @@ TkImgPhotoGet(
*----------------------------------------------------------------------
*/
-#ifndef __WIN32__
+#ifndef _WIN32
#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift))
@@ -419,7 +419,7 @@ TkImgPhotoGet(
(((r) * red_mask / 255) & red_mask) | \
(((g) * green_mask / 255) & green_mask) | \
(((b) * blue_mask / 255) & blue_mask) ))
-#endif /* !__WIN32__ */
+#endif /* !_WIN32 */
static void
BlendComplexAlpha(
@@ -453,7 +453,7 @@ BlendComplexAlpha(
* might be cached for better performance.
*/
-#ifndef __WIN32__
+#ifndef _WIN32
unsigned long red_mask, green_mask, blue_mask;
unsigned long red_shift, green_shift, blue_shift;
Visual *visual = iPtr->visualInfo.visual;
@@ -473,7 +473,7 @@ BlendComplexAlpha(
while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
blue_shift++;
}
-#endif /* !__WIN32__ */
+#endif /* !_WIN32 */
/*
* Only UNIX requires the special case for <24bpp. It varies with 3 extra
@@ -481,7 +481,7 @@ BlendComplexAlpha(
* optimized.
*/
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK))
if (bgImg->depth < 24) {
unsigned char red_mlen, green_mlen, blue_mlen;
@@ -529,7 +529,7 @@ BlendComplexAlpha(
}
return;
}
-#endif /* !__WIN32__ && !MAC_OSX_TK */
+#endif /* !_WIN32 && !MAC_OSX_TK */
for (y = 0; y < height; y++) {
line = (y + yOffset) * iPtr->masterPtr->width;
@@ -1336,12 +1336,12 @@ AllocateColors(
* since we will be passing the color table into the TkPutImage call.
*/
-#ifndef __WIN32__
+#ifndef _WIN32
if ((colorPtr->visualInfo.class != DirectColor)
&& (colorPtr->visualInfo.class != TrueColor)) {
colorPtr->flags |= MAP_COLORS;
}
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
}
colorPtr->numColors = numColors;
@@ -1770,7 +1770,7 @@ TkImgDitherInstance(
case NBBY:
*destBytePtr++ = i;
break;
-#ifndef __WIN32__
+#ifndef _WIN32
/*
* This case is not valid for Windows because the
* image format is different from the pixel format in
@@ -1832,7 +1832,7 @@ TkImgDitherInstance(
case NBBY:
*destBytePtr++ = i;
break;
-#ifndef __WIN32__
+#ifndef _WIN32
/*
* This case is not valid for Windows because the
* image format is different from the pixel format in
diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c
index ce160a4..3e03f3d 100644
--- a/generic/tkImgPhoto.c
+++ b/generic/tkImgPhoto.c
@@ -230,7 +230,7 @@ PhotoFormatThreadExitProc(
while (tsdPtr->formatList != NULL) {
freePtr = tsdPtr->formatList;
tsdPtr->formatList = tsdPtr->formatList->nextPtr;
- ckfree(freePtr->name);
+ ckfree((char *)freePtr->name);
ckfree(freePtr);
}
}
@@ -886,6 +886,19 @@ ImgPhotoCmd(
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) {
@@ -2051,8 +2064,8 @@ static int
ToggleComplexAlphaIfNeeded(
PhotoMaster *mPtr)
{
- size_t len = MAX(mPtr->userWidth, mPtr->width) *
- MAX(mPtr->userHeight, mPtr->height) * 4;
+ size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
+ (size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
unsigned char *c = mPtr->pix32;
unsigned char *end = c + len;
@@ -2062,6 +2075,9 @@ ToggleComplexAlphaIfNeeded(
*/
mPtr->flags &= ~COMPLEX_ALPHA;
+ if (c == NULL) {
+ return 0;
+ }
c += 3; /* Start at first alpha byte. */
for (; c < end; c += 4) {
if (*c && *c != 255) {
@@ -2192,6 +2208,10 @@ ImgPhotoSetSize(
height = masterPtr->userHeight;
}
+ if (width > INT_MAX / 4) {
+ /* Pitch overflows int */
+ return TCL_ERROR;
+ }
pitch = width * 4;
/*
@@ -2201,11 +2221,12 @@ ImgPhotoSetSize(
if ((width != masterPtr->width) || (height != masterPtr->height)
|| (masterPtr->pix32 == NULL)) {
- /*
- * Not a u-long, but should be one.
- */
+ unsigned newPixSize;
- unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch);
+ if (pitch && height > (int)(UINT_MAX / pitch)) {
+ return TCL_ERROR;
+ }
+ newPixSize = height * pitch;
/*
* Some mallocs() really hate allocating zero bytes. [Bug 619544]
@@ -2257,14 +2278,14 @@ ImgPhotoSetSize(
if ((masterPtr->pix32 != NULL)
&& ((width == masterPtr->width) || (width == validBox.width))) {
if (validBox.y > 0) {
- memset(newPix32, 0, (size_t) (validBox.y * pitch));
+ memset(newPix32, 0, ((size_t) validBox.y * pitch));
}
h = validBox.y + validBox.height;
if (h < height) {
- memset(newPix32 + h*pitch, 0, (size_t) ((height - h) * pitch));
+ memset(newPix32 + h*pitch, 0, ((size_t) (height - h) * pitch));
}
} else {
- memset(newPix32, 0, (size_t) (height * pitch));
+ memset(newPix32, 0, ((size_t)height * pitch));
}
if (masterPtr->pix32 != NULL) {
@@ -2281,7 +2302,7 @@ ImgPhotoSetSize(
offset = validBox.y * pitch;
memcpy(newPix32 + offset, masterPtr->pix32 + offset,
- (size_t) (validBox.height * pitch));
+ ((size_t)validBox.height * pitch));
} else if ((validBox.width > 0) && (validBox.height > 0)) {
/*
@@ -2292,7 +2313,7 @@ ImgPhotoSetSize(
srcPtr = masterPtr->pix32 + (validBox.y * masterPtr->width
+ validBox.x) * 4;
for (h = validBox.height; h > 0; h--) {
- memcpy(destPtr, srcPtr, (size_t) (validBox.width * 4));
+ memcpy(destPtr, srcPtr, ((size_t)validBox.width * 4));
destPtr += width * 4;
srcPtr += masterPtr->width * 4;
}
@@ -2772,7 +2793,7 @@ Tk_PhotoPutBlock(
&& (blockPtr->pitch == pitch)))
&& (compRule == TK_PHOTO_COMPOSITE_SET)) {
memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0],
- (size_t) (height * width * 4));
+ ((size_t)height * width * 4));
/*
* We know there's an alpha offset and we're setting the data, so skip
@@ -2804,7 +2825,7 @@ Tk_PhotoPutBlock(
&& (blueOffset == 2) && (alphaOffset == 3)
&& (width <= blockPtr->width)
&& compRuleSet) {
- memcpy(destLinePtr, srcLinePtr, (size_t) (width * 4));
+ memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4));
srcLinePtr += blockPtr->pitch;
destLinePtr += pitch;
continue;
@@ -3454,7 +3475,7 @@ Tk_PhotoBlank(
*/
memset(masterPtr->pix32, 0,
- (size_t) (masterPtr->width * masterPtr->height * 4));
+ ((size_t)masterPtr->width * masterPtr->height * 4));
for (instancePtr = masterPtr->instancePtr; instancePtr != NULL;
instancePtr = instancePtr->nextPtr) {
TkImgResetDither(instancePtr);
@@ -3684,10 +3705,7 @@ ImgGetPhoto(
}
}
if (!alphaOffset) {
- blockPtr->pixelPtr--;
- blockPtr->offset[0]++;
- blockPtr->offset[1]++;
- blockPtr->offset[2]++;
+ blockPtr->offset[3]= -1; /* Tell caller alpha need not be read */
}
greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
@@ -3702,6 +3720,10 @@ ImgGetPhoto(
if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) {
newPixelSize += 2;
}
+
+ if (blockPtr->height > (int)((UINT_MAX/newPixelSize)/blockPtr->width)) {
+ return NULL;
+ }
data = attemptckalloc(newPixelSize*blockPtr->width*blockPtr->height);
if (data == NULL) {
return NULL;
@@ -3803,9 +3825,11 @@ ImgGetPhoto(
if (newPixelSize > 2) {
blockPtr->offset[1] = 1;
blockPtr->offset[2] = 2;
+ blockPtr->offset[3]= 3;
} else {
blockPtr->offset[1] = 0;
blockPtr->offset[2] = 0;
+ blockPtr->offset[3]= 1;
}
return data;
}
@@ -3836,32 +3860,30 @@ ImgStringWrite(
Tk_PhotoImageBlock *blockPtr)
{
int greenOffset, blueOffset;
- Tcl_DString data;
+ Tcl_Obj *data;
greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
- Tcl_DStringInit(&data);
+ data = Tcl_NewObj();
if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
- char *line = ckalloc((8 * blockPtr->width) + 2);
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;
- char *linePtr = line;
for (col=0; col<blockPtr->width; col++) {
- sprintf(linePtr, " #%02x%02x%02x", *pixelPtr,
+ Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x",
+ col ? " " : "", *pixelPtr,
pixelPtr[greenOffset], pixelPtr[blueOffset]);
pixelPtr += blockPtr->pixelSize;
- linePtr += 8;
}
- Tcl_DStringAppendElement(&data, line+1);
+ Tcl_ListObjAppendElement(NULL, data, line);
}
- ckfree(line);
}
- Tcl_DStringResult(interp, &data);
+ Tcl_SetObjResult(interp, data);
return TCL_OK;
}
diff --git a/generic/tkImgPhoto.h b/generic/tkImgPhoto.h
index 7bef76b..36bc6cb 100644
--- a/generic/tkImgPhoto.h
+++ b/generic/tkImgPhoto.h
@@ -17,7 +17,7 @@
*/
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index 2ee9d1c..586b407 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -506,12 +506,12 @@ declare 154 {
# entries needed only by tktest:
declare 156 {
- int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int argc,
- const char **argv)
+ int TkpTestembedCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[])
}
declare 157 {
- int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int argc,
- const char **argv)
+ int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[])
}
declare 158 {
int TkSelGetSelection(Tcl_Interp *interp, Tk_Window tkwin,
@@ -684,8 +684,8 @@ declare 12 x11 {
}
# only needed by tktest:
declare 13 x11 {
- int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc,
- const char **argv)
+ int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[])
}
################################
@@ -841,8 +841,8 @@ declare 44 win {
}
# only needed by tktest:
declare 45 win {
- int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int argc,
- const char **argv)
+ int TkpTestsendCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[])
}
################################
@@ -1017,6 +1017,9 @@ declare 50 aqua {
declare 51 aqua {
void TkGenWMDestroyEvent(Tk_Window tkwin)
}
+declare 52 aqua {
+ void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag)
+}
# removed duplicate from tkPlat table (tk.decls)
#declare 52 aqua {
@@ -1032,6 +1035,9 @@ declare 53 aqua {
declare 54 aqua {
void *TkMacOSXDrawable(Drawable drawable)
}
+declare 55 aqua {
+ int TkpScanWindowId(Tcl_Interp *interp, const char *string, Window *idPtr)
+}
##############################################################################
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 21b882c..b644c5b 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -526,6 +526,7 @@ typedef struct TkDisplay {
#define TK_DISPLAY_USE_IM (1 << 1)
#define TK_DISPLAY_WM_TRACING (1 << 3)
#define TK_DISPLAY_IN_WARP (1 << 4)
+#define TK_DISPLAY_USE_XKB (1 << 5)
/*
* One of the following structures exists for each error handler created by a
@@ -1076,6 +1077,9 @@ MODULE_SCOPE int Tk_ListboxObjCmd(ClientData clientData,
MODULE_SCOPE int Tk_LowerObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tk_MenuObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tk_MenubuttonObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -1106,13 +1110,15 @@ MODULE_SCOPE int Tk_RaiseObjCmd(ClientData clientData,
MODULE_SCOPE int Tk_ScaleObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-MODULE_SCOPE int Tk_ScrollbarCmd(ClientData clientData,
- Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int Tk_ScrollbarObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tk_SelectionObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-MODULE_SCOPE int Tk_SendCmd(ClientData clientData,
- Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData,
+ Tcl_Interp *interp,int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tk_SendObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -1147,9 +1153,8 @@ MODULE_SCOPE void TkFreeGeometryMaster(Tk_Window tkwin,
MODULE_SCOPE void TkEventInit(void);
MODULE_SCOPE void TkRegisterObjTypes(void);
-MODULE_SCOPE int TkCreateMenuCmd(Tcl_Interp *interp);
-MODULE_SCOPE int TkDeadAppCmd(ClientData clientData,
- Tcl_Interp *interp, int argc, const char **argv);
+MODULE_SCOPE int TkDeadAppObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]);
MODULE_SCOPE int TkCanvasGetCoordObj(Tcl_Interp *interp,
Tk_Canvas canvas, Tcl_Obj *obj,
double *doublePtr);
@@ -1213,7 +1218,7 @@ MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp,
ClientData clientData);
MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr);
-#ifdef __WIN32__
+#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
@@ -1239,7 +1244,7 @@ MODULE_SCOPE int SquareObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
MODULE_SCOPE int TkOldTestInit(Tcl_Interp *interp);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#define TkplatformtestInit(x) TCL_OK
#else
MODULE_SCOPE int TkplatformtestInit(Tcl_Interp *interp);
diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h
index 8d36ec0..b8addbd 100644
--- a/generic/tkIntDecls.h
+++ b/generic/tkIntDecls.h
@@ -35,6 +35,10 @@ struct TkSharedText;
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -429,11 +433,11 @@ EXTERN void TkDeleteThreadExitHandler(Tcl_ExitProc *proc,
/* Slot 155 is reserved */
/* 156 */
EXTERN int TkpTestembedCmd(ClientData clientData,
- Tcl_Interp *interp, int argc,
- const char **argv);
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
/* 157 */
EXTERN int TkpTesttextCmd(ClientData dummy, Tcl_Interp *interp,
- int argc, const char **argv);
+ int objc, Tcl_Obj *const objv[]);
/* 158 */
EXTERN int TkSelGetSelection(Tcl_Interp *interp,
Tk_Window tkwin, Atom selection, Atom target,
@@ -549,7 +553,7 @@ EXTERN void TkDrawAngledChars(Display *display,
typedef struct TkIntStubs {
int magic;
- const struct TkIntStubHooks *hooks;
+ void *hooks;
TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */
void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */
@@ -672,20 +676,20 @@ typedef struct TkIntStubs {
void (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */
void (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion dr_return); /* 119 */
void (*reserved120)(void);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
void (*reserved121)(void);
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved121)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */
Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
void (*reserved122)(void);
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved122)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
@@ -693,10 +697,10 @@ typedef struct TkIntStubs {
void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
void (*reserved123)(void);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
void (*reserved124)(void);
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
void (*reserved124)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
@@ -734,8 +738,8 @@ typedef struct TkIntStubs {
void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */
void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */
void (*reserved155)(void);
- int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); /* 156 */
- int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); /* 157 */
+ int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */
+ int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */
int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */
int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */
@@ -765,10 +769,8 @@ typedef struct TkIntStubs {
void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
} TkIntStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TkIntStubs *tkIntStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -1148,7 +1150,7 @@ extern const TkIntStubs *tkIntStubsPtr;
/*
* On X11, these macros are just wrappers for the equivalent X Region calls.
*/
-#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#undef TkClipBox
#undef TkCreateRegion
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index e2528d8..e48e803 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -26,11 +26,15 @@
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN char * TkAlignImageData(XImage *image, int alignment,
int bitOrder);
@@ -136,8 +140,8 @@ EXTERN void TkWmCleanup(TkDisplay *dispPtr);
EXTERN void TkSendCleanup(TkDisplay *dispPtr);
/* 45 */
EXTERN int TkpTestsendCmd(ClientData clientData,
- Tcl_Interp *interp, int argc,
- const char **argv);
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* 0 */
@@ -246,13 +250,17 @@ EXTERN int TkGenerateButtonEvent(int x, int y, Window window,
unsigned int state);
/* 51 */
EXTERN void TkGenWMDestroyEvent(Tk_Window tkwin);
-/* Slot 52 is reserved */
+/* 52 */
+EXTERN void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);
/* 53 */
EXTERN unsigned long TkpGetMS(void);
/* 54 */
EXTERN void * TkMacOSXDrawable(Drawable drawable);
+/* 55 */
+EXTERN int TkpScanWindowId(Tcl_Interp *interp,
+ const char *string, Window *idPtr);
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
/* 0 */
EXTERN void TkCreateXEventSource(void);
/* Slot 1 is reserved */
@@ -279,15 +287,15 @@ EXTERN void TkSendCleanup(TkDisplay *dispPtr);
EXTERN int TkpWmSetState(TkWindow *winPtr, int state);
/* 13 */
EXTERN int TkpTestsendCmd(ClientData clientData,
- Tcl_Interp *interp, int argc,
- const char **argv);
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
#endif /* X11 */
typedef struct TkIntPlatStubs {
int magic;
- const struct TkIntPlatStubHooks *hooks;
+ void *hooks;
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
char * (*tkAlignImageData) (XImage *image, int alignment, int bitOrder); /* 0 */
void (*reserved1)(void);
void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 2 */
@@ -333,7 +341,7 @@ typedef struct TkIntPlatStubs {
void (*tkUnixSetMenubar) (Tk_Window tkwin, Tk_Window menubar); /* 42 */
void (*tkWmCleanup) (TkDisplay *dispPtr); /* 43 */
void (*tkSendCleanup) (TkDisplay *dispPtr); /* 44 */
- int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); /* 45 */
+ int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 45 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
void (*tkGenerateActivateEvents) (TkWindow *winPtr, int active); /* 0 */
@@ -388,11 +396,12 @@ typedef struct TkIntPlatStubs {
Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
- void (*reserved52)(void);
+ void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
unsigned long (*tkpGetMS) (void); /* 53 */
void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
+ int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
void (*tkCreateXEventSource) (void); /* 0 */
void (*reserved1)(void);
void (*reserved2)(void);
@@ -406,14 +415,12 @@ typedef struct TkIntPlatStubs {
void (*tkSendCleanup) (TkDisplay *dispPtr); /* 10 */
void (*reserved11)(void);
int (*tkpWmSetState) (TkWindow *winPtr, int state); /* 12 */
- int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); /* 13 */
+ int (*tkpTestsendCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 13 */
#endif /* X11 */
} TkIntPlatStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TkIntPlatStubs *tkIntPlatStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -424,7 +431,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
* Inline function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define TkAlignImageData \
(tkIntPlatStubsPtr->tkAlignImageData) /* 0 */
/* Slot 1 is reserved */
@@ -615,13 +622,16 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
-/* Slot 52 is reserved */
+#define TkMacOSXSetDrawingEnabled \
+ (tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \
(tkIntPlatStubsPtr->tkpGetMS) /* 53 */
#define TkMacOSXDrawable \
(tkIntPlatStubsPtr->tkMacOSXDrawable) /* 54 */
+#define TkpScanWindowId \
+ (tkIntPlatStubsPtr->tkpScanWindowId) /* 55 */
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
#define TkCreateXEventSource \
(tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */
/* Slot 1 is reserved */
diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h
index 5b0f267..6ac7ccb 100644
--- a/generic/tkIntXlibDecls.h
+++ b/generic/tkIntXlibDecls.h
@@ -36,11 +36,15 @@ typedef int (*XAfterFunction) ( /* WARNING, this type not in Xlib spec */
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN int XSetDashes(Display *display, GC gc, int dash_offset,
_Xconst char *dash_list, int n);
@@ -620,9 +624,9 @@ EXTERN int XSync(Display *display, Bool flag);
typedef struct TkIntXlibStubs {
int magic;
- const struct TkIntXlibStubHooks *hooks;
+ void *hooks;
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
@@ -835,10 +839,8 @@ typedef struct TkIntXlibStubs {
#endif /* AQUA */
} TkIntXlibStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TkIntXlibStubs *tkIntXlibStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -849,7 +851,7 @@ extern const TkIntXlibStubs *tkIntXlibStubsPtr;
* Inline function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define XSetDashes \
(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#define XGetModifierMapping \
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 620f82f..c7effdd 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -15,7 +15,7 @@
#include "default.h"
#include "tkInt.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "tkWinInt.h"
#endif
@@ -90,14 +90,14 @@ typedef struct {
* display. */
int topIndex; /* Index of top-most element visible in
* window. */
- int fullLines; /* Number of lines that fit are completely
+ int fullLines; /* Number of lines that are completely
* visible in window. There may be one
* additional line at the bottom that is
* partially visible. */
int partialLine; /* 0 means that the window holds exactly
* fullLines lines. 1 means that there is one
* additional line that is partially
- * visble. */
+ * visible. */
int setGrid; /* Non-zero means pass gridding information to
* window manager. */
@@ -114,7 +114,8 @@ typedef struct {
int xOffset; /* The left edge of each string in the listbox
* is offset to the left by this many pixels
* (0 means no offset, positive means there is
- * an offset). */
+ * an offset). This is x scrolling information
+ * is not linked to justification. */
/*
* Information about what's selected or active, if any.
@@ -131,7 +132,7 @@ typedef struct {
int active; /* Index of "active" element (the one that has
* been selected by keyboard traversal). -1
* means none. */
- int activeStyle; /* style in which to draw the active element.
+ int activeStyle; /* Style in which to draw the active element.
* One of: underline, none, dotbox */
/*
@@ -165,6 +166,7 @@ typedef struct {
Pixmap gray; /* Pixmap for displaying disabled text. */
int flags; /* Various flag bits: see below for
* definitions. */
+ Tk_Justify justify; /* Justification. */
} Listbox;
/*
@@ -197,7 +199,7 @@ typedef struct {
* be updated.
* GOT_FOCUS: Non-zero means this widget currently has the
* input focus.
- * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date
+ * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date.
* LISTBOX_DELETED: This listbox has been effectively destroyed.
*/
@@ -275,6 +277,8 @@ static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1,
Tk_Offset(Listbox, highlightWidth), 0, 0, 0},
+ {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
+ DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
@@ -285,7 +289,7 @@ static const Tk_OptionSpec optionSpecs[] = {
Tk_Offset(Listbox, selBorderWidth), 0, 0, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(Listbox, selFgColorPtr),
- TK_CONFIG_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
{TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
DEF_LISTBOX_SELECT_MODE, -1, Tk_Offset(Listbox, selectMode),
TK_OPTION_NULL_OK, 0, 0},
@@ -313,7 +317,7 @@ static const Tk_OptionSpec optionSpecs[] = {
/*
* The itemAttrOptionSpecs table defines the valid configuration options for
- * listbox items
+ * listbox items.
*/
static const Tk_OptionSpec itemAttrOptionSpecs[] = {
@@ -340,7 +344,7 @@ static const Tk_OptionSpec itemAttrOptionSpecs[] = {
};
/*
- * The following tables define the listbox widget commands (and sub- commands)
+ * The following tables define the listbox widget commands (and sub-commands)
* and map the indexes into the string tables into enumerated types used to
* dispatch the listbox widget command.
*/
@@ -386,13 +390,13 @@ enum indices {
static void ChangeListboxOffset(Listbox *listPtr, int offset);
static void ChangeListboxView(Listbox *listPtr, int index);
static int ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
- int objc, Tcl_Obj *const objv[], int flags);
+ int objc, Tcl_Obj *const objv[]);
static int ConfigureListboxItem(Tcl_Interp *interp,
Listbox *listPtr, ItemAttr *attrs, int objc,
Tcl_Obj *const objv[], int index);
static int ListboxDeleteSubCmd(Listbox *listPtr,
int first, int last);
-static void DestroyListbox(char *memPtr);
+static void DestroyListbox(void *memPtr);
static void DestroyListboxOptionTables(ClientData clientData,
Tcl_Interp *interp);
static void DisplayListbox(ClientData clientData);
@@ -408,6 +412,7 @@ static void ListboxEventProc(ClientData clientData,
static int ListboxFetchSelection(ClientData clientData,
int offset, char *buffer, int maxBytes);
static void ListboxLostSelection(ClientData clientData);
+static void GenerateListboxSelectEvent(Listbox *listPtr);
static void EventuallyRedrawRange(Listbox *listPtr,
int first, int last);
static void ListboxScanTo(Listbox *listPtr, int x, int y);
@@ -435,6 +440,7 @@ static char * ListboxListVarProc(ClientData clientData,
const char *name2, int flags);
static void MigrateHashEntries(Tcl_HashTable *table,
int first, int last, int offset);
+static int GetMaxOffset(Listbox *listPtr);
/*
* The structure below defines button class behavior by means of procedures
@@ -545,6 +551,7 @@ Tk_ListboxObjCmd(
listPtr->cursor = None;
listPtr->state = STATE_NORMAL;
listPtr->gray = None;
+ listPtr->justify = TK_JUSTIFY_LEFT;
/*
* Keep a hold of the associated tkwin until we destroy the listbox,
@@ -566,7 +573,7 @@ Tk_ListboxObjCmd(
return TCL_ERROR;
}
- if (ConfigureListbox(interp, listPtr, objc-2, objv+2, 0) != TCL_OK) {
+ if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
Tk_DestroyWindow(listPtr->tkwin);
return TCL_ERROR;
}
@@ -612,7 +619,7 @@ ListboxWidgetObjCmd(
/*
* Parse the command by looking up the second argument in the list of
- * valid subcommand names
+ * valid subcommand names.
*/
result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
@@ -697,7 +704,7 @@ ListboxWidgetObjCmd(
Tcl_SetObjResult(interp, objPtr);
result = TCL_OK;
} else {
- result = ConfigureListbox(interp, listPtr, objc-2, objv+2, 0);
+ result = ConfigureListbox(interp, listPtr, objc-2, objv+2);
}
break;
@@ -1075,6 +1082,7 @@ ListboxBboxSubCmd(
Listbox *listPtr, /* Information about the listbox */
int index) /* Index of the element to get bbox info on */
{
+ register Tk_Window tkwin = listPtr->tkwin;
int lastVisibleIndex;
/*
@@ -1110,7 +1118,15 @@ ListboxBboxSubCmd(
Tk_GetFontMetrics(listPtr->tkfont, &fm);
pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
- x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
+ if (listPtr->justify == TK_JUSTIFY_LEFT) {
+ x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
+ } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
+ x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
+ - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr);
+ } else {
+ x = (Tk_Width(tkwin) - pixelWidth)/2
+ - listPtr->xOffset + GetMaxOffset(listPtr)/2;
+ }
y = ((index - listPtr->topIndex)*listPtr->lineHeight)
+ listPtr->inset + listPtr->selBorderWidth;
results[0] = Tcl_NewIntObj(x);
@@ -1428,9 +1444,9 @@ ListboxGetItemAttributes(
static void
DestroyListbox(
- char *memPtr) /* Info about listbox widget. */
+ void *memPtr) /* Info about listbox widget. */
{
- register Listbox *listPtr = (Listbox *) memPtr;
+ register Listbox *listPtr = memPtr;
Tcl_HashEntry *entry;
Tcl_HashSearch search;
@@ -1444,7 +1460,7 @@ DestroyListbox(
}
if (listPtr->listVarName != NULL) {
- Tcl_UntraceVar(listPtr->interp, listPtr->listVarName,
+ Tcl_UntraceVar2(listPtr->interp, listPtr->listVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, listPtr);
}
@@ -1542,8 +1558,7 @@ ConfigureListbox(
register Listbox *listPtr, /* Information about widget; may or may not
* already have values for some fields. */
int objc, /* Number of valid entries in argv. */
- Tcl_Obj *const objv[], /* Arguments. */
- int flags) /* Flags to pass to Tk_ConfigureWidget. */
+ Tcl_Obj *const objv[]) /* Arguments. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *oldListObj = NULL;
@@ -1552,7 +1567,7 @@ ConfigureListbox(
oldExport = listPtr->exportSelection;
if (listPtr->listVarName != NULL) {
- Tcl_UntraceVar(interp, listPtr->listVarName,
+ Tcl_UntraceVar2(interp, listPtr->listVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, listPtr);
}
@@ -1629,9 +1644,6 @@ ConfigureListbox(
if (Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
listVarObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
== NULL) {
- if (oldListObj == NULL) {
- Tcl_DecrRefCount(listVarObj);
- }
continue;
}
}
@@ -1648,8 +1660,8 @@ ConfigureListbox(
}
listPtr->listObj = listVarObj;
- Tcl_TraceVar(listPtr->interp, listPtr->listVarName,
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(listPtr->interp, listPtr->listVarName,
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, listPtr);
} else if (listPtr->listObj == NULL) {
listPtr->listObj = Tcl_NewObj();
@@ -1840,6 +1852,7 @@ DisplayListbox(
* or right edge of the listbox is
* off-screen. */
Pixmap pixmap;
+ int textWidth;
listPtr->flags &= ~REDRAW_PENDING;
if (listPtr->flags & LISTBOX_DELETED) {
@@ -2019,7 +2032,7 @@ DisplayListbox(
} else {
/*
* If there is an item attributes record for this item, draw
- * the background box and set the foreground color accordingly
+ * the background box and set the foreground color accordingly.
*/
if (entry != NULL) {
@@ -2059,12 +2072,24 @@ DisplayListbox(
* Draw the actual text of this item.
*/
+ Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
+ stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
+ textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);
+
Tk_GetFontMetrics(listPtr->tkfont, &fm);
y += fm.ascent + listPtr->selBorderWidth;
- x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
- Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
- stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
- Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
+
+ if (listPtr->justify == TK_JUSTIFY_LEFT) {
+ x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
+ } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
+ x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
+ - textWidth - listPtr->xOffset + GetMaxOffset(listPtr);
+ } else {
+ x = (Tk_Width(tkwin) - textWidth)/2
+ - listPtr->xOffset + GetMaxOffset(listPtr)/2;
+ }
+
+ Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
stringRep, stringLen, x, y);
/*
@@ -2080,7 +2105,7 @@ DisplayListbox(
Tk_UnderlineChars(listPtr->display, pixmap, gc,
listPtr->tkfont, stringRep, x, y, 0, stringLen);
} else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
-#ifdef WIN32
+#ifdef _WIN32
/*
* This provides for exact default look and feel on Windows.
*/
@@ -2097,7 +2122,7 @@ DisplayListbox(
rect.bottom = rect.top + listPtr->lineHeight;
DrawFocusRect(dc, &rect);
TkWinReleaseDrawableDC(pixmap, dc, &state);
-#else /* !WIN32 */
+#else /* !_WIN32 */
/*
* Draw a dotted box around the text.
*/
@@ -2136,7 +2161,7 @@ DisplayListbox(
gcValues.line_style = LineSolid;
XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
}
-#endif /* WIN32 */
+#endif /* _WIN32 */
}
}
@@ -2461,7 +2486,7 @@ ListboxDeleteSubCmd(
/*
* Check width of the element. We only have to check if widthChanged
* has not already been set to 1, because we only need one maxWidth
- * element to disappear for us to have to recompute the width
+ * element to disappear for us to have to recompute the width.
*/
if (widthChanged == 0) {
@@ -2601,7 +2626,7 @@ ListboxEventProc(
if (listPtr->flags & REDRAW_PENDING) {
Tcl_CancelIdleCall(DisplayListbox, clientData);
}
- Tcl_EventuallyFree(clientData, DestroyListbox);
+ Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyListbox);
}
} else if (eventPtr->type == ConfigureNotify) {
int vertSpace;
@@ -2738,7 +2763,11 @@ GetListboxIndex(
stringRep = Tcl_GetString(indexObj);
if (stringRep[0] == '@') {
- /* @x,y index */
+
+ /*
+ * @x,y index
+ */
+
int y;
const char *start;
char *end;
@@ -2847,9 +2876,7 @@ ChangeListboxOffset(
*/
offset += listPtr->xScrollUnit / 2;
- maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) -
- 2*listPtr->inset - 2*listPtr->selBorderWidth)
- + listPtr->xScrollUnit - 1;
+ maxOffset = GetMaxOffset(listPtr);
if (offset > maxOffset) {
offset = maxOffset;
}
@@ -2890,9 +2917,7 @@ ListboxScanTo(
int newTopIndex, newOffset, maxIndex, maxOffset;
maxIndex = listPtr->nElements - listPtr->fullLines;
- maxOffset = listPtr->maxWidth + (listPtr->xScrollUnit - 1)
- - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset
- - 2*listPtr->selBorderWidth - listPtr->xScrollUnit);
+ maxOffset = GetMaxOffset(listPtr);
/*
* Compute new top line for screen by amplifying the difference between
@@ -3173,12 +3198,46 @@ ListboxLostSelection(
if ((listPtr->exportSelection) && (listPtr->nElements > 0)) {
ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
+ GenerateListboxSelectEvent(listPtr);
}
}
/*
*----------------------------------------------------------------------
*
+ * GenerateListboxSelectEvent --
+ *
+ * Send an event that the listbox selection was updated. This is
+ * equivalent to event generate $listboxWidget <<ListboxSelect>>
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Any side effect possible, depending on bindings to this event.
+ *
+ *----------------------------------------------------------------------
+ */
+
+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);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* EventuallyRedrawRange --
*
* Ensure that a given range of elements is eventually redrawn on the
@@ -3244,6 +3303,7 @@ ListboxUpdateVScrollbar(
double first, last;
int result;
Tcl_Interp *interp;
+ Tcl_DString buf;
if (listPtr->yScrollCmd == NULL) {
return;
@@ -3269,8 +3329,14 @@ ListboxUpdateVScrollbar(
interp = listPtr->interp;
Tcl_Preserve(interp);
- result = Tcl_VarEval(interp, listPtr->yScrollCmd, " ", firstStr, " ",
- lastStr, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, listPtr->yScrollCmd, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, firstStr, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, lastStr, -1);
+ result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (vertical scrolling command executed by listbox)");
@@ -3307,6 +3373,7 @@ ListboxUpdateHScrollbar(
int result, windowWidth;
double first, last;
Tcl_Interp *interp;
+ Tcl_DString buf;
if (listPtr->xScrollCmd == NULL) {
return;
@@ -3334,8 +3401,14 @@ ListboxUpdateHScrollbar(
interp = listPtr->interp;
Tcl_Preserve(interp);
- result = Tcl_VarEval(interp, listPtr->xScrollCmd, " ", firstStr, " ",
- lastStr, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, listPtr->xScrollCmd, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, firstStr, -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, lastStr, -1);
+ result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (result != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (horizontal scrolling command executed by listbox)");
@@ -3381,8 +3454,8 @@ ListboxListVarProc(
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL,
listPtr->listObj, TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, listPtr->listVarName,
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, listPtr->listVarName,
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ListboxListVarProc, clientData);
return NULL;
}
@@ -3420,7 +3493,7 @@ ListboxListVarProc(
/*
* If the list length has decreased, then we should clean up selection and
- * attributes information for elements past the end of the new list
+ * attributes information for elements past the end of the new list.
*/
oldLength = listPtr->nElements;
@@ -3538,6 +3611,42 @@ MigrateHashEntries(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * GetMaxOffset --
+ *
+ * Passing in a listbox pointer, returns the maximum offset for the box,
+ * i.e. the maximum possible horizontal scrolling value (in pixels).
+ *
+ * Results:
+ * Listbox's maxOffset.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+*/
+static int GetMaxOffset(
+ register Listbox *listPtr)
+{
+ int maxOffset;
+
+ maxOffset = listPtr->maxWidth -
+ (Tk_Width(listPtr->tkwin) - 2*listPtr->inset -
+ 2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1;
+ if (maxOffset < 0) {
+
+ /*
+ * Listbox is larger in width than its largest width item.
+ */
+
+ maxOffset = 0;
+ }
+ maxOffset -= maxOffset % listPtr->xScrollUnit;
+
+ return maxOffset;
+}
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tkMain.c b/generic/tkMain.c
index 706f444..1b21223 100644
--- a/generic/tkMain.c
+++ b/generic/tkMain.c
@@ -54,8 +54,17 @@ extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
* platforms which don't have <tchar.h> we have to translate that
* to strcmp here.
*/
-#ifdef __WIN32__
-# include "tclInt.h"
+#ifdef _WIN32
+/* Little hack to eliminate the need for "tclInt.h" here:
+ Just copy a small portion of TclIntPlatStubs, just
+ enough to make it work. See [600b72bfbc] */
+typedef struct {
+ int magic;
+ void *hooks;
+ void (*dummy[16]) (void); /* dummy entries 0-15, not used */
+ int (*tclpIsAtty) (int fd); /* 16 */
+} TclIntPlatStubs;
+extern const TclIntPlatStubs *tclIntPlatStubsPtr;
# include "tkWinInt.h"
#else
# define TCHAR char
@@ -95,7 +104,7 @@ extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
* it will conflict with a declaration elsewhere on some systems.
*/
-#if defined(__WIN32__) || defined(_WIN32)
+#if defined(_WIN32)
#define isatty WinIsTty
static int WinIsTty(int fd) {
HANDLE handle;
@@ -108,9 +117,9 @@ static int WinIsTty(int fd) {
*/
#if !defined(STATIC_BUILD)
- if (tclStubsPtr->reserved9 && TclpIsAtty) {
+ if (tclStubsPtr->reserved9 && tclIntPlatStubsPtr->tclpIsAtty) {
/* We are running on Cygwin */
- return TclpIsAtty(fd);
+ return tclIntPlatStubsPtr->tclpIsAtty(fd);
}
#endif
handle = GetStdHandle(STD_INPUT_HANDLE + fd);
@@ -184,15 +193,18 @@ Tk_MainEx(
InteractiveState is;
/*
- * Ensure that we are getting a compatible version of Tcl. This is really
- * only an issue when Tk is loaded dynamically.
+ * Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
- abort();
+ if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+ abort();
+ } else {
+ Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+ }
}
-#if defined(__WIN32__) && !defined(__WIN64__) && !defined(UNICODE) && !defined(STATIC_BUILD)
+#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)
if (tclStubsPtr->reserved9) {
/* We are running win32 Tk under Cygwin, so let's check
@@ -223,7 +235,7 @@ Tk_MainEx(
is.gotPartial = 0;
Tcl_Preserve(interp);
-#if defined(__WIN32__) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
Tk_InitConsoleChannels(interp);
#endif
@@ -315,7 +327,7 @@ Tk_MainEx(
*/
if (appInitProc(interp) != TCL_OK) {
- TkpDisplayWarning(Tcl_GetStringResult(interp),
+ TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)),
"application-specific initialization failed");
}
@@ -335,7 +347,7 @@ Tk_MainEx(
*/
Tcl_AddErrorInfo(interp, "");
- TkpDisplayWarning(Tcl_GetVar(interp, "errorInfo",
+ TkpDisplayWarning(Tcl_GetVar2(interp, "errorInfo", NULL,
TCL_GLOBAL_ONLY), "Error in startup script");
Tcl_DeleteInterp(interp);
Tcl_Exit(1);
@@ -448,7 +460,7 @@ StdinProc(
Tcl_CreateChannelHandler(isPtr->input, TCL_READABLE, StdinProc, isPtr);
}
Tcl_DStringFree(&isPtr->command);
- if (Tcl_GetStringResult(interp)[0] != '\0') {
+ if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {
if ((code != TCL_OK) || (isPtr->tty)) {
chan = Tcl_GetStdChannel((code != TCL_OK) ? TCL_STDERR : TCL_STDOUT);
if (chan) {
@@ -511,7 +523,7 @@ Prompt(
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (script that generates prompt)");
- if (Tcl_GetStringResult(interp)[0] != '\0') {
+ if (Tcl_GetString(Tcl_GetObjResult(interp))[0] != '\0') {
chan = Tcl_GetStdChannel(TCL_STDERR);
if (chan != NULL) {
Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
diff --git a/generic/tkMenu.c b/generic/tkMenu.c
index 12d6ebd..d24516f 100644
--- a/generic/tkMenu.c
+++ b/generic/tkMenu.c
@@ -81,6 +81,10 @@ typedef struct ThreadSpecificData {
int menusInitialized; /* Flag indicates whether thread-specific
* elements of the Windows Menu module have
* been initialized. */
+ Tk_OptionTable menuOptionTable;
+ /* The option table for menus. */
+ Tk_OptionTable entryOptionTables[6];
+ /* The tables for menu entries. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -338,7 +342,7 @@ static void DeleteMenuCloneEntries(TkMenu *menuPtr,
static void DestroyMenuHashTable(ClientData clientData,
Tcl_Interp *interp);
static void DestroyMenuInstance(TkMenu *menuPtr);
-static void DestroyMenuEntry(char *memPtr);
+static void DestroyMenuEntry(void *memPtr);
static int GetIndexFromCoords(Tcl_Interp *interp,
TkMenu *menuPtr, const char *string,
int *indexPtr);
@@ -349,8 +353,6 @@ static int MenuDoXPosition(Tcl_Interp *interp,
static int MenuAddOrInsert(Tcl_Interp *interp,
TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc,
Tcl_Obj *const objv[]);
-static int MenuCmd(ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *const objv[]);
static void MenuCmdDeletedProc(ClientData clientData);
static TkMenuEntry * MenuNewEntry(TkMenu *menuPtr, int index, int type);
static char * MenuVarProc(ClientData clientData,
@@ -381,63 +383,7 @@ static const Tk_ClassProcs menuClass = {
/*
*--------------------------------------------------------------
*
- * TkCreateMenuCmd --
- *
- * Called by Tk at initialization time to create the menu command.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *--------------------------------------------------------------
- */
-
-static void
-FreeOptionTables(
- ClientData clientData,
- Tcl_Interp *interp)
-{
- ckfree(clientData);
-}
-
-int
-TkCreateMenuCmd(
- Tcl_Interp *interp) /* Interpreter we are creating the command
- * in. */
-{
- TkMenuOptionTables *optionTablesPtr = ckalloc(sizeof(TkMenuOptionTables));
-
- optionTablesPtr->menuOptionTable =
- Tk_CreateOptionTable(interp, tkMenuConfigSpecs);
- optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]);
- optionTablesPtr->entryOptionTables[COMMAND_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[COMMAND_ENTRY]);
- optionTablesPtr->entryOptionTables[CASCADE_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[CASCADE_ENTRY]);
- optionTablesPtr->entryOptionTables[SEPARATOR_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[SEPARATOR_ENTRY]);
- optionTablesPtr->entryOptionTables[RADIO_BUTTON_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[RADIO_BUTTON_ENTRY]);
- optionTablesPtr->entryOptionTables[CHECK_BUTTON_ENTRY] =
- Tk_CreateOptionTable(interp, specsArray[CHECK_BUTTON_ENTRY]);
-
- Tcl_CreateObjCommand(interp, "menu", MenuCmd, optionTablesPtr, 0);
- Tcl_CallWhenDeleted(interp, FreeOptionTables, optionTablesPtr);
-
- if (Tcl_IsSafe(interp)) {
- Tcl_HideCommand(interp, "menu", "menu");
- }
-
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * MenuCmd --
+ * Tk_MenuObjCmd --
*
* This function is invoked to process the "menu" Tcl command. See the
* user documentation for details on what it does.
@@ -451,21 +397,22 @@ TkCreateMenuCmd(
*--------------------------------------------------------------
*/
-static int
-MenuCmd(
+int
+Tk_MenuObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument strings. */
{
- Tk_Window tkwin = Tk_MainWindow(interp);
+ Tk_Window tkwin = clientData;
Tk_Window newWin;
register TkMenu *menuPtr;
TkMenuReferences *menuRefPtr;
int i, index, toplevel;
const char *windowName;
static const char *const typeStringList[] = {"-type", NULL};
- TkMenuOptionTables *optionTablesPtr = clientData;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
@@ -476,10 +423,10 @@ MenuCmd(
toplevel = 1;
for (i = 2; i < (objc - 1); i++) {
- if (Tcl_GetIndexFromObj(NULL, objv[i], typeStringList, NULL, 0,
- &index) != TCL_ERROR) {
- if ((Tcl_GetIndexFromObj(NULL, objv[i + 1], menuTypeStrings, NULL,
- 0, &index) == TCL_OK) && (index == MENUBAR)) {
+ if (Tcl_GetIndexFromObjStruct(NULL, objv[i], typeStringList,
+ sizeof(char *), NULL, 0, &index) != TCL_ERROR) {
+ if ((Tcl_GetIndexFromObjStruct(NULL, objv[i + 1], menuTypeStrings,
+ sizeof(char *), NULL, 0, &index) == TCL_OK) && (index == MENUBAR)) {
toplevel = 0;
}
break;
@@ -511,7 +458,6 @@ MenuCmd(
menuPtr->cursorPtr = None;
menuPtr->masterMenuPtr = menuPtr;
menuPtr->menuType = UNKNOWN_TYPE;
- menuPtr->optionTablesPtr = optionTablesPtr;
TkMenuInitializeDrawingFields(menuPtr);
Tk_SetClass(menuPtr->tkwin, "Menu");
@@ -520,7 +466,7 @@ MenuCmd(
ExposureMask|StructureNotifyMask|ActivateMask,
TkMenuEventProc, menuPtr);
if (Tk_InitOptions(interp, (char *) menuPtr,
- menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin)
+ tsdPtr->menuOptionTable, menuPtr->tkwin)
!= TCL_OK) {
Tk_DestroyWindow(menuPtr->tkwin);
return TCL_ERROR;
@@ -675,13 +621,15 @@ MenuWidgetObjCmd(
register TkMenuEntry *mePtr;
int result = TCL_OK;
int option;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], menuOptions, "option", 0,
- &option) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], menuOptions,
+ sizeof(char *), "option", 0, &option) != TCL_OK) {
return TCL_ERROR;
}
Tcl_Preserve(menuPtr);
@@ -725,7 +673,7 @@ MenuWidgetObjCmd(
goto error;
}
resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr,
- menuPtr->optionTablesPtr->menuOptionTable, objv[2],
+ tsdPtr->menuOptionTable, objv[2],
menuPtr->tkwin);
if (resultPtr == NULL) {
goto error;
@@ -745,7 +693,7 @@ MenuWidgetObjCmd(
if (objc == 2) {
resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
- menuPtr->optionTablesPtr->menuOptionTable, NULL,
+ tsdPtr->menuOptionTable, NULL,
menuPtr->tkwin);
if (resultPtr == NULL) {
result = TCL_ERROR;
@@ -755,7 +703,7 @@ MenuWidgetObjCmd(
}
} else if (objc == 3) {
resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
- menuPtr->optionTablesPtr->menuOptionTable, objv[2],
+ tsdPtr->menuOptionTable, objv[2],
menuPtr->tkwin);
if (resultPtr == NULL) {
result = TCL_ERROR;
@@ -937,9 +885,14 @@ MenuWidgetObjCmd(
* Tearoff menus are posted differently on Mac and Windows than
* non-tearoffs. TkpPostMenu does not actually map the menu's window
* on those platforms, and popup menus have to be handled specially.
+ * Also, menubar menues are not intended to be posted (bug 1567681,
+ * 2160206).
*/
- if (menuPtr->menuType != TEAROFF_MENU) {
+ if (menuPtr->menuType == MENUBAR) {
+ Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL);
+ return TCL_ERROR;
+ } else if (menuPtr->menuType != TEAROFF_MENU) {
result = TkpPostMenu(interp, menuPtr, x, y);
} else {
result = TkPostTearoffMenu(interp, menuPtr, x, y);
@@ -1061,7 +1014,7 @@ TkInvokeMenu(
Tcl_DStringInit(&ds);
Tcl_DStringAppend(&ds, "tk::TearOffMenu ", -1);
Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1);
- result = Tcl_Eval(interp, Tcl_DStringValue(&ds));
+ result = Tcl_EvalEx(interp, Tcl_DStringValue(&ds), -1, 0);
Tcl_DStringFree(&ds);
} else if ((mePtr->type == CHECK_BUTTON_ENTRY)
&& (mePtr->namePtr != NULL)) {
@@ -1144,6 +1097,8 @@ DestroyMenuInstance(
Tcl_Obj *newObjv[2];
TkMenu *parentMasterMenuPtr;
TkMenuEntry *parentMasterEntryPtr;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* If the menu has any cascade menu entries pointing to it, the cascade
@@ -1225,7 +1180,7 @@ DestroyMenuInstance(
* for menu entries (i+1)...numEntries.
*/
- DestroyMenuEntry((char *) menuPtr->entries[i]);
+ DestroyMenuEntry(menuPtr->entries[i]);
menuPtr->numEntries = i;
}
if (menuPtr->entries != NULL) {
@@ -1233,7 +1188,7 @@ DestroyMenuInstance(
}
TkMenuFreeDrawOptions(menuPtr);
Tk_FreeConfigOptions((char *) menuPtr,
- menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin);
+ tsdPtr->menuOptionTable, menuPtr->tkwin);
if (menuPtr->tkwin != NULL) {
Tk_Window tkwin = menuPtr->tkwin;
@@ -1423,9 +1378,9 @@ UnhookCascadeEntry(
static void
DestroyMenuEntry(
- char *memPtr) /* Pointer to entry to be freed. */
+ void *memPtr) /* Pointer to entry to be freed. */
{
- register TkMenuEntry *mePtr = (TkMenuEntry *) memPtr;
+ register TkMenuEntry *mePtr = memPtr;
TkMenu *menuPtr = mePtr->menuPtr;
if (menuPtr->postedCascade == mePtr) {
@@ -1469,13 +1424,14 @@ DestroyMenuEntry(
}
}
UnhookCascadeEntry(mePtr);
+ menuRefPtr = mePtr->childMenuRefPtr;
if (menuRefPtr != NULL) {
if (menuRefPtr->menuPtr == destroyThis) {
menuRefPtr->menuPtr = NULL;
}
- if (destroyThis != NULL) {
- TkDestroyMenu(destroyThis);
- }
+ }
+ if (destroyThis != NULL) {
+ TkDestroyMenu(destroyThis);
}
} else {
UnhookCascadeEntry(mePtr);
@@ -1492,7 +1448,7 @@ DestroyMenuEntry(
&& (mePtr->namePtr != NULL)) {
const char *varName = Tcl_GetString(mePtr->namePtr);
- Tcl_UntraceVar(menuPtr->interp, varName,
+ Tcl_UntraceVar2(menuPtr->interp, varName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, mePtr);
}
@@ -1566,12 +1522,14 @@ ConfigureMenu(
int i;
TkMenu *menuListPtr, *cleanupPtr;
int result;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
menuListPtr->errorStructPtr = ckalloc(sizeof(Tk_SavedOptions));
result = Tk_SetOptions(interp, (char *) menuListPtr,
- menuListPtr->optionTablesPtr->menuOptionTable, objc, objv,
+ tsdPtr->menuOptionTable, objc, objv,
menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
if (result != TCL_OK) {
for (cleanupPtr = menuPtr->masterMenuPtr;
@@ -1597,8 +1555,8 @@ ConfigureMenu(
*/
if (menuListPtr->menuType == UNKNOWN_TYPE) {
- Tcl_GetIndexFromObj(NULL, menuListPtr->menuTypePtr,
- menuTypeStrings, NULL, 0, &menuListPtr->menuType);
+ Tcl_GetIndexFromObjStruct(NULL, menuListPtr->menuTypePtr,
+ menuTypeStrings, sizeof(char *), NULL, 0, &menuListPtr->menuType);
/*
* Configure the new window to be either a pop-up menu or a
@@ -1662,7 +1620,7 @@ ConfigureMenu(
&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {
int i;
- Tcl_EventuallyFree(menuListPtr->entries[0], DestroyMenuEntry);
+ Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry);
for (i = 0; i < menuListPtr->numEntries - 1; i++) {
menuListPtr->entries[i] = menuListPtr->entries[i + 1];
@@ -1742,12 +1700,12 @@ PostProcessEntry(
if (mePtr->labelPtr == NULL) {
mePtr->labelLength = 0;
} else {
- Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
+ (void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
}
if (mePtr->accelPtr == NULL) {
mePtr->accelLength = 0;
} else {
- Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
+ (void)Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
}
/*
@@ -1906,8 +1864,8 @@ PostProcessEntry(
}
if (mePtr->namePtr != NULL) {
name = Tcl_GetString(mePtr->namePtr);
- Tcl_TraceVar(menuPtr->interp, name,
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(menuPtr->interp, name,
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, mePtr);
}
}
@@ -1959,7 +1917,7 @@ ConfigureMenuEntry(
|| (mePtr->type == RADIO_BUTTON_ENTRY))) {
const char *name = Tcl_GetString(mePtr->namePtr);
- Tcl_UntraceVar(menuPtr->interp, name,
+ Tcl_UntraceVar2(menuPtr->interp, name, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, mePtr);
}
@@ -2287,6 +2245,8 @@ MenuNewEntry(
TkMenuEntry *mePtr;
TkMenuEntry **newEntries;
int i;
+ ThreadSpecificData *tsdPtr =
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
/*
* Create a new array of entries with an empty slot for the new entry.
@@ -2308,7 +2268,7 @@ MenuNewEntry(
mePtr = ckalloc(sizeof(TkMenuEntry));
menuPtr->entries[index] = mePtr;
mePtr->type = type;
- mePtr->optionTable = menuPtr->optionTablesPtr->entryOptionTables[type];
+ mePtr->optionTable = tsdPtr->entryOptionTables[type];
mePtr->menuPtr = menuPtr;
mePtr->labelPtr = NULL;
mePtr->labelLength = 0;
@@ -2406,8 +2366,8 @@ MenuAddOrInsert(
* Figure out the type of the new entry.
*/
- if (Tcl_GetIndexFromObj(interp, objv[0], menuEntryTypeStrings,
- "menu entry type", 0, &type) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
+ sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
return TCL_ERROR;
}
@@ -2430,7 +2390,7 @@ MenuAddOrInsert(
errorMenuPtr != NULL;
errorMenuPtr = errorMenuPtr->nextInstancePtr) {
Tcl_EventuallyFree(errorMenuPtr->entries[index],
- DestroyMenuEntry);
+ (Tcl_FreeProc *) DestroyMenuEntry);
for (i = index; i < errorMenuPtr->numEntries - 1; i++) {
errorMenuPtr->entries[i] = errorMenuPtr->entries[i + 1];
errorMenuPtr->entries[i]->index = i;
@@ -2544,7 +2504,7 @@ MenuVarProc(
if (flags & TCL_TRACE_UNSETS) {
mePtr->entryFlags &= ~ENTRY_SELECTED;
if (flags & TCL_TRACE_DESTROYED) {
- Tcl_TraceVar(interp, name,
+ Tcl_TraceVar2(interp, name, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuVarProc, clientData);
}
@@ -2558,7 +2518,7 @@ MenuVarProc(
* entry.
*/
- value = Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, name, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
value = "";
}
@@ -2711,8 +2671,8 @@ CloneMenu(
if (newMenuTypePtr == NULL) {
menuType = MASTER_MENU;
} else {
- if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr,
- menuTypeStrings, "menu type", 0, &menuType) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
+ menuTypeStrings, sizeof(char *), "menu type", 0, &menuType) != TCL_OK) {
return TCL_ERROR;
}
}
@@ -2987,10 +2947,10 @@ GetIndexFromCoords(
*indexPtr = -1;
- /* set the width of the final column to the remainder of the window
+ /* set the width of the final column to the remainder of the window
* being aware of windows that may not be mapped yet.
*/
- max = Tk_IsMapped(menuPtr->tkwin)
+ max = Tk_IsMapped(menuPtr->tkwin)
? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin);
max -= borderwidth;
@@ -3090,7 +3050,6 @@ TkNewMenuName(
char *destString;
int i;
int doDot;
- Tcl_CmdInfo cmdInfo;
Tcl_HashTable *nameTablePtr = NULL;
TkWindow *winPtr = (TkWindow *) menuPtr->tkwin;
const char *parentName = Tcl_GetString(parentPtr);
@@ -3130,7 +3089,7 @@ TkNewMenuName(
Tcl_DecrRefCount(intPtr);
}
destString = Tcl_GetString(resultPtr);
- if ((Tcl_GetCommandInfo(interp, destString, &cmdInfo) == 0)
+ if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL)
&& ((nameTablePtr == NULL)
|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
break;
@@ -3540,7 +3499,7 @@ DeleteMenuCloneEntries(
for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
menuListPtr = menuListPtr->nextInstancePtr) {
for (i = last; i >= first; i--) {
- Tcl_EventuallyFree(menuListPtr->entries[i], DestroyMenuEntry);
+ Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
}
for (i = last + 1; i < menuListPtr->numEntries; i++) {
j = i - numDeleted;
@@ -3625,6 +3584,20 @@ TkMenuInit(void)
}
if (!tsdPtr->menusInitialized) {
TkpMenuThreadInit();
+ tsdPtr->menuOptionTable =
+ Tk_CreateOptionTable(NULL, tkMenuConfigSpecs);
+ tsdPtr->entryOptionTables[TEAROFF_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[TEAROFF_ENTRY]);
+ tsdPtr->entryOptionTables[COMMAND_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[COMMAND_ENTRY]);
+ tsdPtr->entryOptionTables[CASCADE_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[CASCADE_ENTRY]);
+ tsdPtr->entryOptionTables[SEPARATOR_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[SEPARATOR_ENTRY]);
+ tsdPtr->entryOptionTables[RADIO_BUTTON_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[RADIO_BUTTON_ENTRY]);
+ tsdPtr->entryOptionTables[CHECK_BUTTON_ENTRY] =
+ Tk_CreateOptionTable(NULL, specsArray[CHECK_BUTTON_ENTRY]);
tsdPtr->menusInitialized = 1;
}
}
diff --git a/generic/tkMenu.h b/generic/tkMenu.h
index def7d19..bac51aa 100644
--- a/generic/tkMenu.h
+++ b/generic/tkMenu.h
@@ -359,10 +359,7 @@ typedef struct TkMenu {
/* A pointer to the original menu for this
* clone chain. Points back to this structure
* if this menu is a master menu. */
- struct TkMenuOptionTables *optionTablesPtr;
- /* A pointer to the collection of option
- * tables that work with menus and menu
- * entries. */
+ void *reserved1; /* not used any more. */
Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the
* toplevel that owns the menu. Only
* applicable for menubar clones. */
@@ -431,17 +428,6 @@ typedef struct TkMenuReferences {
} TkMenuReferences;
/*
- * This structure contains all of the option tables that are needed by menus.
- */
-
-typedef struct TkMenuOptionTables {
- Tk_OptionTable menuOptionTable;
- /* The option table for menus. */
- Tk_OptionTable entryOptionTables[6];
- /* The tables for menu entries. */
-} TkMenuOptionTables;
-
-/*
* Flag bits for menus:
*
* REDRAW_PENDING: Non-zero means a DoWhenIdle handler has
diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c
index 545401c..1a4d5ae 100644
--- a/generic/tkMenubutton.c
+++ b/generic/tkMenubutton.c
@@ -355,8 +355,8 @@ MenuButtonWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, "option", 0,
- &index);
+ result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames,
+ sizeof(char *), "option", 0, &index);
if (result != TCL_OK) {
return result;
}
@@ -436,7 +436,7 @@ DestroyMenuButton(
Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd);
if (mbPtr->textVarName != NULL) {
- Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName,
+ Tcl_UntraceVar2(mbPtr->interp, mbPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuButtonTextVarProc, mbPtr);
}
@@ -506,7 +506,7 @@ ConfigureMenuButton(
*/
if (mbPtr->textVarName != NULL) {
- Tcl_UntraceVar(interp, mbPtr->textVarName,
+ Tcl_UntraceVar2(interp, mbPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuButtonTextVarProc, mbPtr);
}
@@ -625,9 +625,9 @@ ConfigureMenuButton(
*/
const char *value;
- value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
- Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text,
+ Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
TCL_GLOBAL_ONLY);
} else {
if (mbPtr->text != NULL) {
@@ -636,7 +636,7 @@ ConfigureMenuButton(
mbPtr->text = ckalloc(strlen(value) + 1);
strcpy(mbPtr->text, value);
}
- Tcl_TraceVar(interp, mbPtr->textVarName,
+ Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuButtonTextVarProc, mbPtr);
}
@@ -888,16 +888,16 @@ MenuButtonTextVarProc(
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text,
+ Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, mbPtr->textVarName,
+ Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MenuButtonTextVarProc, clientData);
}
return NULL;
}
- value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
value = "";
}
diff --git a/generic/tkMessage.c b/generic/tkMessage.c
index 4779e00..2b71998 100644
--- a/generic/tkMessage.c
+++ b/generic/tkMessage.c
@@ -318,8 +318,8 @@ MessageWidgetObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -405,7 +405,7 @@ DestroyMessage(
Tk_FreeTextLayout(msgPtr->textLayout);
}
if (msgPtr->textVarName != NULL) {
- Tcl_UntraceVar(msgPtr->interp, msgPtr->textVarName,
+ Tcl_UntraceVar2(msgPtr->interp, msgPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, msgPtr);
}
@@ -450,7 +450,7 @@ ConfigureMessage(
*/
if (msgPtr->textVarName != NULL) {
- Tcl_UntraceVar(interp, msgPtr->textVarName,
+ Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, msgPtr);
}
@@ -470,9 +470,9 @@ ConfigureMessage(
if (msgPtr->textVarName != NULL) {
const char *value;
- value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
- Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string,
+ Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
TCL_GLOBAL_ONLY);
} else {
if (msgPtr->string != NULL) {
@@ -480,7 +480,7 @@ ConfigureMessage(
}
msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value);
}
- Tcl_TraceVar(interp, msgPtr->textVarName,
+ Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, msgPtr);
}
@@ -845,16 +845,16 @@ MessageTextVarProc(
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string,
+ Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
TCL_GLOBAL_ONLY);
- Tcl_TraceVar(interp, msgPtr->textVarName,
+ Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
MessageTextVarProc, clientData);
}
return NULL;
}
- value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY);
+ value = Tcl_GetVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
if (value == NULL) {
value = "";
}
diff --git a/generic/tkObj.c b/generic/tkObj.c
index ed947d3..7c09656 100644
--- a/generic/tkObj.c
+++ b/generic/tkObj.c
@@ -33,7 +33,7 @@ typedef struct PixelRep {
(PTR2INT((objPtr)->internalRep.twoPtrValue.ptr1))
#define SET_COMPLEXPIXEL(objPtr, repPtr) \
- (objPtr)->internalRep.twoPtrValue.ptr1 = 0; \
+ (objPtr)->internalRep.twoPtrValue.ptr1 = NULL; \
(objPtr)->internalRep.twoPtrValue.ptr2 = repPtr
#define GET_COMPLEXPIXEL(objPtr) \
@@ -447,7 +447,7 @@ SetPixelFromAny(
double d;
int i, units;
- string = Tcl_GetStringFromObj(objPtr, NULL);
+ string = Tcl_GetString(objPtr);
d = strtod(string, &rest);
if (rest == string) {
@@ -553,7 +553,7 @@ Tk_GetMMFromObj(
}
}
- mmPtr = objPtr->internalRep.otherValuePtr;
+ mmPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (mmPtr->tkwin != tkwin) {
d = mmPtr->value;
if (mmPtr->units == -1) {
@@ -592,8 +592,8 @@ static void
FreeMMInternalRep(
Tcl_Obj *objPtr) /* MM object with internal rep to free. */
{
- ckfree(objPtr->internalRep.otherValuePtr);
- objPtr->internalRep.otherValuePtr = NULL;
+ ckfree(objPtr->internalRep.twoPtrValue.ptr1);
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
objPtr->typePtr = NULL;
}
@@ -623,13 +623,13 @@ DupMMInternalRep(
MMRep *oldPtr, *newPtr;
copyPtr->typePtr = srcPtr->typePtr;
- oldPtr = srcPtr->internalRep.otherValuePtr;
+ oldPtr = srcPtr->internalRep.twoPtrValue.ptr1;
newPtr = ckalloc(sizeof(MMRep));
newPtr->value = oldPtr->value;
newPtr->units = oldPtr->units;
newPtr->tkwin = oldPtr->tkwin;
newPtr->returnValue = oldPtr->returnValue;
- copyPtr->internalRep.otherValuePtr = newPtr;
+ copyPtr->internalRep.twoPtrValue.ptr1 = newPtr;
}
/*
@@ -659,7 +659,7 @@ UpdateStringOfMM(
char buffer[TCL_DOUBLE_SPACE];
register int len;
- mmPtr = objPtr->internalRep.otherValuePtr;
+ mmPtr = objPtr->internalRep.twoPtrValue.ptr1;
/* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
Tcl_Panic("UpdateStringOfMM: false precondition");
@@ -719,13 +719,13 @@ SetMMFromAny(
* ints again from mm obj types.
*/
- (void) Tcl_GetStringFromObj(objPtr, NULL);
+ (void) Tcl_GetString(objPtr);
} else {
/*
* It wasn't a known int or double, so parse it.
*/
- string = Tcl_GetStringFromObj(objPtr, NULL);
+ string = Tcl_GetString(objPtr);
d = strtod(string, &rest);
if (rest == string) {
@@ -782,7 +782,7 @@ SetMMFromAny(
mmPtr->tkwin = NULL;
mmPtr->returnValue = d;
- objPtr->internalRep.otherValuePtr = mmPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = mmPtr;
return TCL_OK;
}
@@ -817,14 +817,15 @@ TkGetWindowFromObj(
{
TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
register WindowRep *winPtr;
- int result;
- result = Tcl_ConvertToType(interp, objPtr, &windowObjType);
- if (result != TCL_OK) {
- return result;
+ if (objPtr->typePtr != &windowObjType) {
+ int result = SetWindowFromAny(interp, objPtr);
+ if (result != TCL_OK) {
+ return result;
+ }
}
- winPtr = objPtr->internalRep.otherValuePtr;
+ winPtr = objPtr->internalRep.twoPtrValue.ptr1;
if (winPtr->tkwin == NULL
|| winPtr->mainPtr == NULL
|| winPtr->mainPtr != mainPtr
@@ -834,7 +835,7 @@ TkGetWindowFromObj(
*/
winPtr->tkwin = Tk_NameToWindow(interp,
- Tcl_GetStringFromObj(objPtr, NULL), tkwin);
+ Tcl_GetString(objPtr), tkwin);
if (winPtr->tkwin == NULL) {
/* ASSERT: Tk_NameToWindow has left error message in interp */
return TCL_ERROR;
@@ -880,7 +881,7 @@ SetWindowFromAny(
* Free the old internalRep before setting the new one.
*/
- Tcl_GetStringFromObj(objPtr, NULL);
+ (void)Tcl_GetString(objPtr);
typePtr = objPtr->typePtr;
if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
typePtr->freeIntRepProc(objPtr);
@@ -891,7 +892,7 @@ SetWindowFromAny(
winPtr->mainPtr = NULL;
winPtr->epoch = 0;
- objPtr->internalRep.otherValuePtr = winPtr;
+ objPtr->internalRep.twoPtrValue.ptr1 = winPtr;
objPtr->typePtr = &windowObjType;
return TCL_OK;
@@ -922,12 +923,12 @@ DupWindowInternalRep(
{
register WindowRep *oldPtr, *newPtr;
- oldPtr = srcPtr->internalRep.otherValuePtr;
+ oldPtr = srcPtr->internalRep.twoPtrValue.ptr1;
newPtr = ckalloc(sizeof(WindowRep));
newPtr->tkwin = oldPtr->tkwin;
newPtr->mainPtr = oldPtr->mainPtr;
newPtr->epoch = oldPtr->epoch;
- copyPtr->internalRep.otherValuePtr = newPtr;
+ copyPtr->internalRep.twoPtrValue.ptr1 = newPtr;
copyPtr->typePtr = srcPtr->typePtr;
}
@@ -953,8 +954,8 @@ static void
FreeWindowInternalRep(
Tcl_Obj *objPtr) /* Window object with internal rep to free. */
{
- ckfree(objPtr->internalRep.otherValuePtr);
- objPtr->internalRep.otherValuePtr = NULL;
+ ckfree(objPtr->internalRep.twoPtrValue.ptr1);
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
objPtr->typePtr = NULL;
}
@@ -985,7 +986,7 @@ TkNewWindowObj(
SetWindowFromAny(NULL, objPtr);
- winPtr = objPtr->internalRep.otherValuePtr;
+ winPtr = objPtr->internalRep.twoPtrValue.ptr1;
winPtr->tkwin = tkwin;
winPtr->mainPtr = mainPtr;
winPtr->epoch = mainPtr->deletionEpoch;
diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c
index 5496076..920d93e 100644
--- a/generic/tkOldConfig.c
+++ b/generic/tkOldConfig.c
@@ -113,6 +113,10 @@ Tk_ConfigureWidget(
staticSpecs = GetCachedSpecs(interp, specs);
+ for (specPtr = staticSpecs; specPtr->type != TK_CONFIG_END; specPtr++) {
+ specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
+ }
+
/*
* Pass one: scan through all of the arguments, processing those that
* match entries in the specs.
@@ -122,7 +126,7 @@ Tk_ConfigureWidget(
const char *arg;
if (flags & TK_CONFIG_OBJS) {
- arg = Tcl_GetStringFromObj((Tcl_Obj *) *argv, NULL);
+ arg = Tcl_GetString((Tcl_Obj *) *argv);
} else {
arg = *argv;
}
@@ -167,7 +171,6 @@ Tk_ConfigureWidget(
if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)
|| (specPtr->argvName == NULL)
|| (specPtr->type == TK_CONFIG_SYNONYM)) {
- specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
continue;
}
if (((specPtr->specFlags & needFlags) != needFlags)
@@ -718,7 +721,7 @@ FormatConfigInfo(
result = Tcl_Merge(5, argv);
if (freeProc != NULL) {
if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
- ckfree(argv[4]);
+ ckfree((char *) argv[4]);
} else {
freeProc((char *) argv[4]);
}
@@ -939,7 +942,7 @@ Tk_ConfigureValue(
Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
if (freeProc != NULL) {
if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
- ckfree(result);
+ ckfree((char *) result);
} else {
freeProc((char *) result);
}
@@ -1126,7 +1129,6 @@ GetCachedSpecs(
specPtr->defValue = Tk_GetUid(specPtr->defValue);
}
}
- specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED;
}
} else {
cachedSpecs = Tcl_GetHashValue(entryPtr);
diff --git a/generic/tkOldTest.c b/generic/tkOldTest.c
index b0edf76..df1bb6c 100644
--- a/generic/tkOldTest.c
+++ b/generic/tkOldTest.c
@@ -81,8 +81,9 @@ static Tk_ImageType imageType = {
* Forward declarations for functions defined later in this file:
*/
-static int ImageCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+static int ImageObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
/*
@@ -175,7 +176,7 @@ ImageCreate(
strcpy(timPtr->imageName, name);
timPtr->varName = ckalloc((unsigned) (strlen(varName) + 1));
strcpy(timPtr->varName, varName);
- Tcl_CreateCommand(interp, name, ImageCmd, timPtr, NULL);
+ Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
*clientDataPtr = timPtr;
Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
return TCL_OK;
@@ -184,7 +185,7 @@ ImageCreate(
/*
*----------------------------------------------------------------------
*
- * ImageCmd --
+ * ImageObjCmd --
*
* This function implements the commands corresponding to individual
* images.
@@ -200,38 +201,37 @@ ImageCreate(
/* ARGSUSED */
static int
-ImageCmd(
+ImageObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
TImageMaster *timPtr = clientData;
int x, y, width, height;
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], "option ?arg ...?", NULL);
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (strcmp(argv[1], "changed") == 0) {
- if (argc != 8) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " changed x y width height imageWidth imageHeight", NULL);
+ if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
+ if (objc != 8) {
+ Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
+ " imageWidth imageHeight");
return TCL_ERROR;
}
- if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
- || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)
- || (Tcl_GetInt(interp, argv[4], &width) != TCL_OK)
- || (Tcl_GetInt(interp, argv[5], &height) != TCL_OK)
- || (Tcl_GetInt(interp, argv[6], &timPtr->width) != TCL_OK)
- || (Tcl_GetInt(interp, argv[7], &timPtr->height) != TCL_OK)) {
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
return TCL_ERROR;
}
Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width,
timPtr->height);
} else {
- Tcl_AppendResult(interp, "bad option \"", argv[1],
+ Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be changed", NULL);
return TCL_ERROR;
}
@@ -268,7 +268,7 @@ ImageGet(
XGCValues gcValues;
sprintf(buffer, "%s get", timPtr->imageName);
- Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
instPtr = ckalloc(sizeof(TImageInstance));
@@ -315,8 +315,8 @@ ImageDisplay(
sprintf(buffer, "%s display %d %d %d %d %d %d",
instPtr->masterPtr->imageName, imageX, imageY, width, height,
drawableX, drawableY);
- Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ 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)) {
width = instPtr->masterPtr->width - imageX;
}
@@ -358,8 +358,8 @@ ImageFree(
char buffer[200];
sprintf(buffer, "%s free", instPtr->masterPtr->imageName);
- Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
+ buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
Tk_FreeColor(instPtr->fg);
Tk_FreeGC(display, instPtr->gc);
ckfree(instPtr);
@@ -392,7 +392,7 @@ ImageDelete(
char buffer[100];
sprintf(buffer, "%s delete", timPtr->imageName);
- Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
diff --git a/generic/tkOption.c b/generic/tkOption.c
index ec9e465..24e7fb3 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -560,7 +560,7 @@ Tk_GetOption(
count -= levelPtr[-1].bases[currentStack];
}
- if (currentStack && CLASS) {
+ if (currentStack & CLASS) {
nodeId = winClassId;
} else {
nodeId = winNameId;
@@ -631,8 +631,8 @@ Tk_OptionObjCmd(
return TCL_ERROR;
}
- result = Tcl_GetIndexFromObj(interp, objv[1], optionCmds, "option", 0,
- &index);
+ result = Tcl_GetIndexFromObjStruct(interp, objv[1], optionCmds,
+ sizeof(char *), "option", 0, &index);
if (result != TCL_OK) {
return result;
}
@@ -1016,14 +1016,25 @@ AddFromString(
Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "NEWLINE", NULL);
return TCL_ERROR;
}
- if ((src[0] == '\\') && (src[1] == '\n')) {
- src += 2;
- lineNum++;
- } else {
- *dst = *src;
- dst++;
- src++;
+ if (*src == '\\'){
+ if (src[1] == '\n') {
+ src += 2;
+ lineNum++;
+ continue;
+ } else if (src[1] == 'n') {
+ src += 2;
+ *dst++ = '\n';
+ continue;
+ } else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
+ ++src;
+ } else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
+ src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
+ *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
+ src += 4;
+ continue;
+ }
}
+ *dst++ = *src++;
}
*dst = 0;
@@ -1069,7 +1080,7 @@ ReadOptionFile(
* TK_MAX_PRIO. */
{
const char *realName;
- char *buffer;
+ Tcl_Obj *buffer;
int result, bufferSize;
Tcl_Channel chan;
Tcl_DString newName;
@@ -1097,24 +1108,10 @@ ReadOptionFile(
return TCL_ERROR;
}
- /*
- * Compute size of file by seeking to the end of the file. This will
- * overallocate if we are performing CRLF translation.
- */
-
- bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END);
- Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET);
-
- if (bufferSize < 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "error seeking to end of file \"%s\": %s",
- fileName, Tcl_PosixError(interp)));
- Tcl_Close(NULL, chan);
- return TCL_ERROR;
- }
-
- buffer = ckalloc(bufferSize + 1);
- bufferSize = Tcl_Read(chan, buffer, bufferSize);
+ buffer = Tcl_NewObj();
+ Tcl_IncrRefCount(buffer);
+ Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
+ bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
if (bufferSize < 0) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"error reading file \"%s\": %s",
@@ -1123,9 +1120,8 @@ ReadOptionFile(
return TCL_ERROR;
}
Tcl_Close(NULL, chan);
- buffer[bufferSize] = 0;
- result = AddFromString(interp, tkwin, buffer, priority);
- ckfree(buffer);
+ result = AddFromString(interp, tkwin, Tcl_GetString(buffer), priority);
+ Tcl_DecrRefCount(buffer);
return result;
}
diff --git a/generic/tkPack.c b/generic/tkPack.c
index 134b61f..88a4b2d 100644
--- a/generic/tkPack.c
+++ b/generic/tkPack.c
@@ -88,7 +88,7 @@ typedef struct Packer {
* Tk will set its requested size to fit the
* needs of its slaves.
* ALLOCED_MASTER 1 means that Pack has allocated itself as
- * geometry master for this window.
+ * geometry master for this window.
*/
#define REQUESTED_REPACK 1
@@ -120,7 +120,7 @@ static const Tk_GeomMgr packerType = {
static void ArrangePacking(ClientData clientData);
static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin,
int objc, Tcl_Obj *const objv[]);
-static void DestroyPacker(char *memPtr);
+static void DestroyPacker(void *memPtr);
static Packer * GetPacker(Tk_Window tkwin);
static int PackAfter(Tcl_Interp *interp, Packer *prevPtr,
Packer *masterPtr, int objc,Tcl_Obj *const objv[]);
@@ -217,8 +217,8 @@ Tk_PackObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
/*
* Call it again without the deprecated ones to get a proper error
* message. This works well since there can't be any ambiguity between
@@ -226,8 +226,8 @@ Tk_PackObjCmd(
*/
Tcl_ResetResult(interp);
- Tcl_GetIndexFromObj(interp, objv[1], &optionStrings[4], "option", 0,
- &index);
+ Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4],
+ sizeof(char *), "option", 0, &index);
return TCL_ERROR;
}
@@ -409,7 +409,7 @@ Tk_PackObjCmd(
if (masterPtr->slavePtr != NULL) {
if (TkSetGeometryMaster(interp, master, "pack") != TCL_OK) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
masterPtr->flags |= ALLOCED_MASTER;
}
@@ -1101,7 +1101,6 @@ PackAfter(
{
register Packer *packPtr;
Tk_Window tkwin, ancestor, parent;
- int length;
Tcl_Obj **options;
int index, optionCount, c;
@@ -1170,24 +1169,25 @@ PackAfter(
packPtr->flags |= OLD_STYLE;
for (index = 0 ; index < optionCount; index++) {
Tcl_Obj *curOptPtr = options[index];
- const char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length);
+ const char *curOpt = Tcl_GetString(curOptPtr);
+ size_t length = curOptPtr->length;
c = curOpt[0];
if ((c == 't')
- && (strncmp(curOpt, "top", (size_t) length)) == 0) {
+ && (strncmp(curOpt, "top", length)) == 0) {
packPtr->side = TOP;
} else if ((c == 'b')
- && (strncmp(curOpt, "bottom", (size_t) length)) == 0) {
+ && (strncmp(curOpt, "bottom", length)) == 0) {
packPtr->side = BOTTOM;
} else if ((c == 'l')
- && (strncmp(curOpt, "left", (size_t) length)) == 0) {
+ && (strncmp(curOpt, "left", length)) == 0) {
packPtr->side = LEFT;
} else if ((c == 'r')
- && (strncmp(curOpt, "right", (size_t) length)) == 0) {
+ && (strncmp(curOpt, "right", length)) == 0) {
packPtr->side = RIGHT;
} else if ((c == 'e')
- && (strncmp(curOpt, "expand", (size_t) length)) == 0) {
+ && (strncmp(curOpt, "expand", length)) == 0) {
packPtr->flags |= EXPAND;
} else if ((c == 'f')
&& (strcmp(curOpt, "fill")) == 0) {
@@ -1287,7 +1287,7 @@ PackAfter(
!= TCL_OK) {
Tk_ManageGeometry(tkwin, NULL, NULL);
Unlink(packPtr);
- return TCL_ERROR;
+ return TCL_ERROR;
}
masterPtr->flags |= ALLOCED_MASTER;
}
@@ -1389,10 +1389,10 @@ Unlink(
static void
DestroyPacker(
- char *memPtr) /* Info about packed window that is now
+ void *memPtr) /* Info about packed window that is now
* dead. */
{
- register Packer *packPtr = (Packer *) memPtr;
+ register Packer *packPtr = memPtr;
ckfree(packPtr);
}
@@ -1463,7 +1463,7 @@ PackStructureProc(
Tcl_CancelIdleCall(ArrangePacking, packPtr);
}
packPtr->tkwin = NULL;
- Tcl_EventuallyFree(packPtr, DestroyPacker);
+ Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
} else if (eventPtr->type == MapNotify) {
/*
* When a master gets mapped, must redo the geometry computation so
@@ -1593,8 +1593,8 @@ ConfigureSlaves(
Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option",
- 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -1725,8 +1725,8 @@ ConfigureSlaves(
}
break;
case CONF_SIDE:
- if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames, "side",
- TCL_EXACT, &side) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i+1], sideNames,
+ sizeof(char *), "side", TCL_EXACT, &side) != TCL_OK) {
return TCL_ERROR;
}
slavePtr->side = (Side) side;
@@ -1829,7 +1829,7 @@ ConfigureSlaves(
!= TCL_OK) {
Tk_ManageGeometry(slave, NULL, NULL);
Unlink(slavePtr);
- return TCL_ERROR;
+ return TCL_ERROR;
}
masterPtr->flags |= ALLOCED_MASTER;
}
diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c
index 4a4af53..2451647 100644
--- a/generic/tkPanedWindow.c
+++ b/generic/tkPanedWindow.c
@@ -147,6 +147,10 @@ typedef struct PanedWindow {
GC gc; /* Graphics context for copying from
* off-screen pixmap onto screen. */
int proxyx, proxyy; /* Proxy x,y coordinates. */
+ Tk_3DBorder proxyBackground;/* Background color used to draw proxy. If NULL, use background. */
+ Tcl_Obj *proxyBorderWidthPtr; /* Tcl_Obj rep for proxyBorderWidth */
+ int proxyBorderWidth; /* Borderwidth used to draw proxy. */
+ int proxyRelief; /* Relief used to draw proxy, if TK_RELIEF_NULL then use relief. */
Slave **slaves; /* Pointer to array of Slaves. */
int numSlaves; /* Number of slaves. */
int sizeofSlaves; /* Number of elements in the slaves array. */
@@ -203,6 +207,8 @@ static void PanedWindowReqProc(ClientData clientData,
static void ArrangePanes(ClientData clientData);
static void Unlink(Slave *slavePtr);
static Slave * GetPane(PanedWindow *pwPtr, Tk_Window tkwin);
+static void GetFirstLastVisiblePane(PanedWindow *pwPtr,
+ int *firstPtr, int *lastPtr);
static void SlaveStructureProc(ClientData clientData,
XEvent *eventPtr);
static int PanedWindowSashCommand(PanedWindow *pwPtr,
@@ -296,6 +302,15 @@ static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
0, orientStrings, GEOMETRY},
+ {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
+ 0, -1, Tk_Offset(PanedWindow, proxyBackground), TK_OPTION_NULL_OK,
+ (ClientData) DEF_PANEDWINDOW_BG_MONO},
+ {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
+ DEF_PANEDWINDOW_PROXYBORDER, Tk_Offset(PanedWindow, proxyBorderWidthPtr),
+ Tk_Offset(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
+ {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
+ 0, -1, Tk_Offset(PanedWindow, proxyRelief),
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(PanedWindow, relief), 0, 0, 0},
{TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
@@ -384,7 +399,7 @@ Tk_PanedWindowObjCmd(
}
tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
- Tcl_GetStringFromObj(objv[1], NULL), NULL);
+ Tcl_GetString(objv[1]), NULL);
if (tkwin == NULL) {
return TCL_ERROR;
}
@@ -682,6 +697,15 @@ PanedWindowWidgetObjCmd(
if (objc <= 4) {
tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
pwPtr->tkwin);
+ if (tkwin == NULL) {
+ /*
+ * Just a plain old bad window; Tk_NameToWindow filled in an
+ * error message for us.
+ */
+
+ result = TCL_ERROR;
+ break;
+ }
for (i = 0; i < pwPtr->numSlaves; i++) {
if (pwPtr->slaves[i]->tkwin == tkwin) {
resultObj = Tk_GetOptionInfo(interp,
@@ -1329,6 +1353,7 @@ PanedWindowEventProc(
XEvent *eventPtr) /* Information about event. */
{
PanedWindow *pwPtr = clientData;
+ int i;
if (eventPtr->type == Expose) {
if (pwPtr->tkwin != NULL && !(pwPtr->flags & REDRAW_PENDING)) {
@@ -1343,6 +1368,14 @@ PanedWindowEventProc(
}
} else if (eventPtr->type == DestroyNotify) {
DestroyPanedWindow(pwPtr);
+ } else if (eventPtr->type == UnmapNotify) {
+ for (i = 0; i < pwPtr->numSlaves; i++) {
+ Tk_UnmapWindow(pwPtr->slaves[i]->tkwin);
+ }
+ } else if (eventPtr->type == MapNotify) {
+ for (i = 0; i < pwPtr->numSlaves; i++) {
+ Tk_MapWindow(pwPtr->slaves[i]->tkwin);
+ }
}
}
@@ -1411,6 +1444,7 @@ DisplayPanedWindow(
Tk_Window tkwin = pwPtr->tkwin;
int i, sashWidth, sashHeight;
const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL);
+ int first, last;
pwPtr->flags &= ~REDRAW_PENDING;
if ((pwPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
@@ -1457,9 +1491,10 @@ DisplayPanedWindow(
* Draw the sashes.
*/
+ GetFirstLastVisiblePane(pwPtr, &first, &last);
for (i = 0; i < pwPtr->numSlaves - 1; i++) {
slavePtr = pwPtr->slaves[i];
- if (slavePtr->hide) {
+ if (slavePtr->hide || i == last) {
continue;
}
if (sashWidth > 0 && sashHeight > 0) {
@@ -1705,17 +1740,10 @@ ArrangePanes(
Tcl_Preserve(pwPtr);
/*
- * Find index of last visible pane.
+ * Find index of first and last visible panes.
*/
- for (i = 0, last = 0, first = -1; i < pwPtr->numSlaves; i++) {
- if (pwPtr->slaves[i]->hide == 0) {
- if (first < 0) {
- first = i;
- }
- last = i;
- }
- }
+ GetFirstLastVisiblePane(pwPtr, &first, &last);
/*
* First pass; compute sizes
@@ -2053,6 +2081,41 @@ GetPane(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * GetFirstLastVisiblePane --
+ *
+ * Given panedwindow, find the index of the first and last visible panes
+ * of that paned window.
+ *
+ * Results:
+ * Index of the first and last visible panes.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetFirstLastVisiblePane(
+ PanedWindow *pwPtr, /* Pointer to the paned window info. */
+ int *firstPtr, /* Returned index for first. */
+ int *lastPtr) /* Returned index for last. */
+{
+ int i;
+
+ for (i = 0, *lastPtr = 0, *firstPtr = -1; i < pwPtr->numSlaves; i++) {
+ if (pwPtr->slaves[i]->hide == 0) {
+ if (*firstPtr < 0) {
+ *firstPtr = i;
+ }
+ *lastPtr = i;
+ }
+ }
+}
+
+/*
*--------------------------------------------------------------
*
* SlaveStructureProc --
@@ -2553,7 +2616,7 @@ MoveSash(
slavePtr->paneWidth = slavePtr->width = slavePtr->sashx
- sashOffset - slavePtr->x - (2 * slavePtr->padx);
} else {
- slavePtr->paneWidth = slavePtr->height = slavePtr->sashy
+ slavePtr->paneHeight = slavePtr->height = slavePtr->sashy
- sashOffset - slavePtr->y - (2 * slavePtr->pady);
}
}
@@ -2726,8 +2789,10 @@ DisplayProxyWindow(
* Redraw the widget's background and border.
*/
- Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background, 0, 0,
- Tk_Width(tkwin), Tk_Height(tkwin), 2, pwPtr->sashRelief);
+ Tk_Fill3DRectangle(tkwin, pixmap,
+ pwPtr->proxyBackground ? pwPtr->proxyBackground : pwPtr->background,
+ 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), pwPtr->proxyBorderWidth,
+ (pwPtr->proxyRelief != TK_RELIEF_NULL) ? pwPtr->proxyRelief : pwPtr->sashRelief);
#ifndef TK_NO_DOUBLE_BUFFERING
/*
@@ -2771,6 +2836,7 @@ PanedWindowProxyCommand(
PROXY_COORD, PROXY_FORGET, PROXY_PLACE
};
int index, x, y, sashWidth, sashHeight;
+ int internalBW, pwWidth, pwHeight;
Tcl_Obj *coords[2];
if (objc < 3) {
@@ -2820,11 +2886,16 @@ PanedWindowProxyCommand(
return TCL_ERROR;
}
+ internalBW = Tk_InternalBorderWidth(pwPtr->tkwin);
if (pwPtr->orient == ORIENT_HORIZONTAL) {
if (x < 0) {
x = 0;
}
- y = Tk_InternalBorderWidth(pwPtr->tkwin);
+ pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW);
+ if (x > pwWidth) {
+ x = pwWidth;
+ }
+ y = Tk_InternalBorderWidth(pwPtr->tkwin);
sashWidth = pwPtr->sashWidth;
sashHeight = Tk_Height(pwPtr->tkwin) -
(2 * Tk_InternalBorderWidth(pwPtr->tkwin));
@@ -2832,6 +2903,10 @@ PanedWindowProxyCommand(
if (y < 0) {
y = 0;
}
+ pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW);
+ if (y > pwHeight) {
+ y = pwHeight;
+ }
x = Tk_InternalBorderWidth(pwPtr->tkwin);
sashHeight = pwPtr->sashWidth;
sashWidth = Tk_Width(pwPtr->tkwin) -
@@ -2905,7 +2980,7 @@ ObjectIsEmpty(
if (objPtr->bytes != NULL) {
return (objPtr->length == 0);
}
- Tcl_GetStringFromObj(objPtr, &length);
+ (void)Tcl_GetStringFromObj(objPtr, &length);
return (length == 0);
}
@@ -2966,6 +3041,7 @@ PanedWindowIdentifyCoords(
{
int i, sashHeight, sashWidth, thisx, thisy;
int found, isHandle, lpad, rpad, tpad, bpad;
+ int first, last;
if (pwPtr->orient == ORIENT_HORIZONTAL) {
if (Tk_IsMapped(pwPtr->tkwin)) {
@@ -3005,10 +3081,11 @@ PanedWindowIdentifyCoords(
lpad = rpad = 0;
}
+ GetFirstLastVisiblePane(pwPtr, &first, &last);
isHandle = 0;
found = -1;
for (i = 0; i < pwPtr->numSlaves - 1; i++) {
- if (pwPtr->slaves[i]->hide) {
+ if (pwPtr->slaves[i]->hide || i == last) {
continue;
}
thisx = pwPtr->slaves[i]->sashx;
diff --git a/generic/tkPlace.c b/generic/tkPlace.c
index afba488..9fa406a 100644
--- a/generic/tkPlace.c
+++ b/generic/tkPlace.c
@@ -276,8 +276,8 @@ Tk_PlaceObjCmd(
dispPtr->placeInit = 1;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
diff --git a/generic/tkPlatDecls.h b/generic/tkPlatDecls.h
index 057d38c..1e69c88 100644
--- a/generic/tkPlatDecls.h
+++ b/generic/tkPlatDecls.h
@@ -29,11 +29,15 @@ extern "C" {
/* !BEGIN!: Do not edit below this line. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
/* 0 */
EXTERN Window Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);
/* 1 */
@@ -82,9 +86,9 @@ EXTERN int Tk_MacOSXIsAppInFront(void);
typedef struct TkPlatStubs {
int magic;
- const struct TkPlatStubHooks *hooks;
+ void *hooks;
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */
HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */
HWND (*tk_GetHWND) (Window window); /* 2 */
@@ -107,10 +111,8 @@ typedef struct TkPlatStubs {
#endif /* AQUA */
} TkPlatStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TkPlatStubs *tkPlatStubsPtr;
+
#ifdef __cplusplus
}
#endif
@@ -121,7 +123,7 @@ extern const TkPlatStubs *tkPlatStubsPtr;
* Inline function declarations:
*/
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
#define Tk_AttachHWND \
(tkPlatStubsPtr->tk_AttachHWND) /* 0 */
#define Tk_GetHINSTANCE \
diff --git a/generic/tkPointer.c b/generic/tkPointer.c
index 451373d..0141b64 100644
--- a/generic/tkPointer.c
+++ b/generic/tkPointer.c
@@ -14,7 +14,7 @@
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#endif
diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c
index a51ca33..50b5f1a 100644
--- a/generic/tkRectOval.c
+++ b/generic/tkRectOval.c
@@ -671,11 +671,11 @@ ComputeRectOvalBbox(
* correct place to solve it, but it works.
*/
-#ifdef __WIN32__
+#ifdef _WIN32
bloat = 1;
#else
bloat = 0;
-#endif /* __WIN32__ */
+#endif /* _WIN32 */
} else {
#ifdef MAC_OSX_TK
/*
diff --git a/generic/tkScale.c b/generic/tkScale.c
index 3ca4a67..cc7c294 100644
--- a/generic/tkScale.c
+++ b/generic/tkScale.c
@@ -340,8 +340,8 @@ ScaleWidgetObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
- "option", 0, &index);
+ result = Tcl_GetIndexFromObjStruct(interp, objv[1], commandNames,
+ sizeof(char *), "option", 0, &index);
if (result != TCL_OK) {
return result;
}
@@ -504,8 +504,8 @@ DestroyScale(
*/
if (scalePtr->varNamePtr != NULL) {
- Tcl_UntraceVar(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ScaleVarProc, scalePtr);
}
if (scalePtr->troughGC != None) {
@@ -561,8 +561,8 @@ ConfigureScale(
*/
if (scalePtr->varNamePtr != NULL) {
- Tcl_UntraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ScaleVarProc, scalePtr);
}
@@ -677,8 +677,8 @@ ConfigureScale(
ScaleSetVariable(scalePtr);
}
}
- Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ScaleVarProc, scalePtr);
}
@@ -800,6 +800,9 @@ ComputeFormat(
*/
numDigits = scalePtr->digits;
+ if (numDigits > TCL_MAX_PREC) {
+ numDigits = 0;
+ }
if (numDigits <= 0) {
if (scalePtr->resolution > 0) {
/*
@@ -880,7 +883,7 @@ static void
ComputeScaleGeometry(
register TkScale *scalePtr) /* Information about widget. */
{
- char valueString[PRINT_CHARS];
+ char valueString[TCL_DOUBLE_SPACE];
int tmp, valuePixels, x, y, extraSpace;
Tk_FontMetrics fm;
@@ -1180,8 +1183,8 @@ ScaleVarProc(
if (flags & TCL_TRACE_UNSETS) {
if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {
- Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
ScaleVarProc, clientData);
scalePtr->flags |= NEVER_SET;
TkScaleSetValue(scalePtr, scalePtr->value, 1, 0);
@@ -1296,7 +1299,7 @@ ScaleSetVariable(
register TkScale *scalePtr) /* Info about widget. */
{
if (scalePtr->varNamePtr != NULL) {
- char string[PRINT_CHARS];
+ char string[TCL_DOUBLE_SPACE];
sprintf(string, scalePtr->format, scalePtr->value);
scalePtr->flags |= SETTING_VAR;
diff --git a/generic/tkScale.h b/generic/tkScale.h
index af35978..4fd9995 100644
--- a/generic/tkScale.h
+++ b/generic/tkScale.h
@@ -215,12 +215,6 @@ typedef struct TkScale {
#define SPACING 2
/*
- * How many characters of space to provide when formatting the scale's value:
- */
-
-#define PRINT_CHARS 150
-
-/*
* Declaration of procedures used in the implementation of the scale widget.
*/
diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c
index 2d91db6..5017d30 100644
--- a/generic/tkScrollbar.c
+++ b/generic/tkScrollbar.c
@@ -12,10 +12,6 @@
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-/*
- * TODO: Convert scrollbars to the Tcl_Obj API.
- */
-
#include "tkInt.h"
#include "tkScrollbar.h"
#include "default.h"
@@ -101,16 +97,16 @@ static const Tk_ConfigSpec configSpecs[] = {
*/
static int ConfigureScrollbar(Tcl_Interp *interp,
- TkScrollbar *scrollPtr, int argc,
- const char **argv, int flags);
+ TkScrollbar *scrollPtr, int objc,
+ Tcl_Obj *const objv[], int flags);
static void ScrollbarCmdDeletedProc(ClientData clientData);
-static int ScrollbarWidgetCmd(ClientData clientData,
- Tcl_Interp *, int argc, const char **argv);
+static int ScrollbarWidgetObjCmd(ClientData clientData,
+ Tcl_Interp *, int objc, Tcl_Obj *const objv[]);
/*
*--------------------------------------------------------------
*
- * Tk_ScrollbarCmd --
+ * Tk_ScrollbarObjCmd --
*
* This function is invoked to process the "scrollbar" Tcl command. See
* the user documentation for details on what it does.
@@ -125,25 +121,22 @@ static int ScrollbarWidgetCmd(ClientData clientData,
*/
int
-Tk_ScrollbarCmd(
+Tk_ScrollbarObjCmd(
ClientData clientData, /* Main window associated with interpreter. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
Tk_Window tkwin = clientData;
register TkScrollbar *scrollPtr;
Tk_Window newWin;
- if (argc < 2) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s pathName ?-option value ...?\"",
- argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
return TCL_ERROR;
}
- newWin = Tk_CreateWindowFromPath(interp, tkwin, argv[1], NULL);
+ newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), NULL);
if (newWin == NULL) {
return TCL_ERROR;
}
@@ -162,8 +155,8 @@ Tk_ScrollbarCmd(
scrollPtr->tkwin = newWin;
scrollPtr->display = Tk_Display(newWin);
scrollPtr->interp = interp;
- scrollPtr->widgetCmd = Tcl_CreateCommand(interp,
- Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetCmd,
+ scrollPtr->widgetCmd = Tcl_CreateObjCommand(interp,
+ Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetObjCmd,
scrollPtr, ScrollbarCmdDeletedProc);
scrollPtr->vertical = 0;
scrollPtr->width = 0;
@@ -196,7 +189,7 @@ Tk_ScrollbarCmd(
scrollPtr->takeFocus = NULL;
scrollPtr->flags = 0;
- if (ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2, 0) != TCL_OK) {
+ if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {
Tk_DestroyWindow(scrollPtr->tkwin);
return TCL_ERROR;
}
@@ -208,7 +201,7 @@ Tk_ScrollbarCmd(
/*
*--------------------------------------------------------------
*
- * ScrollbarWidgetCmd --
+ * ScrollbarWidgetObjCmd --
*
* This function is invoked to process the Tcl command that corresponds
* to a widget managed by this module. See the user documentation for
@@ -224,30 +217,44 @@ Tk_ScrollbarCmd(
*/
static int
-ScrollbarWidgetCmd(
+ScrollbarWidgetObjCmd(
ClientData clientData, /* Information about scrollbar widget. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
register TkScrollbar *scrollPtr = clientData;
int result = TCL_OK;
- size_t length;
- int c;
-
- if (argc < 2) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s option ?arg ...?\"", argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ int length, cmdIndex;
+ static const char *const commandNames[] = {
+ "activate", "cget", "configure", "delta", "fraction",
+ "get", "identify", "set", NULL
+ };
+ enum command {
+ COMMAND_ACTIVATE, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELTA,
+ COMMAND_FRACTION, COMMAND_GET, COMMAND_IDENTIFY, COMMAND_SET
+ };
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
+ /*
+ * Parse the command by looking up the second argument in the list of
+ * valid subcommand names
+ */
+
+ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames,
+ "option", 0, &cmdIndex);
+ if (result != TCL_OK) {
+ return result;
+ }
Tcl_Preserve(scrollPtr);
- c = argv[1][0];
- length = strlen(argv[1]);
- if ((c == 'a') && (strncmp(argv[1], "activate", length) == 0)) {
- int oldActiveField;
+ switch (cmdIndex) {
+ case COMMAND_ACTIVATE: {
+ int oldActiveField, c;
- if (argc == 2) {
+ if (objc == 2) {
const char *zone = "";
switch (scrollPtr->activeField) {
@@ -258,21 +265,17 @@ ScrollbarWidgetCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
goto done;
}
- if (argc != 3) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s activate element\"",
- argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "activate element");
goto error;
}
- c = argv[2][0];
- length = strlen(argv[2]);
+ c = Tcl_GetStringFromObj(objv[2], &length)[0];
oldActiveField = scrollPtr->activeField;
- if ((c == 'a') && (strcmp(argv[2], "arrow1") == 0)) {
+ if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) {
scrollPtr->activeField = TOP_ARROW;
- } else if ((c == 'a') && (strcmp(argv[2], "arrow2") == 0)) {
+ } else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) {
scrollPtr->activeField = BOTTOM_ARROW;
- } else if ((c == 's') && (strncmp(argv[2], "slider", length) == 0)) {
+ } else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", length) == 0)) {
scrollPtr->activeField = SLIDER;
} else {
scrollPtr->activeField = OUTSIDE;
@@ -280,41 +283,40 @@ ScrollbarWidgetCmd(
if (oldActiveField != scrollPtr->activeField) {
TkScrollbarEventuallyRedraw(scrollPtr);
}
- } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
- && (length >= 2)) {
- if (argc != 3) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s cget option\"", argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ break;
+ }
+ case COMMAND_CGET: {
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "cget option");
goto error;
}
result = Tk_ConfigureValue(interp, scrollPtr->tkwin,
- configSpecs, (char *) scrollPtr, argv[2], 0);
- } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
- && (length >= 2)) {
- if (argc == 2) {
+ configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
+ break;
+ }
+ case COMMAND_CONFIGURE: {
+ if (objc == 2) {
result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
configSpecs, (char *) scrollPtr, NULL, 0);
- } else if (argc == 3) {
+ } else if (objc == 3) {
result = Tk_ConfigureInfo(interp, scrollPtr->tkwin,
- configSpecs, (char *) scrollPtr, argv[2], 0);
+ configSpecs, (char *) scrollPtr, Tcl_GetString(objv[2]), 0);
} else {
- result = ConfigureScrollbar(interp, scrollPtr, argc-2, argv+2,
- TK_CONFIG_ARGV_ONLY);
+ result = ConfigureScrollbar(interp, scrollPtr, objc-2,
+ objv+2, TK_CONFIG_ARGV_ONLY);
}
- } else if ((c == 'd') && (strncmp(argv[1], "delta", length) == 0)) {
+ break;
+ }
+ case COMMAND_DELTA: {
int xDelta, yDelta, pixels, length;
double fraction;
- if (argc != 4) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s delta xDelta yDelta\"",
- argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "delta xDelta yDelta");
goto error;
}
- if ((Tcl_GetInt(interp, argv[2], &xDelta) != TCL_OK)
- || (Tcl_GetInt(interp, argv[3], &yDelta) != TCL_OK)) {
+ if ((Tcl_GetIntFromObj(interp, objv[2], &xDelta) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &yDelta) != TCL_OK)) {
goto error;
}
if (scrollPtr->vertical) {
@@ -332,18 +334,18 @@ ScrollbarWidgetCmd(
fraction = ((double) pixels / (double) length);
}
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
- } else if ((c == 'f') && (strncmp(argv[1], "fraction", length) == 0)) {
+ break;
+ }
+ case COMMAND_FRACTION: {
int x, y, pos, length;
double fraction;
- if (argc != 4) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s fraction x y\"", argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "fraction x y");
goto error;
}
- if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
- || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
goto error;
}
if (scrollPtr->vertical) {
@@ -366,13 +368,13 @@ ScrollbarWidgetCmd(
fraction = 1.0;
}
Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fraction));
- } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
+ break;
+ }
+ case COMMAND_GET: {
Tcl_Obj *resObjs[4];
- if (argc != 2) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s get\"", argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "get");
goto error;
}
if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
@@ -386,18 +388,18 @@ ScrollbarWidgetCmd(
resObjs[3] = Tcl_NewIntObj(scrollPtr->lastUnit);
Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs));
}
- } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) {
+ break;
+ }
+ case COMMAND_IDENTIFY: {
int x, y;
const char *zone = "";
- if (argc != 4) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be \"%s identify x y\"", argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "identify x y");
goto error;
}
- if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
- || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
goto error;
}
switch (TkpScrollbarPosition(scrollPtr, x, y)) {
@@ -408,16 +410,18 @@ ScrollbarWidgetCmd(
case BOTTOM_ARROW: zone = "arrow2"; break;
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
- } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) {
+ break;
+ }
+ case COMMAND_SET: {
int totalUnits, windowUnits, firstUnit, lastUnit;
- if (argc == 4) {
+ if (objc == 4) {
double first, last;
- if (Tcl_GetDouble(interp, argv[2], &first) != TCL_OK) {
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) {
goto error;
}
- if (Tcl_GetDouble(interp, argv[3], &last) != TCL_OK) {
+ if (Tcl_GetDoubleFromObj(interp, objv[3], &last) != TCL_OK) {
goto error;
}
if (first < 0) {
@@ -435,23 +439,23 @@ ScrollbarWidgetCmd(
scrollPtr->lastFraction = last;
}
scrollPtr->flags |= NEW_STYLE_COMMANDS;
- } else if (argc == 6) {
- if (Tcl_GetInt(interp, argv[2], &totalUnits) != TCL_OK) {
+ } else if (objc == 6) {
+ if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) {
goto error;
}
if (totalUnits < 0) {
totalUnits = 0;
}
- if (Tcl_GetInt(interp, argv[3], &windowUnits) != TCL_OK) {
+ if (Tcl_GetIntFromObj(interp, objv[3], &windowUnits) != TCL_OK) {
goto error;
}
if (windowUnits < 0) {
windowUnits = 0;
}
- if (Tcl_GetInt(interp, argv[4], &firstUnit) != TCL_OK) {
+ if (Tcl_GetIntFromObj(interp, objv[4], &firstUnit) != TCL_OK) {
goto error;
}
- if (Tcl_GetInt(interp, argv[5], &lastUnit) != TCL_OK) {
+ if (Tcl_GetIntFromObj(interp, objv[5], &lastUnit) != TCL_OK) {
goto error;
}
if (totalUnits > 0) {
@@ -474,23 +478,15 @@ ScrollbarWidgetCmd(
}
scrollPtr->flags &= ~NEW_STYLE_COMMANDS;
} else {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: should be "
- "\"%s set firstFraction lastFraction\" or "
- "\"%s set totalUnits windowUnits firstUnit lastUnit\"",
- argv[0], argv[0]));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+ 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);
TkScrollbarEventuallyRedraw(scrollPtr);
- } else {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad option \"%s\": must be activate, cget, configure,"
- " delta, fraction, get, identify, or set", argv[1]));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
- argv[1], NULL);
- goto error;
+ break;
+ }
}
done:
@@ -528,12 +524,12 @@ ConfigureScrollbar(
register TkScrollbar *scrollPtr,
/* Information about widget; may or may not
* already have values for some fields. */
- int argc, /* Number of valid entries in argv. */
- const char **argv, /* Arguments. */
+ int objc, /* Number of valid entries in argv. */
+ Tcl_Obj *const objv[], /* Arguments. */
int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
- if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs,
- argc, argv, (char *) scrollPtr, flags) != TCL_OK) {
+ if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc,
+ (const char **)objv, (char *) scrollPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
return TCL_ERROR;
}
@@ -626,6 +622,8 @@ TkScrollbarEventProc(
TkScrollbarEventuallyRedraw(scrollPtr);
}
}
+ } else if (eventPtr->type == MapNotify) {
+ TkScrollbarEventuallyRedraw(scrollPtr);
}
}
diff --git a/generic/tkSelect.c b/generic/tkSelect.c
index 2414b3d..ab9018a 100644
--- a/generic/tkSelect.c
+++ b/generic/tkSelect.c
@@ -1193,7 +1193,7 @@ TkSelInit(
* http://www.cl.cam.ac.uk/~mgk25/unicode.html#x11
*/
-#if !defined(__WIN32__)
+#if !defined(_WIN32)
dispPtr->utf8Atom = Tk_InternAtom(tkwin, "UTF8_STRING");
#else
dispPtr->utf8Atom = (Atom) 0;
diff --git a/generic/tkSquare.c b/generic/tkSquare.c
index 787630d..36d2d6e 100644
--- a/generic/tkSquare.c
+++ b/generic/tkSquare.c
@@ -98,7 +98,7 @@ static const Tk_OptionSpec optionSpecs[] = {
static void SquareDeletedProc(ClientData clientData);
static int SquareConfigure(Tcl_Interp *interp, Square *squarePtr);
-static void SquareDestroy(char *memPtr);
+static void SquareDestroy(void *memPtr);
static void SquareDisplay(ClientData clientData);
static void KeepInWindow(Square *squarePtr);
static void SquareObjEventProc(ClientData clientData,
@@ -237,8 +237,8 @@ SquareWidgetObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], squareOptions, "command",
- 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], squareOptions,
+ sizeof(char *), "command", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -410,7 +410,7 @@ SquareObjEventProc(
if (squarePtr->updatePending) {
Tcl_CancelIdleCall(SquareDisplay, squarePtr);
}
- Tcl_EventuallyFree(squarePtr, SquareDestroy);
+ Tcl_EventuallyFree(squarePtr, (Tcl_FreeProc *) SquareDestroy);
}
}
@@ -554,9 +554,9 @@ SquareDisplay(
static void
SquareDestroy(
- char *memPtr) /* Info about square widget. */
+ void *memPtr) /* Info about square widget. */
{
- Square *squarePtr = (Square *) memPtr;
+ Square *squarePtr = memPtr;
ckfree(squarePtr);
}
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index b1cdd53..f08d7f4 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -11,13 +11,13 @@
#include "tkInt.h"
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK))
/* UNIX */
#define UNIX_TK
#include "tkUnixInt.h"
#endif
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#endif
@@ -31,6 +31,7 @@
#include "tkIntXlibDecls.h"
static const TkIntStubs tkIntStubs;
+MODULE_SCOPE const TkStubs tkStubs;
/*
* Remove macro that might interfere with the definition below.
@@ -38,7 +39,7 @@ static const TkIntStubs tkIntStubs;
#undef Tk_MainEx
-#ifdef __WIN32__
+#ifdef _WIN32
int
TkpCmapStressed(Tk_Window tkwin, Colormap colormap)
@@ -65,7 +66,7 @@ TkCreateXEventSource(void)
# define TkSendCleanup (void (*)(TkDisplay *)) TkpSync
# define TkpTestsendCmd 0
-#else /* !__WIN32__ */
+#else /* !_WIN32 */
/*
* Make sure that extensions which call XParseColor through the stub
@@ -224,10 +225,7 @@ void TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
# define TkUnionRectWithRegion (void (*) (XRectangle *, TkRegion, TkRegion)) XUnionRectWithRegion
# define TkSubtractRegion (void (*) (TkRegion, TkRegion, TkRegion)) XSubtractRegion
# endif
-#endif /* !__WIN32__ */
-
-#define reserved274 (void (*)(void)) Tk_DefineBitmap
-#define reserved275 (void (*)(void)) Tk_GetBitmapFromData
+#endif /* !_WIN32 */
/*
* WARNING: The contents of this file is automatically generated by the
@@ -361,20 +359,20 @@ static const TkIntStubs tkIntStubs = {
TkSetRegion, /* 118 */
TkUnionRectWithRegion, /* 119 */
0, /* 120 */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
0, /* 121 */
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 121 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
0, /* 121 */ /* Dummy entry for stubs table backwards compatibility */
TkpCreateNativeBitmap, /* 121 */
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
0, /* 122 */
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 122 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
@@ -382,10 +380,10 @@ static const TkIntStubs tkIntStubs = {
TkpDefineNativeBitmaps, /* 122 */
#endif /* AQUA */
0, /* 123 */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
0, /* 124 */
#endif /* X11 */
-#if defined(__WIN32__) /* WIN */
+#if defined(_WIN32) /* WIN */
0, /* 124 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
@@ -457,7 +455,7 @@ static const TkIntStubs tkIntStubs = {
static const TkIntPlatStubs tkIntPlatStubs = {
TCL_STUB_MAGIC,
0,
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
TkAlignImageData, /* 0 */
0, /* 1 */
TkGenerateActivateEvents, /* 2 */
@@ -558,11 +556,12 @@ static const TkIntPlatStubs tkIntPlatStubs = {
TkGetTransientMaster, /* 49 */
TkGenerateButtonEvent, /* 50 */
TkGenWMDestroyEvent, /* 51 */
- 0, /* 52 */
+ TkMacOSXSetDrawingEnabled, /* 52 */
TkpGetMS, /* 53 */
TkMacOSXDrawable, /* 54 */
+ TkpScanWindowId, /* 55 */
#endif /* AQUA */
-#if !(defined(__WIN32__) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
+#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */
TkCreateXEventSource, /* 0 */
0, /* 1 */
0, /* 2 */
@@ -583,7 +582,7 @@ static const TkIntPlatStubs tkIntPlatStubs = {
static const TkIntXlibStubs tkIntXlibStubs = {
TCL_STUB_MAGIC,
0,
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
XSetDashes, /* 0 */
XGetModifierMapping, /* 1 */
XCreateImage, /* 2 */
@@ -799,7 +798,7 @@ static const TkIntXlibStubs tkIntXlibStubs = {
static const TkPlatStubs tkPlatStubs = {
TCL_STUB_MAGIC,
0,
-#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
Tk_AttachHWND, /* 0 */
Tk_GetHINSTANCE, /* 1 */
Tk_GetHWND, /* 2 */
@@ -1106,8 +1105,6 @@ const TkStubs tkStubs = {
Tk_Interp, /* 271 */
Tk_CreateOldImageType, /* 272 */
Tk_CreateOldPhotoImageFormat, /* 273 */
- reserved274, /* 274 */
- reserved275, /* 275 */
};
/* !END!: Do not edit above this line. */
diff --git a/generic/tkStubLib.c b/generic/tkStubLib.c
index b4063b5..ea48894 100644
--- a/generic/tkStubLib.c
+++ b/generic/tkStubLib.c
@@ -1,31 +1,19 @@
/*
* tkStubLib.c --
*
- * Stub object that will be statically linked into extensions that wish
+ * Stub object that will be statically linked into extensions that want
* to access Tk.
*
- * Copyright (c) 1998 Paul Duffin.
* Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 1998 Paul Duffin.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-/*
- * We need to ensure that we use the stub macros so that this file contains no
- * references to any of the stub functions. This will make it possible to
- * build an extension that references Tk_InitStubs but doesn't end up
- * including the rest of the stub functions.
- */
-
-#undef USE_TCL_STUBS
-#define USE_TCL_STUBS
-
-#define USE_TK_STUBS
-
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#endif
@@ -33,7 +21,7 @@
#include "tkMacOSXInt.h"
#endif
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#include "tkUnixInt.h"
#endif
@@ -58,8 +46,7 @@ const TkIntXlibStubs *tkIntXlibStubsPtr = NULL;
*/
static int
-isDigit(
- const int c)
+isDigit(const int c)
{
return (c >= '0' && c <= '9');
}
@@ -81,61 +68,73 @@ isDigit(
*
*----------------------------------------------------------------------
*/
-
+#undef Tk_InitStubs
MODULE_SCOPE const char *
Tk_InitStubs(
Tcl_Interp *interp,
const char *version,
int exact)
{
- ClientData pkgClientData = NULL;
- const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0,
- &pkgClientData);
- const TkStubs *stubsPtr = pkgClientData;
-
- if (!actualVersion) {
+ const char *packageName = "Tk";
+ const char *errMsg = NULL;
+ ClientData clientData = NULL;
+ const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
+ packageName, version, 0, &clientData);
+ const TkStubs *stubsPtr = clientData;
+
+ if (actualVersion == NULL) {
return NULL;
}
+
if (exact) {
- const char *p = version;
- int count = 0;
+ const char *p = version;
+ int count = 0;
- while (*p) {
- count += !isDigit(*p++);
- }
- if (count == 1) {
+ while (*p) {
+ count += !isDigit(*p++);
+ }
+ if (count == 1) {
const char *q = actualVersion;
p = version;
while (*p && (*p == *q)) {
p++; q++;
}
- if (*p) {
+ if (*p || isDigit(*q)) {
/* Construct error message */
- Tcl_PkgRequireEx(interp, "Tk", version, 1, NULL);
- return NULL;
- }
- } else {
- actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 1, NULL);
- if (actualVersion == NULL) {
- return NULL;
- }
- }
+ tclStubsPtr->tcl_PkgRequireEx(interp, packageName, version, 1, NULL);
+ return NULL;
+ }
+ } else {
+ actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp, packageName,
+ version, 1, NULL);
+ if (actualVersion == NULL) {
+ return NULL;
+ }
+ }
}
-
- if (!stubsPtr) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "this implementation of Tk does not support stubs", -1));
- return NULL;
+ if (stubsPtr == NULL) {
+ errMsg = "missing stub table pointer";
+ } else {
+ tkStubsPtr = stubsPtr;
+ if (stubsPtr->hooks) {
+ tkPlatStubsPtr = stubsPtr->hooks->tkPlatStubs;
+ tkIntStubsPtr = stubsPtr->hooks->tkIntStubs;
+ tkIntPlatStubsPtr = stubsPtr->hooks->tkIntPlatStubs;
+ tkIntXlibStubsPtr = stubsPtr->hooks->tkIntXlibStubs;
+ } else {
+ tkPlatStubsPtr = NULL;
+ tkIntStubsPtr = NULL;
+ tkIntPlatStubsPtr = NULL;
+ tkIntXlibStubsPtr = NULL;
+ }
+ return actualVersion;
}
-
- tkPlatStubsPtr = stubsPtr->hooks->tkPlatStubs;
- tkIntStubsPtr = stubsPtr->hooks->tkIntStubs;
- tkIntPlatStubsPtr = stubsPtr->hooks->tkIntPlatStubs;
- tkIntXlibStubsPtr = stubsPtr->hooks->tkIntXlibStubs;
- tkStubsPtr = stubsPtr;
-
- return actualVersion;
+ tclStubsPtr->tcl_ResetResult(interp);
+ tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
+ " (requested version ", version, ", actual version ",
+ actualVersion, "): ", errMsg, NULL);
+ return NULL;
}
/*
diff --git a/generic/tkStyle.c b/generic/tkStyle.c
index d5e1407..e7401df 100644
--- a/generic/tkStyle.c
+++ b/generic/tkStyle.c
@@ -146,8 +146,8 @@ static int SetStyleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
/*
* The following structure defines the implementation of the "style" Tcl
- * object, used for drawing. The internalRep.otherValuePtr field of each style
- * object points to the Style structure for the stylefont, or NULL.
+ * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each
+ * style object points to the Style structure for the stylefont, or NULL.
*/
static const Tcl_ObjType styleObjType = {
@@ -1410,7 +1410,7 @@ Tk_AllocStyleFromObj(
if (objPtr->typePtr != &styleObjType) {
SetStyleFromAny(interp, objPtr);
}
- stylePtr = objPtr->internalRep.otherValuePtr;
+ stylePtr = objPtr->internalRep.twoPtrValue.ptr1;
return (Tk_Style) stylePtr;
}
@@ -1442,7 +1442,7 @@ Tk_GetStyleFromObj(
SetStyleFromAny(NULL, objPtr);
}
- return objPtr->internalRep.otherValuePtr;
+ return objPtr->internalRep.twoPtrValue.ptr1;
}
/*
@@ -1497,7 +1497,7 @@ SetStyleFromAny(
}
objPtr->typePtr = &styleObjType;
- objPtr->internalRep.otherValuePtr = Tk_GetStyle(interp, name);
+ objPtr->internalRep.twoPtrValue.ptr1 = Tk_GetStyle(interp, name);
return TCL_OK;
}
@@ -1520,7 +1520,7 @@ static void
FreeStyleObjProc(
Tcl_Obj *objPtr) /* The object we are releasing. */
{
- objPtr->internalRep.otherValuePtr = NULL;
+ objPtr->internalRep.twoPtrValue.ptr1 = NULL;
objPtr->typePtr = NULL;
}
@@ -1541,8 +1541,8 @@ DupStyleObjProc(
Tcl_Obj *dupObjPtr) /* The object we are copying to. */
{
dupObjPtr->typePtr = srcObjPtr->typePtr;
- dupObjPtr->internalRep.otherValuePtr =
- srcObjPtr->internalRep.otherValuePtr;
+ dupObjPtr->internalRep.twoPtrValue.ptr1 =
+ srcObjPtr->internalRep.twoPtrValue.ptr1;
}
/*
diff --git a/generic/tkTest.c b/generic/tkTest.c
index bd15739..fa9e073 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -24,7 +24,7 @@
#include "tkInt.h"
#include "tkText.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#endif
@@ -139,8 +139,9 @@ typedef struct TrivialCommandHeader {
* Forward declarations for functions defined later in this file:
*/
-static int ImageCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+static int ImageObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
static int TestbitmapObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
@@ -153,20 +154,24 @@ static int TestcolorObjCmd(ClientData dummy,
static int TestcursorObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
-static int TestdeleteappsCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+static int TestdeleteappsObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
static int TestfontObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-static int TestmakeexistCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int TestmenubarCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+static int TestmakeexistObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
+static int TestmenubarObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
#endif
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
-static int TestmetricsCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+#if defined(_WIN32) || defined(MAC_OSX_TK)
+static int TestmetricsObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj * const objv[]);
#endif
static int TestobjconfigObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
@@ -184,11 +189,13 @@ static void CustomOptionRestore(ClientData clientData,
char *saveInternalPtr);
static void CustomOptionFree(ClientData clientData,
Tk_Window tkwin, char *internalPtr);
-static int TestpropCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-static int TestwrapperCmd(ClientData dummy,
- Tcl_Interp *interp, int argc, const char **argv);
+static int TestpropObjCmd(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,
+ Tcl_Obj * const objv[]);
#endif
static void TrivialCmdDeletedProc(ClientData clientData);
static int TrivialConfigObjCmd(ClientData dummy,
@@ -223,7 +230,7 @@ Tktest_Init(
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
return TCL_ERROR;
}
- if (Tk_InitStubs(interp, "8.1", 0) == NULL) {
+ if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
return TCL_ERROR;
}
@@ -231,7 +238,7 @@ Tktest_Init(
* Create additional commands for testing Tk.
*/
- if (Tcl_PkgProvide(interp, "Tktest", TK_VERSION) == TCL_ERROR) {
+ if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -244,32 +251,32 @@ Tktest_Init(
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testdeleteapps", TestdeleteappsCmd,
+ Tcl_CreateObjCommand(interp, "testdeleteapps", TestdeleteappsObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testembed", TkpTestembedCmd,
+ Tcl_CreateObjCommand(interp, "testembed", TkpTestembedCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testmakeexist", TestmakeexistCmd,
+ Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testprop", TestpropCmd,
+ Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testtext", TkpTesttextCmd,
+ Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
- Tcl_CreateCommand(interp, "testmetrics", TestmetricsCmd,
+#if defined(_WIN32) || defined(MAC_OSX_TK)
+ Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#else
- Tcl_CreateCommand(interp, "testmenubar", TestmenubarCmd,
+#elif !defined(__CYGWIN__)
+ Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testsend", TkpTestsendCmd,
+ Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
(ClientData) Tk_MainWindow(interp), NULL);
- Tcl_CreateCommand(interp, "testwrapper", TestwrapperCmd,
+ Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#endif /* __WIN32__ || MAC_OSX_TK */
+#endif /* _WIN32 || MAC_OSX_TK */
/*
* Create test image type.
@@ -436,7 +443,7 @@ TestcursorObjCmd(
/*
*----------------------------------------------------------------------
*
- * TestdeleteappsCmd --
+ * TestdeleteappsObjCmd --
*
* This function implements the "testdeleteapps" command. It cleans up
* all the interpreters left behind by the "testnewapp" command.
@@ -453,11 +460,11 @@ TestcursorObjCmd(
/* ARGSUSED */
static int
-TestdeleteappsCmd(
+TestdeleteappsObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
NewApp *nextPtr;
@@ -497,11 +504,11 @@ TestobjconfigObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
static const char *const options[] = {
- "alltypes", "chain1", "chain2", "configerror", "delete", "info",
+ "alltypes", "chain1", "chain2", "chain3", "configerror", "delete", "info",
"internal", "new", "notenoughparams", "twowindows", NULL
};
enum {
- ALL_TYPES, CHAIN1, CHAIN2, CONFIG_ERROR,
+ ALL_TYPES, CHAIN1, CHAIN2, CHAIN3, CONFIG_ERROR,
DEL, /* Can't use DELETE: VC++ compiler barfs. */
INFO, INTERNAL, NEW, NOT_ENOUGH_PARAMS, TWO_WINDOWS
};
@@ -547,8 +554,8 @@ TestobjconfigObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
+ sizeof(char *), "command", 0, &index)!= TCL_OK) {
return TCL_ERROR;
}
@@ -720,7 +727,8 @@ TestobjconfigObjCmd(
break;
}
- case CHAIN2: {
+ case CHAIN2:
+ case CHAIN3: {
ExtensionWidgetRecord *recordPtr;
static const Tk_OptionSpec extensionSpecs[] = {
{TK_OPTION_STRING, "-three", "three", "Three", "three",
@@ -797,12 +805,15 @@ TestobjconfigObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "tableName");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], options,
+ sizeof(char *), "table", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
if (tables[index] != NULL) {
Tk_DeleteOptionTable(tables[index]);
+ /* Make sure that Tk_DeleteOptionTable() is never done
+ * twice for the same table. */
+ tables[index] = NULL;
}
break;
@@ -811,8 +822,8 @@ TestobjconfigObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "tableName");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], options,
+ sizeof(char *), "table", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
Tcl_SetObjResult(interp, TkDebugConfig(interp, tables[index]));
@@ -1143,8 +1154,8 @@ TrivialConfigObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
+ sizeof(char *), "command", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -1321,8 +1332,8 @@ TestfontObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], options,
+ sizeof(char *), "command", 0, &index)!= TCL_OK) {
return TCL_ERROR;
}
@@ -1403,7 +1414,7 @@ ImageCreate(
strcpy(timPtr->imageName, name);
timPtr->varName = ckalloc(strlen(varName) + 1);
strcpy(timPtr->varName, varName);
- Tcl_CreateCommand(interp, name, ImageCmd, timPtr, NULL);
+ Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
*clientDataPtr = timPtr;
Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
return TCL_OK;
@@ -1412,7 +1423,7 @@ ImageCreate(
/*
*----------------------------------------------------------------------
*
- * ImageCmd --
+ * ImageObjCmd --
*
* This function implements the commands corresponding to individual
* images.
@@ -1428,38 +1439,37 @@ ImageCreate(
/* ARGSUSED */
static int
-ImageCmd(
+ImageObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
TImageMaster *timPtr = (TImageMaster *) clientData;
int x, y, width, height;
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], "option ?arg ...?", NULL);
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (strcmp(argv[1], "changed") == 0) {
- if (argc != 8) {
- Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " changed x y width height imageWidth imageHeight", NULL);
+ if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
+ if (objc != 8) {
+ Tcl_WrongNumArgs(interp, 1, objv, "changed x y width height"
+ " imageWidth imageHeight");
return TCL_ERROR;
}
- if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK)
- || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)
- || (Tcl_GetInt(interp, argv[4], &width) != TCL_OK)
- || (Tcl_GetInt(interp, argv[5], &height) != TCL_OK)
- || (Tcl_GetInt(interp, argv[6], &timPtr->width) != TCL_OK)
- || (Tcl_GetInt(interp, argv[7], &timPtr->height) != TCL_OK)) {
+ if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[4], &width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[5], &height) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[6], &timPtr->width) != TCL_OK)
+ || (Tcl_GetIntFromObj(interp, objv[7], &timPtr->height) != TCL_OK)) {
return TCL_ERROR;
}
Tk_ImageChanged(timPtr->master, x, y, width, height, timPtr->width,
timPtr->height);
} else {
- Tcl_AppendResult(interp, "bad option \"", argv[1],
+ Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be changed", NULL);
return TCL_ERROR;
}
@@ -1496,7 +1506,7 @@ ImageGet(
XGCValues gcValues;
sprintf(buffer, "%s get", timPtr->imageName);
- Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
instPtr = ckalloc(sizeof(TImageInstance));
@@ -1543,8 +1553,8 @@ ImageDisplay(
sprintf(buffer, "%s display %d %d %d %d %d %d",
instPtr->masterPtr->imageName, imageX, imageY, width, height,
drawableX, drawableY);
- Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ 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)) {
width = instPtr->masterPtr->width - imageX;
}
@@ -1586,8 +1596,8 @@ ImageFree(
char buffer[200];
sprintf(buffer, "%s free", instPtr->masterPtr->imageName);
- Tcl_SetVar(instPtr->masterPtr->interp, instPtr->masterPtr->varName, buffer,
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
+ buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
Tk_FreeColor(instPtr->fg);
Tk_FreeGC(display, instPtr->gc);
ckfree(instPtr);
@@ -1620,7 +1630,7 @@ ImageDelete(
char buffer[100];
sprintf(buffer, "%s delete", timPtr->imageName);
- Tcl_SetVar(timPtr->interp, timPtr->varName, buffer,
+ Tcl_SetVar2(timPtr->interp, timPtr->varName, NULL, buffer,
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
Tcl_DeleteCommand(timPtr->interp, timPtr->imageName);
@@ -1632,7 +1642,7 @@ ImageDelete(
/*
*----------------------------------------------------------------------
*
- * TestmakeexistCmd --
+ * TestmakeexistObjCmd --
*
* This function implements the "testmakeexist" command. It calls
* Tk_MakeWindowExist on each of its arguments to force the windows to be
@@ -1649,18 +1659,18 @@ ImageDelete(
/* ARGSUSED */
static int
-TestmakeexistCmd(
+TestmakeexistObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
Tk_Window mainWin = (Tk_Window) clientData;
int i;
Tk_Window tkwin;
- for (i = 1; i < argc; i++) {
- tkwin = Tk_NameToWindow(interp, argv[i], mainWin);
+ for (i = 1; i < objc; i++) {
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i]), mainWin);
if (tkwin == NULL) {
return TCL_ERROR;
}
@@ -1673,7 +1683,7 @@ TestmakeexistCmd(
/*
*----------------------------------------------------------------------
*
- * TestmenubarCmd --
+ * TestmenubarObjCmd --
*
* This function implements the "testmenubar" command. It is used to test
* the Unix facilities for creating space above a toplevel window for a
@@ -1689,53 +1699,50 @@ TestmakeexistCmd(
*/
/* ARGSUSED */
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int
-TestmenubarCmd(
+TestmenubarObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
#ifdef __UNIX__
Tk_Window mainWin = (Tk_Window) clientData;
Tk_Window tkwin, menubar;
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option ?arg ...?\"", NULL);
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (strcmp(argv[1], "window") == 0) {
- if (argc != 4) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- "window toplevel menubar\"", NULL);
+ if (strcmp(Tcl_GetString(objv[1]), "window") == 0) {
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "windows toplevel menubar");
return TCL_ERROR;
}
- tkwin = Tk_NameToWindow(interp, argv[2], mainWin);
+ tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), mainWin);
if (tkwin == NULL) {
return TCL_ERROR;
}
- if (argv[3][0] == 0) {
+ if (Tcl_GetString(objv[3])[0] == 0) {
TkUnixSetMenubar(tkwin, NULL);
} else {
- menubar = Tk_NameToWindow(interp, argv[3], mainWin);
+ menubar = Tk_NameToWindow(interp, Tcl_GetString(objv[3]), mainWin);
if (menubar == NULL) {
return TCL_ERROR;
}
TkUnixSetMenubar(tkwin, menubar);
}
} else {
- Tcl_AppendResult(interp, "bad option \"", argv[1],
+ Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be window", NULL);
return TCL_ERROR;
}
return TCL_OK;
#else
- Tcl_SetResult(interp, "testmenubar is supported only under Unix",
- TCL_STATIC);
+ Tcl_AppendResult(interp, "testmenubar is supported only under Unix", NULL);
return TCL_ERROR;
#endif
}
@@ -1744,7 +1751,7 @@ TestmenubarCmd(
/*
*----------------------------------------------------------------------
*
- * TestmetricsCmd --
+ * TestmetricsObjCmd --
*
* This function implements the testmetrics command. It provides a way to
* determine the size of various widget components.
@@ -1758,53 +1765,51 @@ TestmenubarCmd(
*----------------------------------------------------------------------
*/
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
+#if defined(_WIN32) || defined(MAC_OSX_TK)
static int
-TestmetricsCmd(
+TestmetricsObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
char buf[TCL_INTEGER_SPACE];
int val;
-#ifdef __WIN32__
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option ?arg ...?\"", NULL);
+#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 (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " option window\"", NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "option window");
return TCL_ERROR;
}
- winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
+ winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
if (winPtr == NULL) {
return TCL_ERROR;
}
#endif
- if (strcmp(argv[1], "cyvscroll") == 0) {
-#ifdef __WIN32__
+ if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {
+#ifdef _WIN32
val = GetSystemMetrics(SM_CYVSCROLL);
#else
val = ((TkScrollbar *) winPtr->instanceData)->width;
#endif
- } else if (strcmp(argv[1], "cxhscroll") == 0) {
-#ifdef __WIN32__
+ } 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 \"", argv[1],
+ Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be cxhscroll or cyvscroll", NULL);
return TCL_ERROR;
}
@@ -1817,7 +1822,7 @@ TestmetricsCmd(
/*
*----------------------------------------------------------------------
*
- * TestpropCmd --
+ * TestpropObjCmd --
*
* This function implements the "testprop" command. It fetches and prints
* the value of a property on a window.
@@ -1833,11 +1838,11 @@ TestmetricsCmd(
/* ARGSUSED */
static int
-TestpropCmd(
+TestpropObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
Tk_Window mainWin = (Tk_Window) clientData;
int result, actualFormat;
@@ -1848,14 +1853,13 @@ TestpropCmd(
Window w;
char buffer[30];
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " window property\"", NULL);
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "window property");
return TCL_ERROR;
}
- w = strtoul(argv[1], &end, 0);
- propName = Tk_InternAtom(mainWin, argv[2]);
+ w = strtoul(Tcl_GetString(objv[1]), &end, 0);
+ propName = Tk_InternAtom(mainWin, Tcl_GetString(objv[2]));
property = NULL;
result = XGetWindowProperty(Tk_Display(mainWin),
w, propName, 0, 100000, False, AnyPropertyType,
@@ -1868,7 +1872,7 @@ TestpropCmd(
*p = '\n';
}
}
- Tcl_SetResult(interp, (/*!unsigned*/char*)property, TCL_VOLATILE);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj((/*!unsigned*/char*)property, -1));
} else {
for (p = property; length > 0; length--) {
if (actualFormat == 32) {
@@ -1892,11 +1896,11 @@ TestpropCmd(
return TCL_OK;
}
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
+#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
/*
*----------------------------------------------------------------------
*
- * TestwrapperCmd --
+ * TestwrapperObjCmd --
*
* This function implements the "testwrapper" command. It provides a way
* from Tcl to determine the extra window Tk adds in between the toplevel
@@ -1913,23 +1917,22 @@ TestpropCmd(
/* ARGSUSED */
static int
-TestwrapperCmd(
+TestwrapperObjCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
TkWindow *winPtr, *wrapperPtr;
Tk_Window tkwin;
- if (argc != 2) {
- Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0],
- " window\"", NULL);
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "window");
return TCL_ERROR;
}
tkwin = (Tk_Window) clientData;
- winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin);
+ winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[1]), tkwin);
if (winPtr == NULL) {
return TCL_ERROR;
}
@@ -1939,7 +1942,7 @@ TestwrapperCmd(
char buf[TCL_INTEGER_SPACE];
TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr));
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
}
return TCL_OK;
}
@@ -1982,7 +1985,7 @@ CustomOptionSet(
char *saveInternalPtr,
int flags)
{
- int objEmpty, length;
+ int objEmpty;
char *newStr, *string, *internalPtr;
objEmpty = 0;
@@ -2003,25 +2006,24 @@ CustomOptionSet(
} else if ((*value)->bytes != NULL) {
objEmpty = ((*value)->length == 0);
} else {
- Tcl_GetStringFromObj((*value), &length);
- objEmpty = (length == 0);
+ (void)Tcl_GetString(*value);
+ objEmpty = ((*value)->length == 0);
}
if ((flags & TK_OPTION_NULL_OK) && objEmpty) {
*value = NULL;
} else {
- string = Tcl_GetStringFromObj((*value), &length);
+ string = Tcl_GetString(*value);
Tcl_UtfToUpper(string);
if (strcmp(string, "BAD") == 0) {
- Tcl_SetResult(interp, "expected good value, got \"BAD\"",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("expected good value, got \"BAD\"", -1));
return TCL_ERROR;
}
}
if (internalPtr != NULL) {
- if ((*value) != NULL) {
- string = Tcl_GetStringFromObj((*value), &length);
- newStr = ckalloc(length + 1);
+ if (*value != NULL) {
+ string = Tcl_GetString(*value);
+ newStr = ckalloc((*value)->length + 1);
strcpy(newStr, string);
} else {
newStr = NULL;
diff --git a/generic/tkText.c b/generic/tkText.c
index e7b1c4d..3079417 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -211,18 +211,18 @@ static const Tk_OptionSpec optionSpecs[] = {
TK_OPTION_NULL_OK, DEF_TEXT_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr),
- TK_CONFIG_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, DEF_TEXT_SELECT_FG_MONO, 0},
{TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0},
{TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing",
DEF_TEXT_SPACING1, -1, Tk_Offset(TkText, spacing1),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
DEF_TEXT_SPACING3, -1, Tk_Offset(TkText, spacing3),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_CUSTOM, "-startline", NULL, NULL,
NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK,
&lineOption, TK_TEXT_LINE_RANGE},
@@ -402,6 +402,7 @@ static Tcl_Obj * TextGetText(const TkText *textPtr,
const TkTextIndex *index2, int visibleOnly);
static void GenerateModifiedEvent(TkText *textPtr);
static void UpdateDirtyFlag(TkSharedText *sharedPtr);
+static void RunAfterSyncCmd(ClientData clientData);
static void TextPushUndoAction(TkText *textPtr,
Tcl_Obj *undoString, int insert,
const TkTextIndex *index1Ptr,
@@ -580,14 +581,6 @@ CreateWidget(
textPtr->end = NULL;
}
- /*
- * Register with the B-tree. In some sense it would be best if we could do
- * this later (after configuration options), so that any changes to
- * start,end do not require a total recalculation.
- */
-
- TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight);
-
textPtr->state = TK_TEXT_STATE_NORMAL;
textPtr->relief = TK_RELIEF_FLAT;
textPtr->cursor = None;
@@ -598,6 +591,14 @@ CreateWidget(
textPtr->prevHeight = Tk_Height(newWin);
/*
+ * Register with the B-tree. In some sense it would be best if we could do
+ * this later (after configuration options), so that any changes to
+ * start,end do not require a total recalculation.
+ */
+
+ TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight);
+
+ /*
* This will add refCounts to textPtr.
*/
@@ -702,15 +703,16 @@ TextWidgetObjCmd(
static const char *const optionStrings[] = {
"bbox", "cget", "compare", "configure", "count", "debug", "delete",
"dlineinfo", "dump", "edit", "get", "image", "index", "insert",
- "mark", "peer", "replace", "scan", "search", "see", "tag", "window",
- "xview", "yview", NULL
+ "mark", "peer", "pendingsync", "replace", "scan", "search",
+ "see", "sync", "tag", "window", "xview", "yview", NULL
};
enum options {
TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT,
TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT,
TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK,
- TEXT_PEER, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE,
- TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW
+ TEXT_PEER, TEXT_PENDINGSYNC, TEXT_REPLACE, TEXT_SCAN,
+ TEXT_SEARCH, TEXT_SEE, TEXT_SYNC, TEXT_TAG, TEXT_WINDOW,
+ TEXT_XVIEW, TEXT_YVIEW
};
if (objc < 2) {
@@ -718,8 +720,8 @@ TextWidgetObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
textPtr->refCount++;
@@ -859,9 +861,10 @@ TextWidgetObjCmd(
for (i = 2; i < objc-2; i++) {
int value, length;
- const char *option = Tcl_GetStringFromObj(objv[i], &length);
+ const char *option = Tcl_GetString(objv[i]);
char c;
+ length = objv[i]->length;
if (length < 2 || option[0] != '-') {
goto badOption;
}
@@ -880,7 +883,7 @@ TextWidgetObjCmd(
} else if (c == 'd' && (length > 8)
&& !strncmp("-displaylines", option, (unsigned) length)) {
TkTextLine *fromPtr, *lastPtr;
- TkTextIndex index;
+ TkTextIndex index, index2;
int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
value = 0;
@@ -915,35 +918,44 @@ 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', and then subtract off what we didn't
- * want from 'from' and add on what we didn't count from 'to.
+ * 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
+ * on what we didn't count from 'to'.
*/
- while (index.linePtr != indexToPtr->linePtr) {
- value += TkTextUpdateOneLine(textPtr, fromPtr,0,&index,0);
-
- /*
- * We might have skipped past indexToPtr, if we have
- * multiple logical lines in a single display line.
- */
- if (TkTextIndexCmp(&index,indexToPtr) > 0) {
- break;
- }
+ while (TkTextIndexCmp(&index,indexToPtr) < 0) {
+ value += TkTextUpdateOneLine(textPtr, index.linePtr,
+ 0, &index, 0);
}
- /*
- * Now we need to adjust the count to add on the number of
- * display lines in the last logical line, and subtract off
- * the number of display lines overcounted in the first
- * logical line. This logic is still ok if both indices are in
- * the same logical line.
- */
+ 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 (index.byteIndex >= indexFromPtr->byteIndex) {
+ if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -955,7 +967,7 @@ TextWidgetObjCmd(
index.byteIndex = 0;
while (1) {
TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
- if (index.byteIndex >= indexToPtr->byteIndex) {
+ if (TkTextIndexCmp(&index,indexToPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -1260,12 +1272,14 @@ TextWidgetObjCmd(
i = 2;
if (objc > 3) {
- name = Tcl_GetStringFromObj(objv[i], &length);
+ name = Tcl_GetString(objv[i]);
+ length = objv[i]->length;
if (length > 1 && name[0] == '-') {
if (strncmp("-displaychars", name, (unsigned) length) == 0) {
i++;
visible = 1;
- name = Tcl_GetStringFromObj(objv[i], &length);
+ name = Tcl_GetString(objv[i]);
+ length = objv[i]->length;
}
if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
i++;
@@ -1380,6 +1394,16 @@ TextWidgetObjCmd(
case TEXT_PEER:
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;
+ }
case TEXT_REPLACE: {
const TkTextIndex *indexFromPtr, *indexToPtr;
@@ -1494,6 +1518,39 @@ TextWidgetObjCmd(
case TEXT_SEE:
result = TkTextSeeCmd(textPtr, interp, objc, objv);
break;
+ case TEXT_SYNC: {
+ if (objc == 4) {
+ Tcl_Obj *cmd = objv[3];
+ const char *option = Tcl_GetString(objv[2]);
+ if (strncmp(option, "-command", objv[2]->length)) {
+ Tcl_AppendResult(interp, "wrong option \"", option, "\": should be \"-command\"", NULL);
+ result = TCL_ERROR;
+ goto done;
+ }
+ Tcl_IncrRefCount(cmd);
+ if (TkTextPendingsync(textPtr)) {
+ if (textPtr->afterSyncCmd) {
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ }
+ textPtr->afterSyncCmd = cmd;
+ } else {
+ textPtr->afterSyncCmd = cmd;
+ Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr);
+ }
+ break;
+ } else if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-command command?");
+ result = TCL_ERROR;
+ goto done;
+ }
+ if (textPtr->afterSyncCmd) {
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ }
+ textPtr->afterSyncCmd = NULL;
+ TkTextUpdateLineMetrics(textPtr, 1,
+ TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1);
+ break;
+ }
case TEXT_TAG:
result = TkTextTagCmd(textPtr, interp, objc, objv);
break;
@@ -1559,8 +1616,8 @@ SharedTextObjCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -1664,8 +1721,8 @@ TextPeerCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], peerOptionStrings,
- "peer option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], peerOptionStrings,
+ sizeof(char *), "peer option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -1983,6 +2040,10 @@ 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) {
ckfree(textPtr);
}
@@ -2332,6 +2393,7 @@ TextWorldChanged(
{
Tk_FontMetrics fm;
int border;
+ int oldCharHeight = textPtr->charHeight;
textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1);
if (textPtr->charWidth <= 0) {
@@ -2343,6 +2405,9 @@ TextWorldChanged(
if (textPtr->charHeight <= 0) {
textPtr->charHeight = 1;
}
+ if (textPtr->charHeight != oldCharHeight) {
+ TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
+ }
border = textPtr->borderWidth + textPtr->highlightWidth;
Tk_GeometryRequest(textPtr->tkwin,
textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border,
@@ -2552,9 +2617,9 @@ InsertChars(
int *lineAndByteIndex;
int resetViewCount;
int pixels[2*PIXEL_CLIENTS];
+ const char *string = Tcl_GetString(stringPtr);
- const char *string = Tcl_GetStringFromObj(stringPtr, &length);
-
+ length = stringPtr->length;
if (sharedTextPtr == NULL) {
sharedTextPtr = textPtr->sharedTextPtr;
}
@@ -3010,11 +3075,9 @@ 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. If there is a newline just before the first
- * character being deleted, then back up the first index too, so that an
- * even number of lines gets deleted. 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
+ * 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.
*/
@@ -3029,10 +3092,6 @@ 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++) {
@@ -3713,15 +3772,15 @@ TextSearchCmd(
break;
}
- if (Tcl_GetIndexFromObj(NULL, objv[i], switchStrings, "switch", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(NULL, objv[i], switchStrings,
+ sizeof(char *), "switch", 0, &index) != TCL_OK) {
/*
* Hide the -hidden option, generating the error description with
* the side effects of T_GIFO.
*/
- (void) Tcl_GetIndexFromObj(interp, objv[i], switchStrings+1,
- "switch", 0, &index);
+ (void) Tcl_GetIndexFromObjStruct(interp, objv[i], switchStrings+1,
+ sizeof(char *), "switch", 0, &index);
return TCL_ERROR;
}
@@ -4093,7 +4152,8 @@ TextSearchAddNextLine(
if (lenPtr != NULL) {
if (searchSpecPtr->exact) {
- Tcl_GetStringFromObj(theLine, lenPtr);
+ (void)Tcl_GetString(theLine);
+ *lenPtr = theLine->length;
} else {
*lenPtr = Tcl_GetCharLength(theLine);
}
@@ -4227,7 +4287,11 @@ TextSearchFoundMatch(
matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1);
}
} else {
- leftToScan -= segPtr->size;
+ if (searchSpecPtr->exact) {
+ leftToScan -= segPtr->size;
+ } else {
+ leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1);
+ }
}
curIndex.byteIndex += segPtr->size;
}
@@ -4482,8 +4546,8 @@ TkTextGetTabs(
}
i += 1;
- if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings,
- "tab alignment", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], tabOptionStrings,
+ sizeof(char *), "tab alignment", 0, &index) != TCL_OK) {
goto error;
}
tabPtr->alignment = (TkTextTabAlign) index;
@@ -4560,8 +4624,8 @@ TextDumpCmd(
if (Tcl_GetString(objv[arg])[0] != '-') {
break;
}
- if (Tcl_GetIndexFromObj(interp, objv[arg], optStrings, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[arg], optStrings,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum opts) index) {
@@ -4619,7 +4683,8 @@ TextDumpCmd(
if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
return TCL_ERROR;
}
- str = Tcl_GetStringFromObj(objv[arg], &length);
+ str = Tcl_GetString(objv[arg]);
+ length = objv[arg]->length;
if (strncmp(str, "end", (unsigned) length) == 0) {
atEnd = 1;
}
@@ -4936,9 +5001,20 @@ DumpSegment(
return 0;
} else {
int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
-
- Tcl_VarEval(interp, Tcl_GetString(command), " ", Tcl_GetString(tuple),
- NULL);
+ Tcl_DString buf;
+ int code;
+
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, Tcl_GetString(command), -1);
+ Tcl_DStringAppend(&buf, " ", -1);
+ Tcl_DStringAppend(&buf, Tcl_GetString(tuple), -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
+ if (code != TCL_OK) {
+ Tcl_AddErrorInfo(interp,
+ "\n (segment dumping command executed by text)");
+ Tcl_BackgroundException(interp, code);
+ }
Tcl_DecrRefCount(tuple);
return ((textPtr->flags & DESTROYED) ||
TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch);
@@ -5077,8 +5153,8 @@ TextEditCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings,
- "edit option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], editOptionStrings,
+ sizeof(char *), "edit option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -5341,6 +5417,52 @@ UpdateDirtyFlag(
/*
*----------------------------------------------------------------------
*
+ * RunAfterSyncCmd --
+ *
+ * This function is called by the event loop and executes the command
+ * scheduled by [.text sync -command $cmd].
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Anything may happen, depending on $cmd contents.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RunAfterSyncCmd(
+ ClientData clientData) /* Information about text widget. */
+{
+ register TkText *textPtr = (TkText *) clientData;
+ int code;
+
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
+ /*
+ * The widget has been deleted. Don't do anything.
+ */
+
+ if (--textPtr->refCount == 0) {
+ 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_Release((ClientData) textPtr->interp);
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* SearchPerform --
*
* Overall control of search process. Is given a pattern, a starting
@@ -5541,7 +5663,8 @@ SearchCore(
* it has dual purpose.
*/
- pattern = Tcl_GetStringFromObj(patObj, &matchLength);
+ pattern = Tcl_GetString(patObj);
+ matchLength = patObj->length;
nl = strchr(pattern, '\n');
/*
@@ -6609,16 +6732,14 @@ 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);
}
- Tcl_GetStringFromObj(objPtr, &length);
- return (length == 0);
+ (void)Tcl_GetString(objPtr);
+ return (objPtr->length == 0);
}
/*
@@ -6643,8 +6764,8 @@ int
TkpTesttextCmd(
ClientData clientData, /* Main window for application. */
Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- const char **argv) /* Argument strings. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument strings. */
{
TkText *textPtr;
size_t len;
@@ -6653,45 +6774,41 @@ TkpTesttextCmd(
char buf[64];
Tcl_CmdInfo info;
- if (argc < 3) {
+ if (objc < 3) {
return TCL_ERROR;
}
- if (Tcl_GetCommandInfo(interp, argv[1], &info) == 0) {
+ if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) == 0) {
return TCL_ERROR;
}
- if (info.isNativeObjectProc) {
- textPtr = info.objClientData;
- } else {
- textPtr = info.clientData;
- }
- len = strlen(argv[2]);
- if (strncmp(argv[2], "byteindex", len) == 0) {
- if (argc != 5) {
+ textPtr = info.objClientData;
+ len = strlen(Tcl_GetString(objv[2]));
+ if (strncmp(Tcl_GetString(objv[2]), "byteindex", len) == 0) {
+ if (objc != 5) {
return TCL_ERROR;
}
- lineIndex = atoi(argv[3]) - 1;
- byteIndex = atoi(argv[4]);
+ lineIndex = atoi(Tcl_GetString(objv[3])) - 1;
+ byteIndex = atoi(Tcl_GetString(objv[4]));
TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineIndex,
byteIndex, &index);
- } else if (strncmp(argv[2], "forwbytes", len) == 0) {
- if (argc != 5) {
+ } else if (strncmp(Tcl_GetString(objv[2]), "forwbytes", len) == 0) {
+ if (objc != 5) {
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) {
return TCL_ERROR;
}
- byteOffset = atoi(argv[4]);
+ byteOffset = atoi(Tcl_GetString(objv[4]));
TkTextIndexForwBytes(textPtr, &index, byteOffset, &index);
- } else if (strncmp(argv[2], "backbytes", len) == 0) {
- if (argc != 5) {
+ } else if (strncmp(Tcl_GetString(objv[2]), "backbytes", len) == 0) {
+ if (objc != 5) {
return TCL_ERROR;
}
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
+ if (TkTextGetIndex(interp, textPtr, Tcl_GetString(objv[3]), &index) != TCL_OK) {
return TCL_ERROR;
}
- byteOffset = atoi(argv[4]);
+ byteOffset = atoi(Tcl_GetString(objv[4]));
TkTextIndexBackBytes(textPtr, &index, byteOffset, &index);
} else {
return TCL_ERROR;
diff --git a/generic/tkText.h b/generic/tkText.h
index fb9eab2..fc92644 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -168,7 +168,7 @@ typedef struct TkTextSegment {
int size; /* Size of this segment (# of bytes of index
* space it occupies). */
union {
- char chars[1]; /* Characters that make up character info.
+ char chars[2]; /* Characters that make up character info.
* Actual length varies to hold as many
* characters as needed.*/
TkTextToggle toggle; /* Information about tag toggle. */
@@ -785,6 +785,8 @@ typedef struct TkText {
* statements. */
int autoSeparators; /* Non-zero means the separators will be
* inserted automatically. */
+ Tcl_Obj *afterSyncCmd; /* Command to be executed when lines are up to
+ * date */
} TkText;
/*
@@ -1066,6 +1068,9 @@ MODULE_SCOPE void TkTextIndexBackChars(const TkText *textPtr,
TkTextIndex *dstPtr, TkTextCountType type);
MODULE_SCOPE int TkTextIndexCmp(const TkTextIndex *index1Ptr,
const TkTextIndex *index2Ptr);
+MODULE_SCOPE int TkTextIndexCountBytes(const TkText *textPtr,
+ const TkTextIndex *index1Ptr,
+ const TkTextIndex *index2Ptr);
MODULE_SCOPE int TkTextIndexCount(const TkText *textPtr,
const TkTextIndex *index1Ptr,
const TkTextIndex *index2Ptr,
@@ -1106,6 +1111,7 @@ MODULE_SCOPE int TkTextMarkNameToIndex(TkText *textPtr,
MODULE_SCOPE void TkTextMarkSegToIndex(TkText *textPtr,
TkTextSegment *markPtr, TkTextIndex *indexPtr);
MODULE_SCOPE void TkTextEventuallyRepick(TkText *textPtr);
+MODULE_SCOPE Bool TkTextPendingsync(TkText *textPtr);
MODULE_SCOPE void TkTextPickCurrent(TkText *textPtr, XEvent *eventPtr);
MODULE_SCOPE void TkTextPixelIndex(TkText *textPtr, int x, int y,
TkTextIndex *indexPtr, int *nearest);
diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c
index e34dae7..0fdc280 100644
--- a/generic/tkTextBTree.c
+++ b/generic/tkTextBTree.c
@@ -1112,7 +1112,7 @@ TkBTreeInsertChars(
/*
* I don't believe it's possible for either of the two lines passed to
* this function to be the last line of text, but the function is robust
- * to that case anyway. (We must never re-calculated the line height of
+ * to that case anyway. (We must never re-calculate the line height of
* the last line).
*/
@@ -1879,8 +1879,7 @@ TkBTreePreviousLine(
* number of pixels in the widget.
*
* Results:
- * The result is the index of linePtr within the tree, where 0
- * corresponds to the first line in the tree.
+ * The result is the pixel height of the top of the given line.
*
* Side effects:
* None.
@@ -1989,7 +1988,7 @@ TkBTreeLinesTo(
}
}
if (textPtr != NULL) {
- /*
+ /*
* The index to return must be relative to textPtr, not to the entire
* tree. Take care to never return a negative index when linePtr
* denotes a line before -startline, or an index larger than the
@@ -3616,20 +3615,6 @@ TkTextIsElided(
infoPtr->elidePriority = -1;
for (i = infoPtr->numTags-1; i >=0; i--) {
if (infoPtr->tagCnts[i] & 1) {
- /*
- * Who would make the selection elided?
- */
-
- if ((tagPtr == textPtr->selTagPtr)
- && !(textPtr->flags & GOT_FOCUS)
- && (textPtr->inactiveSelBorder == NULL
-#ifdef MAC_OSX_TK
- /* Don't show inactive selection in disabled widgets. */
- || textPtr->state == TK_TEXT_STATE_DISABLED
-#endif
- )) {
- continue;
- }
infoPtr->elide = infoPtr->tagPtrs[i]->elide;
/*
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index d75f61c..1eea37d 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -16,7 +16,7 @@
#include "tkInt.h"
#include "tkText.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
@@ -243,7 +243,8 @@ typedef struct DLine {
* top to bottom. Note: the next DLine doesn't
* always correspond to the next line of text:
* (a) can have multiple DLines for one text
- * line, and (b) can have gaps where DLine's
+ * line (wrapping), (b) can have elided newlines,
+ * and (c) can have gaps where DLine's
* have been deleted because they're out of
* date. */
int flags; /* Various flag bits: see below for values. */
@@ -543,7 +544,8 @@ static void DisplayDLine(TkText *textPtr, DLine *dlPtr,
static void DisplayLineBackground(TkText *textPtr, DLine *dlPtr,
DLine *prevPtr, Pixmap pixmap);
static void DisplayText(ClientData clientData);
-static DLine * FindDLine(DLine *dlPtr, const TkTextIndex *indexPtr);
+static DLine * FindDLine(TkText *textPtr, DLine *dlPtr,
+ const TkTextIndex *indexPtr);
static void FreeDLines(TkText *textPtr, DLine *firstPtr,
DLine *lastPtr, int action);
static void FreeStyle(TkText *textPtr, TextStyle *stylePtr);
@@ -589,7 +591,10 @@ static int TextGetScrollInfoObj(Tcl_Interp *interp,
Tcl_Obj *const objv[], double *dblPtr,
int *intPtr);
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);
/*
* Result values returned by TextGetScrollInfoObj:
@@ -655,17 +660,8 @@ TkTextCreateDInfo(
dInfoPtr->metricEpoch = -1;
dInfoPtr->metricIndex.textPtr = NULL;
dInfoPtr->metricIndex.linePtr = NULL;
-
- /*
- * Add a refCount for each of the idle call-backs.
- */
-
- textPtr->refCount++;
- dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(0,
- AsyncUpdateLineMetrics, textPtr);
- textPtr->refCount++;
- dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200,
- AsyncUpdateYScrollbar, textPtr);
+ dInfoPtr->lineUpdateTimer = NULL;
+ dInfoPtr->scrollbarTimer = NULL;
textPtr->dInfoPtr = dInfoPtr;
}
@@ -1020,7 +1016,7 @@ FreeStyle(
* whose leftmost character is given by indexPtr.
*
* Results:
- * The return value is a pointer to a DLine structure desribing the
+ * The return value is a pointer to a DLine structure describing the
* display line. All fields are filled in and correct except for y and
* nextPtr.
*
@@ -1644,7 +1640,7 @@ LayoutDLine(
* Make one more pass over the line to recompute various things like its
* height, length, and total number of bytes. Also modify the x-locations
* of chunks to reflect justification. If we're not wrapping, I'm not sure
- * what is the best way to handle left and center justification: should
+ * what is the best way to handle right and center justification: should
* the total length, for purposes of justification, be (a) the window
* width, (b) the length of the longest line in the window, or (c) the
* length of the longest line in the text? (c) isn't available, (b) seems
@@ -1759,7 +1755,7 @@ UpdateDisplayInfo(
*/
index = textPtr->topIndex;
- dlPtr = FindDLine(dInfoPtr->dLinePtr, &index);
+ dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, &index);
if ((dlPtr != NULL) && (dlPtr != dInfoPtr->dLinePtr)) {
FreeDLines(textPtr, dInfoPtr->dLinePtr, dlPtr, DLINE_UNLINK);
}
@@ -1909,7 +1905,7 @@ UpdateDisplayInfo(
prevPtr->index.linePtr) != lineHeight)) {
/*
* The logical line height we just calculated is actually
- * differnt to the currently cached height of the text line.
+ * different to the currently cached height of the text line.
* That is fine (the text line heights are only calculated
* asynchronously), but we must update the cached height so
* that any counts made with DLine pointers are the same as
@@ -2222,7 +2218,7 @@ UpdateDisplayInfo(
* Here's a problem: see the tests textDisp-29.2.1-4
*
* If the widget is being created, but has not yet been configured it will
- * have a maxY of 1 above, and we we won't have examined all the lines
+ * have a maxY of 1 above, and we won't have examined all the lines
* (just the first line, in fact), and so maxOffset will not be a true
* reflection of the widget's lines. Therefore we must not overwrite the
* original newXPixelOffset in this case.
@@ -2537,7 +2533,7 @@ DisplayLineBackground(
* current x coordinate? */
int matchRight; /* Does line's style match its neighbor just
* to the right of the current x-coord? */
- int minX, maxX, xOffset;
+ int minX, maxX, xOffset, bw;
StyleValues *sValuePtr;
Display *display;
#ifndef TK_NO_DOUBLE_BUFFERING
@@ -2608,16 +2604,25 @@ DisplayLineBackground(
rightX = leftX + 32767;
}
+ /*
+ * Prevent the borders from leaking on adjacent characters,
+ * which would happen for too large border width.
+ */
+
+ bw = sValuePtr->borderWidth;
+ if (leftX + sValuePtr->borderWidth > rightX) {
+ bw = rightX - leftX;
+ }
+
XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC,
leftX + xOffset, y, (unsigned int) (rightX - leftX),
(unsigned int) dlPtr->height);
if (sValuePtr->relief != TK_RELIEF_FLAT) {
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- leftX + xOffset, y, sValuePtr->borderWidth,
- dlPtr->height, 1, sValuePtr->relief);
+ leftX + xOffset, y, bw, dlPtr->height, 1,
+ sValuePtr->relief);
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- rightX - sValuePtr->borderWidth + xOffset,
- y, sValuePtr->borderWidth, dlPtr->height, 0,
+ rightX - bw + xOffset, y, bw, dlPtr->height, 0,
sValuePtr->relief);
}
}
@@ -2714,22 +2719,29 @@ DisplayLineBackground(
matchRight = (nextPtr2 != NULL)
&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
if (matchLeft && !matchRight) {
+ bw = sValuePtr->borderWidth;
+ if (rightX2 - sValuePtr->borderWidth < leftX) {
+ bw = rightX2 - leftX;
+ }
if (sValuePtr->relief != TK_RELIEF_FLAT) {
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- rightX2 - sValuePtr->borderWidth + xOffset, y,
- sValuePtr->borderWidth, sValuePtr->borderWidth, 0,
- sValuePtr->relief);
+ rightX2 - bw + xOffset, y, bw,
+ sValuePtr->borderWidth, 0, sValuePtr->relief);
}
- leftX = rightX2 - sValuePtr->borderWidth;
+ leftX = rightX2 - bw;
leftXIn = 0;
} else if (!matchLeft && matchRight
&& (sValuePtr->relief != TK_RELIEF_FLAT)) {
+ bw = sValuePtr->borderWidth;
+ if (rightX2 + sValuePtr->borderWidth > rightX) {
+ bw = rightX - rightX2;
+ }
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- rightX2 + xOffset, y, sValuePtr->borderWidth,
- sValuePtr->borderWidth, 1, sValuePtr->relief);
+ rightX2 + xOffset, y, bw, sValuePtr->borderWidth,
+ 1, sValuePtr->relief);
Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- leftX + xOffset, y, rightX2 + sValuePtr->borderWidth -
- leftX, sValuePtr->borderWidth, leftXIn, 0, 1,
+ leftX + xOffset, y, rightX2 + bw - leftX,
+ sValuePtr->borderWidth, leftXIn, 0, 1,
sValuePtr->relief);
}
@@ -2761,7 +2773,7 @@ DisplayLineBackground(
chunkPtr2 = NULL;
if (dlPtr->nextPtr != NULL && dlPtr->nextPtr->chunkPtr != NULL) {
/*
- * Find the chunk in the previous line that covers leftX.
+ * Find the chunk in the next line that covers leftX.
*/
nextPtr2 = dlPtr->nextPtr->chunkPtr;
@@ -2817,26 +2829,33 @@ DisplayLineBackground(
matchRight = (nextPtr2 != NULL)
&& SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr);
if (matchLeft && !matchRight) {
+ bw = sValuePtr->borderWidth;
+ if (rightX2 - sValuePtr->borderWidth < leftX) {
+ bw = rightX2 - leftX;
+ }
if (sValuePtr->relief != TK_RELIEF_FLAT) {
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- rightX2 - sValuePtr->borderWidth + xOffset,
+ rightX2 - bw + xOffset,
y + dlPtr->height - sValuePtr->borderWidth,
- sValuePtr->borderWidth, sValuePtr->borderWidth, 0,
- sValuePtr->relief);
+ bw, sValuePtr->borderWidth, 0, sValuePtr->relief);
}
- leftX = rightX2 - sValuePtr->borderWidth;
+ leftX = rightX2 - bw;
leftXIn = 1;
} else if (!matchLeft && matchRight
&& (sValuePtr->relief != TK_RELIEF_FLAT)) {
+ bw = sValuePtr->borderWidth;
+ if (rightX2 + sValuePtr->borderWidth > rightX) {
+ bw = rightX - rightX2;
+ }
Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- rightX2 + xOffset, y + dlPtr->height -
- sValuePtr->borderWidth, sValuePtr->borderWidth,
+ rightX2 + xOffset,
+ y + dlPtr->height - sValuePtr->borderWidth, bw,
sValuePtr->borderWidth, 1, sValuePtr->relief);
Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border,
- leftX + xOffset, y + dlPtr->height -
- sValuePtr->borderWidth, rightX2 + sValuePtr->borderWidth -
- leftX, sValuePtr->borderWidth, leftXIn, 1, 0,
- sValuePtr->relief);
+ leftX + xOffset,
+ y + dlPtr->height - sValuePtr->borderWidth,
+ rightX2 + bw - leftX, sValuePtr->borderWidth, leftXIn,
+ 1, 0, sValuePtr->relief);
}
nextChunk2b:
@@ -2886,9 +2905,10 @@ AsyncUpdateLineMetrics(
dInfoPtr->lineUpdateTimer = NULL;
- if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)
+ || !Tk_IsMapped(textPtr->tkwin)) {
/*
- * The widget has been deleted. Don't do anything.
+ * The widget has been deleted, or is not mapped. Don't do anything.
*/
if (--textPtr->refCount == 0) {
@@ -2922,6 +2942,8 @@ AsyncUpdateLineMetrics(
lineNum = TkTextUpdateLineMetrics(textPtr, lineNum,
dInfoPtr->lastMetricUpdateLine, 256);
+ dInfoPtr->currentMetricUpdateLine = lineNum;
+
if (tkTextDebug) {
char buffer[2 * TCL_INTEGER_SPACE + 1];
@@ -2939,16 +2961,37 @@ AsyncUpdateLineMetrics(
/*
* We have looped over all lines, so we're done. We must release our
* refCount on the widget (the timer token was already set to NULL
- * above).
+ * above). If there is a registered aftersync command, run that first.
*/
+ if (textPtr->afterSyncCmd) {
+ int code;
+ 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_Release((ClientData) textPtr->interp);
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
+ }
+
+ /*
+ * Fire the <<WidgetViewSync>> event since the widget view is in sync
+ * with its internal data (actually it will be after the next trip
+ * through the event loop, because the widget redraws at idle-time).
+ */
+
+ GenerateWidgetViewSyncEvent(textPtr, 1);
+
textPtr->refCount--;
if (textPtr->refCount == 0) {
ckfree(textPtr);
}
return;
}
- dInfoPtr->currentMetricUpdateLine = lineNum;
/*
* Re-arm the timer. We already have a refCount on the text widget so no
@@ -2962,6 +3005,45 @@ AsyncUpdateLineMetrics(
/*
*----------------------------------------------------------------------
*
+ * GenerateWidgetViewSyncEvent --
+ *
+ * Send the <<WidgetViewSync>> event related to the text widget
+ * line metrics asynchronous update.
+ * This is equivalent to:
+ * event generate $textWidget <<WidgetViewSync>> -detail $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).
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * If corresponding bindings are present, they will trigger.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateWidgetViewSyncEvent(
+ TkText *textPtr, /* Information about text widget. */
+ 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);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkTextUpdateLineMetrics --
*
* This function updates the pixel height calculations of a range of
@@ -3334,6 +3416,7 @@ TextInvalidateLineMetrics(
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
AsyncUpdateLineMetrics, textPtr);
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
}
@@ -3385,7 +3468,7 @@ TkTextFindDisplayLineEnd(
{
TkTextIndex index;
- if (!end && indexPtr->byteIndex == 0) {
+ if (!end && IsStartOfNotMergedLine(textPtr, indexPtr)) {
/*
* Nothing to do.
*/
@@ -3463,7 +3546,8 @@ TkTextFindDisplayLineEnd(
*/
*xOffset = DlineXOfIndex(textPtr, dlPtr,
- indexPtr->byteIndex - dlPtr->index.byteIndex);
+ TkTextIndexCountBytes(textPtr, &dlPtr->index,
+ indexPtr));
}
if (end) {
/*
@@ -3533,6 +3617,27 @@ CalculateDisplayLineHeight(
DLine *dlPtr;
int pixelHeight;
+ if (tkTextDebug) {
+ int oldtkTextDebug = tkTextDebug;
+ /*
+ * Check that the indexPtr we are given really is at the start of a
+ * display line. The gymnastics with tkTextDebug is to prevent
+ * failure of a test suite test, that checks that lines are rendered
+ * exactly once. TkTextFindDisplayLineEnd is used here for checking
+ * indexPtr but it calls LayoutDLine/FreeDLine which makes the
+ * counting wrong. The debug mode shall therefore be switched off
+ * when calling TkTextFindDisplayLineEnd.
+ */
+
+ TkTextIndex indexPtr2 = *indexPtr;
+ tkTextDebug = 0;
+ TkTextFindDisplayLineEnd(textPtr, &indexPtr2, 0, NULL);
+ tkTextDebug = oldtkTextDebug;
+ if (TkTextIndexCmp(&indexPtr2,indexPtr) != 0) {
+ Tcl_Panic("CalculateDisplayLineHeight called with bad indexPtr");
+ }
+ }
+
/*
* Special case for artificial last line. May be better to move this
* inside LayoutDLine.
@@ -3599,26 +3704,44 @@ TkTextIndexYPixels(
{
int pixelHeight;
TkTextIndex index;
+ int alreadyStartOfLine = 1;
+
+ /*
+ * Find the index denoting the closest position being at the same time
+ * the start of a logical line above indexPtr and the start of a display
+ * line.
+ */
- pixelHeight = TkBTreePixelsTo(textPtr, indexPtr->linePtr);
+ index = *indexPtr;
+ while (1) {
+ TkTextFindDisplayLineEnd(textPtr, &index, 0, NULL);
+ if (index.byteIndex == 0) {
+ break;
+ }
+ TkTextIndexBackBytes(textPtr, &index, 1, &index);
+ alreadyStartOfLine = 0;
+ }
+
+ pixelHeight = TkBTreePixelsTo(textPtr, index.linePtr);
/*
- * Iterate through all display-lines corresponding to the single logical
- * line belonging to indexPtr, adding up the pixel height of each such
- * display line as we go along, until we go past 'indexPtr'.
+ * Shortcut to avoid layout of a superfluous display line. We know there
+ * is nothing more to add up to the height if the index we were given was
+ * already on the first display line of a logical line.
*/
- if (indexPtr->byteIndex == 0) {
- return pixelHeight;
+ if (alreadyStartOfLine) {
+ return pixelHeight;
}
- index.tree = textPtr->sharedTextPtr->tree;
- index.linePtr = indexPtr->linePtr;
- index.byteIndex = 0;
- index.textPtr = NULL;
+ /*
+ * Iterate through display lines, starting at the logical line belonging
+ * to index, adding up the pixel height of each such display line as we
+ * go along, until we go past 'indexPtr'.
+ */
while (1) {
- int bytes, height;
+ int bytes, height, compare;
/*
* Currently this call doesn't have many side-effects. However, if in
@@ -3630,9 +3753,10 @@ TkTextIndexYPixels(
height = CalculateDisplayLineHeight(textPtr, &index, &bytes, NULL);
- index.byteIndex += bytes;
+ TkTextIndexForwBytes(textPtr, &index, bytes, &index);
- if (index.byteIndex > indexPtr->byteIndex) {
+ compare = TkTextIndexCmp(&index,indexPtr);
+ if (compare > 0) {
return pixelHeight;
}
@@ -3640,7 +3764,7 @@ TkTextIndexYPixels(
pixelHeight += height;
}
- if (index.byteIndex == indexPtr->byteIndex) {
+ if (compare == 0) {
return pixelHeight;
}
}
@@ -3704,10 +3828,26 @@ TkTextUpdateOneLine(
}
/*
+ * CalculateDisplayLineHeight _must_ be called (below) with an index at
+ * the beginning of a display line. Force this to happen. This is needed
+ * when TkTextUpdateOneLine is called with a line that is merged with its
+ * previous line: the number of merged logical lines in a display line is
+ * calculated correctly only when CalculateDisplayLineHeight receives
+ * an index at the beginning of a display line. In turn this causes the
+ * merged lines to receive their correct zero pixel height in
+ * TkBTreeAdjustPixelHeight.
+ */
+
+ TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL);
+ linePtr = indexPtr->linePtr;
+
+ /*
* Iterate through all display-lines corresponding to the single logical
- * line 'linePtr', adding up the pixel height of each such display line as
- * we go along. The final total is, therefore, the height of the logical
- * line.
+ * line 'linePtr' (and lines merged into this line due to eol elision),
+ * adding up the pixel height of each such display line as we go along.
+ * The final total is, therefore, the total height of all display lines
+ * made up by the logical line 'linePtr' and subsequent logical lines
+ * merged into this line.
*/
displayLines = 0;
@@ -3724,7 +3864,7 @@ TkTextUpdateOneLine(
* test below this while loop.
*/
- height = CalculateDisplayLineHeight(textPtr, indexPtr, &bytes,
+ height = CalculateDisplayLineHeight(textPtr, indexPtr, &bytes,
&logicalLines);
if (height > 0) {
@@ -3738,44 +3878,31 @@ TkTextUpdateOneLine(
break;
}
- if (logicalLines == 0) {
- if (indexPtr->linePtr != linePtr) {
- /*
- * If we reached the end of the logical line, then either way
- * we don't have a partial calculation.
- */
+ if (mergedLines == 0) {
+ if (indexPtr->linePtr != linePtr) {
+ /*
+ * If we reached the end of the logical line, then either way
+ * we don't have a partial calculation.
+ */
- partialCalc = 0;
- break;
- }
- } else if (indexPtr->byteIndex != 0) {
- /*
- * We must still be on the same wrapped line.
- */
- } else {
- /*
- * Must check if indexPtr is really a new logical line which is
- * not merged with the previous line. The only code that would
- * really know this is LayoutDLine, which doesn't pass the
- * information on, so we have to check manually here.
- */
-
- TkTextIndex idx;
-
- TkTextIndexBackChars(textPtr, indexPtr, 1, &idx, COUNT_INDICES);
- if (!TkTextIsElided(textPtr, &idx, NULL)) {
- /*
- * We've ended a logical line.
- */
-
- partialCalc = 0;
- break;
- }
+ partialCalc = 0;
+ break;
+ }
+ } else {
+ if (IsStartOfNotMergedLine(textPtr, indexPtr)) {
+ /*
+ * We've ended a logical line.
+ */
+
+ partialCalc = 0;
+ break;
+ }
- /*
- * We must still be on the same wrapped line.
- */
- }
+ /*
+ * We must still be on the same wrapped line, on a new logical
+ * line merged with the logical line 'linePtr'.
+ */
+ }
if (partialCalc && displayLines > 50 && mergedLines == 0) {
/*
* Only calculate 50 display lines at a time, to avoid huge
@@ -3900,6 +4027,19 @@ DisplayText(
* warnings. */
Tcl_Interp *interp;
+#ifdef MAC_OSX_TK
+ /*
+ * If drawing is disabled, all we need to do is
+ * clear the REDRAW_PENDING flag.
+ */
+ TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
+ MacDrawable *macWin = winPtr->privatePtr;
+ if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
+ dInfoPtr->flags &= ~REDRAW_PENDING;
+ return;
+ }
+#endif
+
if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
/*
* The widget has been deleted. Don't do anything.
@@ -3915,14 +4055,6 @@ DisplayText(
Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
}
- if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
- /*
- * The widget has been deleted. Don't do anything.
- */
-
- goto end;
- }
-
if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
|| (dInfoPtr->maxY <= dInfoPtr->y)) {
UpdateDisplayInfo(textPtr);
@@ -3934,14 +4066,6 @@ DisplayText(
Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY);
}
- if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
- /*
- * The widget has been deleted. Don't do anything.
- */
-
- goto end;
- }
-
/*
* Choose a new current item if that is needed (this could cause event
* handlers to be invoked, hence the preserve/release calls and the loop,
@@ -4035,7 +4159,7 @@ DisplayText(
*/
if ((y + height) > dInfoPtr->maxY) {
- height = dInfoPtr->maxY -y;
+ height = dInfoPtr->maxY - y;
}
oldY = dlPtr->oldY;
if (y < dInfoPtr->y) {
@@ -4091,6 +4215,7 @@ DisplayText(
oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
damageRgn)) {
TextInvalidateRegion(textPtr, damageRgn);
+
}
numCopies++;
TkDestroyRegion(damageRgn);
@@ -4539,6 +4664,8 @@ TextChanged(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *firstPtr, *lastPtr;
TkTextIndex rounded;
+ TkTextLine *linePtr;
+ int notBegin;
/*
* Schedule both a redisplay and a recomputation of display information.
@@ -4564,23 +4691,78 @@ TextChanged(
/*
* Find the DLines corresponding to index1Ptr and index2Ptr. There is one
* tricky thing here, which is that we have to relayout in units of whole
- * text lines: round index1Ptr back to the beginning of its text line, and
- * include all the display lines after index2, up to the end of its text
- * line. This is necessary because the indices stored in the display lines
- * will no longer be valid. It's also needed because any edit could change
- * the way lines wrap.
+ * text lines: This is necessary because the indices stored in the display
+ * lines will no longer be valid. It's also needed because any edit could
+ * change the way lines wrap.
+ * To relayout in units of whole text (logical) lines, round index1Ptr
+ * back to the beginning of its text line (or, if this line start is
+ * elided, to the beginning of the text line that starts the display line
+ * it is included in), and include all the display lines after index2Ptr,
+ * up to the end of its text line (or, if this line end is elided, up to
+ * the end of the first non elided text line after this line end).
*/
rounded = *index1Ptr;
rounded.byteIndex = 0;
- firstPtr = FindDLine(dInfoPtr->dLinePtr, &rounded);
+ notBegin = 0;
+ while (!IsStartOfNotMergedLine(textPtr, &rounded) && notBegin) {
+ notBegin = !TkTextIndexBackBytes(textPtr, &rounded, 1, &rounded);
+ rounded.byteIndex = 0;
+ }
+
+ /*
+ * 'rounded' now points to the start of a display line as well as the
+ * real (non elided) start of a logical line, and this index is the
+ * closest before index1Ptr.
+ */
+
+ firstPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, &rounded);
+
if (firstPtr == NULL) {
+ /*
+ * index1Ptr pertains to no display line, i.e this index is after
+ * the last display line. Since index2Ptr is after index1Ptr, there
+ * is no display line to free/redisplay and we can return early.
+ */
+
return;
}
- lastPtr = FindDLine(dInfoPtr->dLinePtr, index2Ptr);
- while ((lastPtr != NULL)
- && (lastPtr->index.linePtr == index2Ptr->linePtr)) {
- lastPtr = lastPtr->nextPtr;
+
+ rounded = *index2Ptr;
+ linePtr = index2Ptr->linePtr;
+ do {
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ if (linePtr == NULL) {
+ break;
+ }
+ rounded.linePtr = linePtr;
+ rounded.byteIndex = 0;
+ } while (!IsStartOfNotMergedLine(textPtr, &rounded));
+
+ if (linePtr == NULL) {
+ lastPtr = NULL;
+ } else {
+ /*
+ * 'rounded' now points to the start of a display line as well as the
+ * start of a logical line not merged with its previous line, and
+ * this index is the closest after index2Ptr.
+ */
+
+ lastPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, &rounded);
+
+ /*
+ * At least one display line is supposed to change. This makes the
+ * redisplay OK in case the display line we expect to get here was
+ * unlinked by a previous call to TkTextChanged and the text widget
+ * did not update before reaching this point. This happens for
+ * instance when moving the cursor up one line.
+ * Note that lastPtr != NULL here, otherwise we would have returned
+ * earlier when we tested for firstPtr being NULL.
+ */
+
+ if (lastPtr == firstPtr) {
+ lastPtr = lastPtr->nextPtr;
+ }
}
/*
@@ -4760,14 +4942,13 @@ TextRedrawTag(
* the line containing the previous character.
*/
- if (curIndexPtr->byteIndex == 0) {
- dlPtr = FindDLine(dlPtr, curIndexPtr);
+ if (IsStartOfNotMergedLine(textPtr, curIndexPtr)) {
+ dlPtr = FindDLine(textPtr, dlPtr, curIndexPtr);
} else {
- TkTextIndex tmp;
+ TkTextIndex tmp = *curIndexPtr;
- tmp = *curIndexPtr;
- tmp.byteIndex -= 1;
- dlPtr = FindDLine(dlPtr, &tmp);
+ TkTextIndexBackBytes(textPtr, &tmp, 1, &tmp);
+ dlPtr = FindDLine(textPtr, dlPtr, &tmp);
}
if (dlPtr == NULL) {
break;
@@ -4783,9 +4964,9 @@ TextRedrawTag(
curIndexPtr = &search.curIndex;
endIndexPtr = curIndexPtr;
}
- endPtr = FindDLine(dlPtr, endIndexPtr);
- if ((endPtr != NULL) && (endPtr->index.linePtr == endIndexPtr->linePtr)
- && (endPtr->index.byteIndex < endIndexPtr->byteIndex)) {
+ endPtr = FindDLine(textPtr, dlPtr, endIndexPtr);
+ if ((endPtr != NULL)
+ && (TkTextIndexCmp(&endPtr->index,endIndexPtr) < 0)) {
endPtr = endPtr->nextPtr;
}
@@ -4903,7 +5084,7 @@ TkTextRelayoutWindow(
* could change the way lines wrap.
*/
- if (textPtr->topIndex.byteIndex != 0) {
+ if (!IsStartOfNotMergedLine(textPtr, &textPtr->topIndex)) {
TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
}
@@ -4940,6 +5121,7 @@ TkTextRelayoutWindow(
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
AsyncUpdateLineMetrics, textPtr);
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
}
}
@@ -5016,9 +5198,9 @@ TkTextSetYView(
*/
textPtr->topIndex = *indexPtr;
- if (indexPtr->byteIndex != 0) {
- TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
- }
+ if (!IsStartOfNotMergedLine(textPtr, indexPtr)) {
+ TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex, 0, NULL);
+ }
dInfoPtr->newTopPixelOffset = pickPlace;
goto scheduleUpdate;
}
@@ -5032,7 +5214,7 @@ TkTextSetYView(
if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
UpdateDisplayInfo(textPtr);
}
- dlPtr = FindDLine(dInfoPtr->dLinePtr, indexPtr);
+ dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);
if (dlPtr != NULL) {
if ((dlPtr->y + dlPtr->height) > dInfoPtr->maxY) {
/*
@@ -5041,19 +5223,23 @@ TkTextSetYView(
*/
dlPtr = NULL;
- } else if ((dlPtr->index.linePtr == indexPtr->linePtr)
- && (dlPtr->index.byteIndex <= indexPtr->byteIndex)) {
- if (dInfoPtr->dLinePtr == dlPtr && dInfoPtr->topPixelOffset != 0) {
- /*
- * It is on the top line, but that line is hanging off the top
- * of the screen. Change the top overlap to zero and update.
- */
-
- dInfoPtr->newTopPixelOffset = 0;
- goto scheduleUpdate;
- }
- return;
- }
+ } else {
+ if (TkTextIndexCmp(&dlPtr->index, indexPtr) <= 0) {
+ if (dInfoPtr->dLinePtr == dlPtr && dInfoPtr->topPixelOffset != 0) {
+ /*
+ * It is on the top line, but that line is hanging off the top
+ * of the screen. Change the top overlap to zero and update.
+ */
+
+ dInfoPtr->newTopPixelOffset = 0;
+ goto scheduleUpdate;
+ }
+ /*
+ * The line is already on screen, with no need to scroll.
+ */
+ return;
+ }
+ }
}
/*
@@ -5064,7 +5250,9 @@ TkTextSetYView(
* If the line is not close, place it in the center of the window.
*/
- lineHeight = CalculateDisplayLineHeight(textPtr, indexPtr, NULL, NULL);
+ tmpIndex = *indexPtr;
+ TkTextFindDisplayLineEnd(textPtr, &tmpIndex, 0, NULL);
+ lineHeight = CalculateDisplayLineHeight(textPtr, &tmpIndex, NULL, NULL);
/*
* It would be better if 'bottomY' were calculated using the actual height
@@ -5105,12 +5293,21 @@ TkTextSetYView(
MeasureUp(textPtr, indexPtr, close + lineHeight
- textPtr->charHeight/2, &tmpIndex, &overlap);
- if (FindDLine(dInfoPtr->dLinePtr, &tmpIndex) != NULL) {
+ if (FindDLine(textPtr, dInfoPtr->dLinePtr, &tmpIndex) != NULL) {
bottomY = dInfoPtr->maxY - dInfoPtr->y;
}
}
/*
+ * If the window height is smaller than the line height, prefer to make
+ * the top of the line visible.
+ */
+
+ if (dInfoPtr->maxY - dInfoPtr->y < lineHeight) {
+ bottomY = lineHeight;
+ }
+
+ /*
* Our job now is to arrange the display so that indexPtr appears as low
* on the screen as possible but with its bottom no lower than bottomY.
* BottomY is the bottom of the window if the desired line is just below
@@ -5243,6 +5440,8 @@ MeasureUp(
index.linePtr = TkBTreeFindLine(srcPtr->tree, textPtr, lineNum);
index.byteIndex = 0;
+ TkTextFindDisplayLineEnd(textPtr, &index, 0, NULL);
+ lineNum = TkBTreeLinesTo(textPtr, index.linePtr);
lowestPtr = NULL;
do {
dlPtr = LayoutDLine(textPtr, &index);
@@ -5263,8 +5462,21 @@ MeasureUp(
for (dlPtr = lowestPtr; dlPtr != NULL; dlPtr = dlPtr->nextPtr) {
distance -= dlPtr->height;
if (distance <= 0) {
- *dstPtr = dlPtr->index;
- if (overlap != NULL) {
+ *dstPtr = dlPtr->index;
+
+ /*
+ * dstPtr is the start of a display line that is or is not
+ * the start of a logical line. If it is the start of a
+ * logical line, we must check whether this line is merged
+ * with the previous logical line, and if so we must adjust
+ * dstPtr to the start of the display line since a display
+ * line start needs to be returned.
+ */
+ if (!IsStartOfNotMergedLine(textPtr, dstPtr)) {
+ TkTextFindDisplayLineEnd(textPtr, dstPtr, 0, NULL);
+ }
+
+ if (overlap != NULL) {
*overlap = -distance;
}
break;
@@ -5364,16 +5576,24 @@ TkTextSeeCmd(
}
/*
- * Find the chunk that contains the desired index. dlPtr may be NULL if
- * the widget is not mapped. [Bug #641778]
+ * Find the display line containing the desired index. dlPtr may be NULL
+ * if the widget is not mapped. [Bug #641778]
*/
- dlPtr = FindDLine(dInfoPtr->dLinePtr, &index);
+ dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, &index);
if (dlPtr == NULL) {
return TCL_OK;
}
- byteCount = index.byteIndex - dlPtr->index.byteIndex;
+ /*
+ * Find the chunk within the display line that contains the desired
+ * index. The chunks making the display line are skipped up to but not
+ * including the one crossing index. Skipping is done based on a
+ * byteCount offset possibly spanning several logical lines in case
+ * they are elided.
+ */
+
+ byteCount = TkTextIndexCountBytes(textPtr, &dlPtr->index, &index);
for (chunkPtr = dlPtr->chunkPtr; chunkPtr != NULL ;
chunkPtr = chunkPtr->nextPtr) {
if (byteCount < chunkPtr->numBytes) {
@@ -5389,29 +5609,30 @@ TkTextSeeCmd(
*/
if (chunkPtr != NULL) {
- chunkPtr->bboxProc(textPtr, chunkPtr, byteCount,
- dlPtr->y + dlPtr->spaceAbove,
- dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
- dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
- &height);
- delta = x - dInfoPtr->curXPixelOffset;
- oneThird = lineWidth/3;
- if (delta < 0) {
- if (delta < -oneThird) {
- dInfoPtr->newXPixelOffset = x - lineWidth/2;
- } else {
- dInfoPtr->newXPixelOffset += delta;
- }
- } else {
- delta -= lineWidth - width;
- if (delta <= 0) {
- return TCL_OK;
- } else if (delta > oneThird) {
- dInfoPtr->newXPixelOffset = x - lineWidth/2;
- } else {
- dInfoPtr->newXPixelOffset += delta;
- }
- }
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteCount,
+ dlPtr->y + dlPtr->spaceAbove,
+ dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
+ dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width,
+ &height);
+ delta = x - dInfoPtr->curXPixelOffset;
+ oneThird = lineWidth/3;
+ if (delta < 0) {
+ if (delta < -oneThird) {
+ dInfoPtr->newXPixelOffset = x - lineWidth/2;
+ } else {
+ dInfoPtr->newXPixelOffset += delta;
+ }
+ } else {
+ delta -= lineWidth - width;
+ if (delta <= 0) {
+ return TCL_OK;
+ }
+ if (delta > oneThird) {
+ dInfoPtr->newXPixelOffset = x - lineWidth/2;
+ } else {
+ dInfoPtr->newXPixelOffset += delta;
+ }
+ }
}
dInfoPtr->flags |= DINFO_OUT_OF_DATE;
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
@@ -5648,7 +5869,25 @@ YScrollByLines(
offset++;
if (offset == 0) {
textPtr->topIndex = dlPtr->index;
- break;
+
+ /*
+ * topIndex is the start of a logical line. However, if
+ * the eol of the previous logical line is elided, then
+ * topIndex may be elsewhere than the first character of
+ * a display line, which is unwanted. Adjust to the start
+ * of the display line, if needed.
+ * topIndex is the start of a display line that is or is
+ * not the start of a logical line. If it is the start of
+ * a logical line, we must check whether this line is
+ * merged with the previous logical line, and if so we
+ * must adjust topIndex to the start of the display line.
+ */
+ if (!IsStartOfNotMergedLine(textPtr, &textPtr->topIndex)) {
+ TkTextFindDisplayLineEnd(textPtr, &textPtr->topIndex,
+ 0, NULL);
+ }
+
+ break;
}
}
@@ -5888,6 +6127,35 @@ TkTextYviewCmd(
/*
*--------------------------------------------------------------
*
+ * TkTextPendingsync --
+ *
+ * This function checks if any line heights are not up-to-date.
+ *
+ * Results:
+ * Returns a boolean true if it is the case, or false if all line
+ * heights are up-to-date.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+Bool
+TkTextPendingsync(
+ TkText *textPtr) /* Information about text widget. */
+{
+ TextDInfo *dInfoPtr = textPtr->dInfoPtr;
+
+ return (
+ ((dInfoPtr->metricEpoch == -1) &&
+ (dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ?
+ 0 : 1);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* TkTextScanCmd --
*
* This function is invoked to process the "scan" option for the widget
@@ -6064,12 +6332,18 @@ GetXView(
if (textPtr->xScrollCmd != NULL) {
char buf1[TCL_DOUBLE_SPACE+1];
char buf2[TCL_DOUBLE_SPACE+1];
+ Tcl_DString buf;
buf1[0] = ' ';
buf2[0] = ' ';
Tcl_PrintDouble(NULL, first, buf1+1);
Tcl_PrintDouble(NULL, last, buf2+1);
- code = Tcl_VarEval(interp, textPtr->xScrollCmd, buf1, buf2, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, textPtr->xScrollCmd, -1);
+ Tcl_DStringAppend(&buf, buf1, -1);
+ Tcl_DStringAppend(&buf, buf2, -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (horizontal scrolling command executed by text)");
@@ -6129,13 +6403,10 @@ GetYPixelCount(
/*
* For the common case where this dlPtr is also the start of the logical
- * line, we can return right away. Note the implicit assumption here that
- * the start of a logical line is always the start of a display line (if
- * the 'elide won't elide first newline' bug is fixed, this will no longer
- * necessarily be true).
+ * line, we can return right away.
*/
- if (dlPtr->index.byteIndex == 0) {
+ if (IsStartOfNotMergedLine(textPtr, &dlPtr->index)) {
return count;
}
@@ -6346,12 +6617,18 @@ GetYView(
if (textPtr->yScrollCmd != NULL) {
char buf1[TCL_DOUBLE_SPACE+1];
char buf2[TCL_DOUBLE_SPACE+1];
+ Tcl_DString buf;
buf1[0] = ' ';
buf2[0] = ' ';
Tcl_PrintDouble(NULL, first, buf1+1);
Tcl_PrintDouble(NULL, last, buf2+1);
- code = Tcl_VarEval(interp, textPtr->yScrollCmd, buf1, buf2, NULL);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, textPtr->yScrollCmd, -1);
+ Tcl_DStringAppend(&buf, buf1, -1);
+ Tcl_DStringAppend(&buf, buf2, -1);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
+ Tcl_DStringFree(&buf);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (vertical scrolling command executed by text)");
@@ -6416,11 +6693,13 @@ AsyncUpdateYScrollbar(
static DLine *
FindDLine(
+ TkText *textPtr, /* Widget record for text widget. */
register DLine *dlPtr, /* Pointer to first in list of DLines to
* search. */
const TkTextIndex *indexPtr)/* Index of desired character. */
{
- TkTextLine *linePtr;
+ DLine *dlPtrPrev;
+ TkTextIndex indexPtr2;
if (dlPtr == NULL) {
return NULL;
@@ -6435,43 +6714,123 @@ FindDLine(
}
/*
- * Find the first display line that covers the desired text line.
+ * The display line containing the desired index is such that the index
+ * of the first character of this display line is at or before the
+ * desired index, and the index of the first character of the next
+ * display line is after the desired index.
*/
- linePtr = dlPtr->index.linePtr;
- while (linePtr != indexPtr->linePtr) {
- while (dlPtr->index.linePtr == linePtr) {
- dlPtr = dlPtr->nextPtr;
- if (dlPtr == NULL) {
- return NULL;
- }
- }
+ while (TkTextIndexCmp(&dlPtr->index,indexPtr) < 0) {
+ dlPtrPrev = dlPtr;
+ dlPtr = dlPtr->nextPtr;
+ if (dlPtr == NULL) {
+ /*
+ * We're past the last display line, either because the desired
+ * index lies past the visible text, or because the desired index
+ * is on the last display line.
+ */
+ indexPtr2 = dlPtrPrev->index;
+ TkTextIndexForwBytes(textPtr, &indexPtr2, dlPtrPrev->byteCount,
+ &indexPtr2);
+ if (TkTextIndexCmp(&indexPtr2,indexPtr) > 0) {
+ /*
+ * The desired index is on the last display line.
+ * --> return this display line.
+ */
+ dlPtr = dlPtrPrev;
+ } else {
+ /*
+ * The desired index is past the visible text. There is no
+ * display line displaying something at the desired index.
+ * --> return NULL.
+ */
+ }
+ break;
+ }
+ if (TkTextIndexCmp(&dlPtr->index,indexPtr) > 0) {
+ /*
+ * If we're here then we would normally expect that:
+ * dlPtrPrev->index <= indexPtr < dlPtr->index
+ * i.e. we have found the searched display line being dlPtr.
+ * However it is possible that some DLines were unlinked
+ * previously, leading to a situation where going through
+ * the list of display lines skips display lines that did
+ * exist just a moment ago.
+ */
+ indexPtr2 = dlPtrPrev->index;
+ TkTextIndexForwBytes(textPtr, &indexPtr2, dlPtrPrev->byteCount,
+ &indexPtr2);
+ if (TkTextIndexCmp(&indexPtr2,indexPtr) > 0) {
+ /*
+ * Confirmed:
+ * dlPtrPrev->index <= indexPtr < dlPtr->index
+ * --> return dlPtrPrev.
+ */
+ dlPtr = dlPtrPrev;
+ } else {
+ /*
+ * The last (rightmost) index shown by dlPtrPrev is still
+ * before the desired index. This may be because there was
+ * previously a display line between dlPtrPrev and dlPtr
+ * and this display line has been unlinked.
+ * --> return dlPtr.
+ */
+ }
+ break;
+ }
+ }
- /*
- * VMD: some concern here as to whether this logic, or the caller's
- * logic will work well with partial peer widgets.
- */
+ return dlPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IsStartOfNotMergedLine --
+ *
+ * This function checks whether the given index is the start of a
+ * logical line that is not merged with the previous logical line
+ * (due to elision of the eol of the previous line).
+ *
+ * Results:
+ * Returns whether the given index denotes the first index of a
+* logical line not merged with its previous line.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
- linePtr = TkBTreeNextLine(NULL, linePtr);
- if (linePtr == NULL) {
- Tcl_Panic("FindDLine reached end of text");
- }
- }
- if (indexPtr->linePtr != dlPtr->index.linePtr) {
- return dlPtr;
+static int
+IsStartOfNotMergedLine(
+ TkText *textPtr, /* Widget record for text widget. */
+ CONST TkTextIndex *indexPtr) /* Index to check. */
+{
+ TkTextIndex indexPtr2;
+
+ if (indexPtr->byteIndex != 0) {
+ /*
+ * Not the start of a logical line.
+ */
+ return 0;
}
- /*
- * Now get to the right position within the text line.
- */
+ if (TkTextIndexBackBytes(textPtr, indexPtr, 1, &indexPtr2)) {
+ /*
+ * indexPtr is the first index of the text widget.
+ */
+ return 1;
+ }
- while (indexPtr->byteIndex >= (dlPtr->index.byteIndex+dlPtr->byteCount)) {
- dlPtr = dlPtr->nextPtr;
- if ((dlPtr == NULL) || (dlPtr->index.linePtr != indexPtr->linePtr)) {
- break;
- }
+ if (!TkTextIsElided(textPtr, &indexPtr2, NULL)) {
+ /*
+ * The eol of the line just before indexPtr is elided.
+ */
+ return 1;
}
- return dlPtr;
+
+ return 0;
}
/*
@@ -6642,10 +7001,15 @@ DlineIndexOfX(
* We've reached the end of the text.
*/
+ TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr, COUNT_INDICES);
return;
}
if (chunkPtr->nextPtr == NULL) {
- TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr, COUNT_INDICES);
+ /*
+ * We've reached the end of the display line.
+ */
+
+ TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr, COUNT_INDICES);
return;
}
chunkPtr = chunkPtr->nextPtr;
@@ -6801,7 +7165,7 @@ TkTextIndexBbox(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
DLine *dlPtr;
register TkTextDispChunk *chunkPtr;
- int byteIndex;
+ int byteCount;
/*
* Make sure that all of the screen layout information is up to date.
@@ -6815,24 +7179,37 @@ TkTextIndexBbox(
* Find the display line containing the desired index.
*/
- dlPtr = FindDLine(dInfoPtr->dLinePtr, indexPtr);
+ dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);
+
+ /*
+ * Two cases shall be trapped here because the logic later really
+ * needs dlPtr to be the display line containing indexPtr:
+ * 1. if no display line contains the desired index (NULL dlPtr)
+ * 2. if indexPtr is before the first display line, in which case
+ * dlPtr currently points to the first display line
+ */
+
if ((dlPtr == NULL) || (TkTextIndexCmp(&dlPtr->index, indexPtr) > 0)) {
return -1;
}
/*
- * Find the chunk within the line that contains the desired index.
+ * Find the chunk within the display line that contains the desired
+ * index. The chunks making the display line are skipped up to but not
+ * including the one crossing indexPtr. Skipping is done based on
+ * a byteCount offset possibly spanning several logical lines in case
+ * they are elided.
*/
- byteIndex = indexPtr->byteIndex - dlPtr->index.byteIndex;
+ byteCount = TkTextIndexCountBytes(textPtr, &dlPtr->index, indexPtr);
for (chunkPtr = dlPtr->chunkPtr; ; chunkPtr = chunkPtr->nextPtr) {
if (chunkPtr == NULL) {
return -1;
}
- if (byteIndex < chunkPtr->numBytes) {
+ if (byteCount < chunkPtr->numBytes) {
break;
}
- byteIndex -= chunkPtr->numBytes;
+ byteCount -= chunkPtr->numBytes;
}
/*
@@ -6842,13 +7219,13 @@ TkTextIndexBbox(
* coordinate on the screen. Translate it to reflect horizontal scrolling.
*/
- chunkPtr->bboxProc(textPtr, chunkPtr, byteIndex,
+ chunkPtr->bboxProc(textPtr, chunkPtr, byteCount,
dlPtr->y + dlPtr->spaceAbove,
dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,
dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr,
heightPtr);
*xPtr = *xPtr + dInfoPtr->x - dInfoPtr->curXPixelOffset;
- if ((byteIndex == chunkPtr->numBytes-1) && (chunkPtr->nextPtr == NULL)) {
+ if ((byteCount == chunkPtr->numBytes-1) && (chunkPtr->nextPtr == NULL)) {
/*
* Last character in display line. Give it all the space up to the
* line.
@@ -6946,7 +7323,16 @@ TkTextDLineInfo(
* Find the display line containing the desired index.
*/
- dlPtr = FindDLine(dInfoPtr->dLinePtr, indexPtr);
+ dlPtr = FindDLine(textPtr, dInfoPtr->dLinePtr, indexPtr);
+
+ /*
+ * Two cases shall be trapped here because the logic later really
+ * needs dlPtr to be the display line containing indexPtr:
+ * 1. if no display line contains the desired index (NULL dlPtr)
+ * 2. if indexPtr is before the first display line, in which case
+ * dlPtr currently points to the first display line
+ */
+
if ((dlPtr == NULL) || (TkTextIndexCmp(&dlPtr->index, indexPtr) > 0)) {
return -1;
}
@@ -8196,8 +8582,8 @@ TextGetScrollInfoObj(
};
int index;
- if (Tcl_GetIndexFromObj(interp, objv[2], subcommands, "option", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], subcommands,
+ sizeof(char *), "option", 0, &index) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
@@ -8216,8 +8602,8 @@ TextGetScrollInfoObj(
Tcl_WrongNumArgs(interp, 3, objv, "number units|pages|pixels");
return TKTEXT_SCROLL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[4], units, "argument", 0,
- &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[4], units,
+ sizeof(char *), "argument", 0, &index) != TCL_OK) {
return TKTEXT_SCROLL_ERROR;
}
switch ((enum viewUnits) index) {
diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c
index 1770cb6..41dd448 100644
--- a/generic/tkTextImage.c
+++ b/generic/tkTextImage.c
@@ -138,8 +138,8 @@ TkTextImageCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0,
- &idx) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], optionStrings,
+ sizeof(char *), "option", 0, &idx) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum opts) idx) {
@@ -786,6 +786,10 @@ TkTextImageIndex(
Tcl_HashEntry *hPtr;
TkTextSegment *eiPtr;
+ if (textPtr == NULL) {
+ return 0;
+ }
+
hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
if (hPtr == NULL) {
return 0;
diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c
index 25888d8..8820191 100644
--- a/generic/tkTextIndex.c
+++ b/generic/tkTextIndex.c
@@ -40,6 +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);
/*
* The "textindex" Tcl_Obj definition:
@@ -48,8 +51,6 @@ static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr,
static void DupTextIndexInternalRep(Tcl_Obj *srcPtr,
Tcl_Obj *copyPtr);
static void FreeTextIndexInternalRep(Tcl_Obj *listPtr);
-static int SetTextIndexFromAny(Tcl_Interp *interp,
- Tcl_Obj *objPtr);
static void UpdateStringOfTextIndex(Tcl_Obj *objPtr);
/*
@@ -75,7 +76,7 @@ const Tcl_ObjType tkTextIndexType = {
FreeTextIndexInternalRep, /* freeIntRepProc */
DupTextIndexInternalRep, /* dupIntRepProc */
NULL, /* updateStringProc */
- SetTextIndexFromAny /* setFromAnyProc */
+ NULL /* setFromAnyProc */
};
static void
@@ -142,18 +143,6 @@ UpdateStringOfTextIndex(
strcpy(objPtr->bytes, buffer);
objPtr->length = len;
}
-
-static int
-SetTextIndexFromAny(
- Tcl_Interp *interp, /* Used for error reporting if not NULL. */
- Tcl_Obj *objPtr) /* The object to convert. */
-{
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't convert value to textindex except via"
- " TkTextGetIndexFromObj API", -1));
- Tcl_SetErrorCode(interp, "TK", "API_ABUSE", NULL);
- return TCL_ERROR;
-}
/*
*---------------------------------------------------------------------------
@@ -760,9 +749,11 @@ GetIndex(
/*
*---------------------------------------------------------------------
- * Stage 1: check to see if the index consists of nothing but a mark name.
- * We do this check now even though it's also done later, in order to
- * allow mark names that include funny characters such as spaces or "+1c".
+ * Stage 1: check to see if the index consists of nothing but a mark
+ * name, an embedded window or an embedded image. We do this check
+ * now even though it's also done later, in order to allow mark names,
+ * embedded window names or image names that include funny characters
+ * such as spaces or "+1c".
*---------------------------------------------------------------------
*/
@@ -770,6 +761,14 @@ GetIndex(
goto done;
}
+ if (TkTextWindowIndex(textPtr, string, indexPtr) != 0) {
+ goto done;
+ }
+
+ if (TkTextImageIndex(textPtr, string, indexPtr) != 0) {
+ goto done;
+ }
+
/*
*------------------------------------------------
* Stage 2: start again by parsing the base index.
@@ -1620,6 +1619,90 @@ TkTextIndexForwChars(
/*
*---------------------------------------------------------------------------
*
+ * TkTextIndexCountBytes --
+ *
+ * Given a pair of indices in a text widget, this function counts how
+ * many bytes are between the two indices. The two indices do not need
+ * to be ordered.
+ *
+ * Results:
+ * The number of bytes in the given range.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TkTextIndexCountBytes(
+ CONST TkText *textPtr,
+ CONST TkTextIndex *indexPtr1, /* Index describing one location. */
+ CONST TkTextIndex *indexPtr2) /* Index describing second location. */
+{
+ int compare = TkTextIndexCmp(indexPtr1, indexPtr2);
+
+ if (compare == 0) {
+ return 0;
+ } else if (compare > 0) {
+ return IndexCountBytesOrdered(textPtr, indexPtr2, indexPtr1);
+ } else {
+ return IndexCountBytesOrdered(textPtr, indexPtr1, indexPtr2);
+ }
+}
+
+static int
+IndexCountBytesOrdered(
+ CONST TkText *textPtr,
+ CONST TkTextIndex *indexPtr1,
+ /* Index describing location of character from
+ * which to count. */
+ CONST TkTextIndex *indexPtr2)
+ /* Index describing location of last character
+ * at which to stop the count. */
+{
+ int byteCount, offset;
+ TkTextSegment *segPtr, *segPtr1;
+ TkTextLine *linePtr;
+
+ if (indexPtr1->linePtr == indexPtr2->linePtr) {
+ return indexPtr2->byteIndex - indexPtr1->byteIndex;
+ }
+
+ /*
+ * indexPtr2 is on a line strictly after the line containing indexPtr1.
+ * Add up:
+ * bytes between indexPtr1 and end of its line
+ * bytes in lines strictly between indexPtr1 and indexPtr2
+ * bytes between start of the indexPtr2 line and indexPtr2
+ */
+
+ segPtr1 = TkTextIndexToSeg(indexPtr1, &offset);
+ byteCount = -offset;
+ for (segPtr = segPtr1; segPtr != NULL; segPtr = segPtr->nextPtr) {
+ byteCount += segPtr->size;
+ }
+
+ linePtr = TkBTreeNextLine(textPtr, indexPtr1->linePtr);
+ while (linePtr != indexPtr2->linePtr) {
+ for (segPtr = linePtr->segPtr; segPtr != NULL;
+ segPtr = segPtr->nextPtr) {
+ byteCount += segPtr->size;
+ }
+ linePtr = TkBTreeNextLine(textPtr, linePtr);
+ if (linePtr == NULL) {
+ Tcl_Panic("TextIndexCountBytesOrdered ran out of lines");
+ }
+ }
+
+ byteCount += indexPtr2->byteIndex;
+
+ return byteCount;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
* TkTextIndexCount --
*
* Given an ordered pair of indices in a text widget, this function
@@ -2122,7 +2205,7 @@ StartEnd(
TkText *textPtr, /* Information about text widget. */
const char *string, /* String to parse for additional info about
* modifier (count and units). Points to first
- * character of modifer word. */
+ * character of modifier word. */
TkTextIndex *indexPtr) /* Index to modify based on string. */
{
const char *p;
@@ -2244,7 +2327,7 @@ StartEnd(
int offset;
if (modifier == TKINDEX_DISPLAY) {
- TkTextIndexForwChars(NULL, indexPtr, 0, indexPtr,
+ TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
COUNT_DISPLAY_INDICES);
}
@@ -2273,11 +2356,20 @@ StartEnd(
}
firstChar = 0;
}
- offset -= chSize;
- indexPtr->byteIndex -= chSize;
+ if (offset == 0) {
+ if (modifier == TKINDEX_DISPLAY) {
+ TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr,
+ COUNT_DISPLAY_INDICES);
+ } else {
+ TkTextIndexBackChars(NULL, indexPtr, 1, indexPtr,
+ COUNT_INDICES);
+ }
+ } else {
+ indexPtr->byteIndex -= chSize;
+ }
+ offset -= chSize;
if (offset < 0) {
- if (indexPtr->byteIndex < 0) {
- indexPtr->byteIndex = 0;
+ if (indexPtr->byteIndex == 0) {
goto done;
}
segPtr = TkTextIndexToSeg(indexPtr, &offset);
diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c
index a306a05..6a41c77 100644
--- a/generic/tkTextMark.c
+++ b/generic/tkTextMark.c
@@ -40,9 +40,9 @@ static int MarkLayoutProc(TkText *textPtr, TkTextIndex *indexPtr,
int maxChars, int noCharsYet, TkWrapMode wrapMode,
TkTextDispChunk *chunkPtr);
static int MarkFindNext(Tcl_Interp *interp,
- TkText *textPtr, const char *markName);
+ TkText *textPtr, Tcl_Obj *markName);
static int MarkFindPrev(Tcl_Interp *interp,
- TkText *textPtr, const char *markName);
+ TkText *textPtr, Tcl_Obj *markName);
/*
@@ -118,8 +118,8 @@ TkTextMarkCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], markOptionStrings, "mark option",
- 0, &optionIndex) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], markOptionStrings,
+ sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
@@ -205,13 +205,13 @@ TkTextMarkCmd(
Tcl_WrongNumArgs(interp, 3, objv, "index");
return TCL_ERROR;
}
- return MarkFindNext(interp, textPtr, Tcl_GetString(objv[3]));
+ return MarkFindNext(interp, textPtr, objv[3]);
case MARK_PREVIOUS:
if (objc != 4) {
Tcl_WrongNumArgs(interp, 3, objv, "index");
return TCL_ERROR;
}
- return MarkFindPrev(interp, textPtr, Tcl_GetString(objv[3]));
+ return MarkFindPrev(interp, textPtr, objv[3]);
case MARK_SET:
if (objc != 5) {
Tcl_WrongNumArgs(interp, 3, objv, "markName index");
@@ -805,12 +805,13 @@ static int
MarkFindNext(
Tcl_Interp *interp, /* For error reporting */
TkText *textPtr, /* The widget */
- const char *string) /* The starting index or mark name */
+ Tcl_Obj *obj) /* The starting index or mark name */
{
TkTextIndex index;
Tcl_HashEntry *hPtr;
register TkTextSegment *segPtr;
int offset;
+ const char *string = Tcl_GetString(obj);
if (!strcmp(string, "insert")) {
segPtr = textPtr->insertMarkPtr;
@@ -838,7 +839,7 @@ MarkFindNext(
* right at the index.
*/
- if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) {
return TCL_ERROR;
}
for (offset = 0, segPtr = index.linePtr->segPtr;
@@ -895,12 +896,13 @@ static int
MarkFindPrev(
Tcl_Interp *interp, /* For error reporting */
TkText *textPtr, /* The widget */
- const char *string) /* The starting index or mark name */
+ Tcl_Obj *obj) /* The starting index or mark name */
{
TkTextIndex index;
Tcl_HashEntry *hPtr;
register TkTextSegment *segPtr, *seg2Ptr, *prevPtr;
int offset;
+ const char *string = Tcl_GetString(obj);
if (!strcmp(string, "insert")) {
segPtr = textPtr->insertMarkPtr;
@@ -925,7 +927,7 @@ MarkFindPrev(
* right at the index.
*/
- if (TkTextGetIndex(interp, textPtr, string, &index) != TCL_OK) {
+ if (TkTextGetObjIndex(interp, textPtr, obj, &index) != TCL_OK) {
return TCL_ERROR;
}
for (offset = 0, segPtr = index.linePtr->segPtr;
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index beb7eb5..3363d25 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -44,11 +44,11 @@ static const Tk_OptionSpec tagOptionSpecs[] = {
{TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
- "0", Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
- TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ NULL, Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_STRING, "-elide", NULL, NULL,
- "0", -1, Tk_Offset(TkTextTag, elideString),
- TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ NULL, -1, Tk_Offset(TkTextTag, elideString),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_FONT, "-font", NULL, NULL,
@@ -148,8 +148,8 @@ TkTextTagCmd(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings,
- "tag option", 0, &optionIndex) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], tagOptionStrings,
+ sizeof(char *), "tag option", 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
@@ -169,6 +169,14 @@ TkTextTagCmd(
return TCL_ERROR;
}
tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
+ if (tagPtr->elide) {
+ /*
+ * Indices are potentially obsolete after adding or removing
+ * elided character ranges, especially indices having "display"
+ * or "any" submodifier, therefore increase the epoch.
+ */
+ textPtr->sharedTextPtr->stateEpoch++;
+ }
for (i = 4; i < objc; i += 2) {
if (TkTextGetObjIndex(interp, textPtr, objv[i],
&index1) != TCL_OK) {
@@ -289,7 +297,7 @@ TkTextTagCmd(
textPtr->sharedTextPtr->bindingTable,
(ClientData) tagPtr->name, Tcl_GetString(objv[4]));
if (command == NULL) {
- const char *string = Tcl_GetStringResult(interp);
+ const char *string = Tcl_GetString(Tcl_GetObjResult(interp));
/*
* Ignore missing binding errors. This is a special hack that
diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c
index d2998da..c9fc20f 100644
--- a/generic/tkTextWind.c
+++ b/generic/tkTextWind.c
@@ -153,8 +153,8 @@ TkTextWindowCmd(
Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], windOptionStrings,
- "window option", 0, &optionIndex) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], windOptionStrings,
+ sizeof(char *), "window option", 0, &optionIndex) != TCL_OK) {
return TCL_ERROR;
}
switch ((enum windOptions) optionIndex) {
@@ -911,10 +911,10 @@ EmbWinLayoutProc(
if (dsPtr != NULL) {
Tcl_DStringAppend(dsPtr, before, (int) (string-before));
- code = Tcl_GlobalEval(textPtr->interp, Tcl_DStringValue(dsPtr));
+ code = Tcl_EvalEx(textPtr->interp, Tcl_DStringValue(dsPtr), -1, TCL_EVAL_GLOBAL);
Tcl_DStringFree(dsPtr);
} else {
- code = Tcl_GlobalEval(textPtr->interp, ewPtr->body.ew.create);
+ code = Tcl_EvalEx(textPtr->interp, ewPtr->body.ew.create, -1, TCL_EVAL_GLOBAL);
}
if (code != TCL_OK) {
Tcl_BackgroundException(textPtr->interp, code);
@@ -927,7 +927,7 @@ EmbWinLayoutProc(
Tcl_GetString(nameObj), textPtr->tkwin);
Tcl_DecrRefCount(nameObj);
if (ewPtr->body.ew.tkwin == NULL) {
- Tcl_BackgroundError(textPtr->interp);
+ Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
goto gotWindow;
}
@@ -948,7 +948,7 @@ EmbWinLayoutProc(
Tk_PathName(textPtr->tkwin)));
Tcl_SetErrorCode(textPtr->interp, "TK", "GEOMETRY", "HIERARCHY",
NULL);
- Tcl_BackgroundError(textPtr->interp);
+ Tcl_BackgroundException(textPtr->interp, TCL_ERROR);
ewPtr->body.ew.tkwin = NULL;
goto gotWindow;
}
@@ -1134,6 +1134,16 @@ TkTextEmbWinDisplayProc(
&lineX, &windowY, &width, &height);
windowX = lineX - chunkPtr->x + x;
+ /*
+ * Mark the window as displayed so that it won't get unmapped.
+ * This needs to be done before the next instruction block because
+ * Tk_MaintainGeometry/Tk_MapWindow will run event handlers, in
+ * particular for the <Map> event, and if the bound script deletes
+ * the embedded window its clients will get freed.
+ */
+
+ client->displayed = 1;
+
if (textPtr->tkwin == Tk_Parent(tkwin)) {
if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin))
|| (Tk_ReqWidth(tkwin) != Tk_Width(tkwin))
@@ -1145,12 +1155,6 @@ TkTextEmbWinDisplayProc(
Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY,
width, height);
}
-
- /*
- * Mark the window as displayed so that it won't get unmapped.
- */
-
- client->displayed = 1;
}
/*
@@ -1340,6 +1344,10 @@ TkTextWindowIndex(
Tcl_HashEntry *hPtr;
TkTextSegment *ewPtr;
+ if (textPtr == NULL) {
+ return 0;
+ }
+
hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
if (hPtr == NULL) {
return 0;
diff --git a/generic/tkUndo.c b/generic/tkUndo.c
index a642e72..8359e0a 100644
--- a/generic/tkUndo.c
+++ b/generic/tkUndo.c
@@ -392,7 +392,7 @@ TkUndoSetDepth(
prevelem = elem;
elem = elem->next;
}
- CLANG_ASSERT(prevelem);
+ CLANG_ASSERT(prevelem);
prevelem->next = NULL;
while (elem != NULL) {
prevelem = elem;
diff --git a/generic/tkUtil.c b/generic/tkUtil.c
index 385d1cb..7ff9ecb 100644
--- a/generic/tkUtil.c
+++ b/generic/tkUtil.c
@@ -729,8 +729,8 @@ Tk_GetScrollInfoObj(
int *intPtr) /* Filled in with number of pages or lines to
* scroll, if any. */
{
- int length;
- const char *arg = Tcl_GetStringFromObj(objv[2], &length);
+ const char *arg = Tcl_GetString(objv[2]);
+ size_t length = objv[2]->length;
#define ArgPfxEq(str) \
((arg[0] == str[0]) && !strncmp(arg, str, (unsigned)length))
@@ -753,7 +753,8 @@ Tk_GetScrollInfoObj(
return TK_SCROLL_ERROR;
}
- arg = Tcl_GetStringFromObj(objv[4], &length);
+ arg = Tcl_GetString(objv[4]);
+ length = objv[4]->length;
if (ArgPfxEq("pages")) {
return TK_SCROLL_PAGES;
} else if (ArgPfxEq("units")) {
@@ -970,7 +971,7 @@ TkFindStateNumObj(
* Not there. Look in the state map.
*/
- key = Tcl_GetStringFromObj(keyPtr, NULL);
+ key = Tcl_GetString(keyPtr);
for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
if (strcmp(key, mPtr->strKey) == 0) {
typePtr = keyPtr->typePtr;
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index f4138b2..b5cbbab 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -14,7 +14,7 @@
#include "tkInt.h"
-#ifdef __WIN32__
+#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
@@ -97,9 +97,8 @@ static const XSetWindowAttributes defAtts= {
#define ISSAFE 1
#define PASSMAINWINDOW 2
-#define NOOBJPROC 4
-#define WINMACONLY 8
-#define USEINITPROC 16
+#define WINMACONLY 4
+#define USEINITPROC 8
typedef int (TkInitProc)(Tcl_Interp *interp, ClientData clientData);
typedef struct {
@@ -149,13 +148,13 @@ static const TkCmd commands[] = {
{"label", Tk_LabelObjCmd, ISSAFE},
{"labelframe", Tk_LabelframeObjCmd, ISSAFE},
{"listbox", Tk_ListboxObjCmd, ISSAFE},
+ {"menu", Tk_MenuObjCmd, PASSMAINWINDOW},
{"menubutton", Tk_MenubuttonObjCmd, ISSAFE},
{"message", Tk_MessageObjCmd, ISSAFE},
{"panedwindow", Tk_PanedWindowObjCmd, ISSAFE},
{"radiobutton", Tk_RadiobuttonObjCmd, ISSAFE},
{"scale", Tk_ScaleObjCmd, ISSAFE},
- {"scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd,
- NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"scrollbar", Tk_ScrollbarObjCmd, PASSMAINWINDOW|ISSAFE},
{"spinbox", Tk_SpinboxObjCmd, ISSAFE},
{"text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
{"toplevel", Tk_ToplevelObjCmd, 0},
@@ -177,8 +176,7 @@ static const TkCmd commands[] = {
{"::tk::panedwindow",Tk_PanedWindowObjCmd, ISSAFE},
{"::tk::radiobutton",Tk_RadiobuttonObjCmd, ISSAFE},
{"::tk::scale", Tk_ScaleObjCmd, ISSAFE},
- {"::tk::scrollbar", (Tcl_ObjCmdProc *) Tk_ScrollbarCmd,
- NOOBJPROC|PASSMAINWINDOW|ISSAFE},
+ {"::tk::scrollbar", Tk_ScrollbarObjCmd, PASSMAINWINDOW|ISSAFE},
{"::tk::spinbox", Tk_SpinboxObjCmd, ISSAFE},
{"::tk::text", Tk_TextObjCmd, PASSMAINWINDOW|ISSAFE},
{"::tk::toplevel", Tk_ToplevelObjCmd, 0},
@@ -188,7 +186,7 @@ static const TkCmd commands[] = {
* these commands differently (via the script library).
*/
-#if defined(__WIN32__) || defined(MAC_OSX_TK)
+#if defined(_WIN32) || defined(MAC_OSX_TK)
{"tk_chooseColor", Tk_ChooseColorObjCmd, PASSMAINWINDOW},
{"tk_chooseDirectory", Tk_ChooseDirectoryObjCmd,WINMACONLY|PASSMAINWINDOW},
{"tk_getOpenFile", Tk_GetOpenFileObjCmd, WINMACONLY|PASSMAINWINDOW},
@@ -958,7 +956,7 @@ TkCreateMainWindow(
Tcl_Panic("TkCreateMainWindow: builtin command with NULL string and object procs");
}
-#if defined(__WIN32__) && !defined(STATIC_BUILD)
+#if defined(_WIN32) && !defined(STATIC_BUILD)
if ((cmdPtr->flags & WINMACONLY) && tclStubsPtr->reserved9) {
/*
* We are running on Cygwin, so don't use the win32 dialogs.
@@ -966,7 +964,7 @@ TkCreateMainWindow(
continue;
}
-#endif /* __WIN32__ && !STATIC_BUILD */
+#endif /* _WIN32 && !STATIC_BUILD */
if (cmdPtr->flags & PASSMAINWINDOW) {
clientData = tkwin;
@@ -975,9 +973,6 @@ TkCreateMainWindow(
}
if (cmdPtr->flags & USEINITPROC) {
((TkInitProc *) cmdPtr->objProc)(interp, clientData);
- } else if (cmdPtr->flags & NOOBJPROC) {
- Tcl_CreateCommand(interp, cmdPtr->name,
- (Tcl_CmdProc *) cmdPtr->objProc, clientData, NULL);
} else {
Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc,
clientData, NULL);
@@ -987,14 +982,12 @@ TkCreateMainWindow(
}
}
- TkCreateMenuCmd(interp);
-
/*
* Set variables for the intepreter.
*/
- Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
- Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "tk_version", NULL, TK_VERSION, TCL_GLOBAL_ONLY);
tsdPtr->numMainWindows++;
return tkwin;
@@ -1467,7 +1460,7 @@ Tk_DestroyWindow(
TkWmRemoveFromColormapWindows(winPtr);
}
if (winPtr->window != None) {
-#if defined(MAC_OSX_TK) || defined(__WIN32__)
+#if defined(MAC_OSX_TK) || defined(_WIN32)
XDestroyWindow(winPtr->display, winPtr->window);
#else
if ((winPtr->flags & TK_TOP_HIERARCHY)
@@ -1544,11 +1537,11 @@ Tk_DestroyWindow(
if ((winPtr->mainPtr->interp != NULL) &&
!Tcl_InterpDeleted(winPtr->mainPtr->interp)) {
for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
- Tcl_CreateCommand(winPtr->mainPtr->interp, cmdPtr->name,
- TkDeadAppCmd, NULL, NULL);
+ Tcl_CreateObjCommand(winPtr->mainPtr->interp, cmdPtr->name,
+ TkDeadAppObjCmd, NULL, NULL);
}
- Tcl_CreateCommand(winPtr->mainPtr->interp, "send",
- TkDeadAppCmd, NULL, NULL);
+ Tcl_CreateObjCommand(winPtr->mainPtr->interp, "send",
+ TkDeadAppObjCmd, NULL, NULL);
Tcl_UnlinkVar(winPtr->mainPtr->interp, "tk_strictMotif");
Tcl_UnlinkVar(winPtr->mainPtr->interp,
"::tk::AlwaysShowSelection");
@@ -1579,7 +1572,7 @@ Tk_DestroyWindow(
* display now and relinquish its data structures.
*/
-#if !defined(WIN32) && defined(NOT_YET)
+#if !defined(_WIN32) && defined(NOT_YET)
if (dispPtr->refCount <= 0) {
/*
* I have disabled this code because on Windows there are
@@ -1627,7 +1620,7 @@ Tk_DestroyWindow(
TkCloseDisplay(dispPtr);
}
-#endif /* !WIN32 && NOT_YET */
+#endif /* !_WIN32 && NOT_YET */
}
}
Tcl_EventuallyFree(winPtr, TCL_DYNAMIC);
@@ -2852,7 +2845,7 @@ DeleteWindowsExitProc(
tsdPtr->initialized = 0;
}
-#if defined(__WIN32__) && !defined(__WIN64__)
+#if defined(_WIN32)
static HMODULE tkcygwindll = NULL;
@@ -2898,7 +2891,7 @@ TkCygwinMainEx(
tkmainex(argc, argv, appInitProc, interp);
return 1;
}
-#endif /* __WIN32__ && !__WIN64__ */
+#endif /* _WIN32 */
/*
*----------------------------------------------------------------------
@@ -2927,7 +2920,7 @@ int
Tk_Init(
Tcl_Interp *interp) /* Interpreter to initialize. */
{
-#if defined(__WIN32__) && !defined(__WIN64__)
+#if defined(_WIN32)
if (tkcygwindll) {
int (*tkinit)(Tcl_Interp *);
@@ -2936,7 +2929,7 @@ Tk_Init(
return tkinit(interp);
}
}
-#endif /* __WIN32__ && !__WIN64__ */
+#endif /* _WIN32 */
return Initialize(interp);
}
@@ -3000,7 +2993,7 @@ Tk_SafeInit(
* checked at several places to differentiate the two initialisations.
*/
-#if defined(__WIN32__) && !defined(__WIN64__)
+#if defined(_WIN32)
if (tkcygwindll) {
int (*tksafeinit)(Tcl_Interp *);
@@ -3010,7 +3003,7 @@ Tk_SafeInit(
return tksafeinit(interp);
}
}
-#endif /* __WIN32__ && !__WIN64__ */
+#endif /* _WIN32 */
return Initialize(interp);
}
@@ -3047,11 +3040,10 @@ Initialize(
ThreadSpecificData *tsdPtr;
/*
- * Ensure that we are getting a compatible version of Tcl. This is really
- * only an issue when Tk is loaded dynamically.
+ * Ensure that we are getting a compatible version of Tcl.
*/
- if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
+ if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
return TCL_ERROR;
}
@@ -3136,14 +3128,14 @@ Initialize(
Tcl_DStringInit(&ds);
Tcl_DStringAppendElement(&ds, "::safe::TkInit");
- Tcl_DStringAppendElement(&ds, Tcl_GetStringResult(master));
+ Tcl_DStringAppendElement(&ds, Tcl_GetString(Tcl_GetObjResult(master)));
/*
* Step 2 : Eval in the master. The argument is the *reversed* interp
* path of the slave.
*/
- code = Tcl_Eval(master, Tcl_DStringValue(&ds));
+ code = Tcl_EvalEx(master, Tcl_DStringValue(&ds), -1, 0);
if (code != TCL_OK) {
/*
* We might want to transfer the error message or not. We don't.
@@ -3164,7 +3156,7 @@ Initialize(
* changing the code below.
*/
- argString = Tcl_GetStringResult(master);
+ argString = Tcl_GetString(Tcl_GetObjResult(master));
} else {
/*
* If there is an "argv" variable, get its value, extract out relevant
@@ -3279,19 +3271,20 @@ Initialize(
*/
if (geometry != NULL) {
- Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY);
- code = Tcl_VarEval(interp, "wm geometry . ", geometry, NULL);
+ Tcl_DString buf;
+
+ 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);
if (code != TCL_OK) {
goto done;
}
geometry = NULL;
}
- if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
- code = TCL_ERROR;
- goto done;
- }
-
/*
* Provide Tk and its stub table.
*/
@@ -3343,7 +3336,7 @@ Initialize(
* an alternate [tkInit] command before calling Tk_Init().
*/
- code = Tcl_Eval(interp,
+ code = Tcl_EvalEx(interp,
"if {[namespace which -command tkInit] eq \"\"} {\n\
proc tkInit {} {\n\
global tk_library tk_version tk_patchLevel\n\
@@ -3351,7 +3344,7 @@ Initialize(
tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\
}\n\
}\n\
-tkInit");
+tkInit", -1, 0);
}
if (code == TCL_OK) {
/*
@@ -3397,7 +3390,7 @@ Tk_PkgInitStubsCheck(
const char * version,
int exact)
{
- const char *actualVersion = Tcl_PkgRequire(interp, "Tk", version, 0);
+ const char *actualVersion = Tcl_PkgRequireEx(interp, "Tk", version, 0, NULL);
if (exact && actualVersion) {
const char *p = version;
@@ -3409,11 +3402,11 @@ Tk_PkgInitStubsCheck(
if (count == 1) {
if (0 != strncmp(version, actualVersion, strlen(version))) {
/* Construct error message */
- Tcl_PkgPresent(interp, "Tk", version, 1);
+ Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
return NULL;
}
} else {
- return Tcl_PkgPresent(interp, "Tk", version, 1);
+ return Tcl_PkgPresentEx(interp, "Tk", version, 1, NULL);
}
}
return actualVersion;
diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c
index 2954184..bc44f25 100644
--- a/generic/ttk/ttkButton.c
+++ b/generic/ttk/ttkButton.c
@@ -413,8 +413,8 @@ typedef struct
static Tk_OptionSpec CheckbuttonOptionSpecs[] =
{
{TK_OPTION_STRING, "-variable", "variable", "Variable",
- "", Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
- TK_OPTION_DONT_SET_DEFAULT,0,0},
+ NULL, Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
+ TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-onvalue", "onValue", "OnValue",
"1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1,
0,0,0},
diff --git a/generic/ttk/ttkCache.c b/generic/ttk/ttkCache.c
index 39c76e0..0ae2372 100644
--- a/generic/ttk/ttkCache.c
+++ b/generic/ttk/ttkCache.c
@@ -270,7 +270,7 @@ static Tcl_Obj *Ttk_Use(
} else {
Tcl_DecrRefCount(cacheObj);
Tcl_SetHashValue(entryPtr, NULL);
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, TCL_ERROR);
return NULL;
}
}
@@ -341,7 +341,7 @@ Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
Tcl_SetHashValue(entryPtr, image);
if (!image) {
- Tcl_BackgroundError(cache->interp);
+ Tcl_BackgroundException(cache->interp, TCL_ERROR);
}
return image;
diff --git a/generic/ttk/ttkClamTheme.c b/generic/ttk/ttkClamTheme.c
index 572f630..15ebcb7 100644
--- a/generic/ttk/ttkClamTheme.c
+++ b/generic/ttk/ttkClamTheme.c
@@ -12,7 +12,7 @@
* off-by-one error in the end point. This is especially apparent with this
* theme. Defining this macro as true handles this case.
*/
-#if defined(WIN32) && !defined(WIN32_XDRAWLINE_HACK)
+#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK)
# define WIN32_XDRAWLINE_HACK 1
#else
# define WIN32_XDRAWLINE_HACK 0
diff --git a/generic/ttk/ttkDecls.h b/generic/ttk/ttkDecls.h
index 3ff2f62..6701724 100644
--- a/generic/ttk/ttkDecls.h
+++ b/generic/ttk/ttkDecls.h
@@ -13,7 +13,7 @@ extern const char *TtkInitializeStubs(
interp, TTK_VERSION, TTK_STUBS_EPOCH, TTK_STUBS_REVISION)
#else
-#define Ttk_InitStubs(interp) Tcl_PkgRequire(interp, "Ttk", TTK_VERSION, 0)
+#define Ttk_InitStubs(interp) Tcl_PkgRequireEx(interp, "Ttk", TTK_VERSION, 0, NULL)
#endif
@@ -23,6 +23,10 @@ extern const char *TtkInitializeStubs(
#define TTK_STUBS_EPOCH 0
#define TTK_STUBS_REVISION 31
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* Exported function declarations:
*/
@@ -133,7 +137,7 @@ typedef struct TtkStubs {
int magic;
int epoch;
int revision;
- const struct TtkStubHooks *hooks;
+ void *hooks;
Ttk_Theme (*ttk_GetTheme) (Tcl_Interp *interp, const char *name); /* 0 */
Ttk_Theme (*ttk_GetDefaultTheme) (Tcl_Interp *interp); /* 1 */
@@ -178,10 +182,8 @@ typedef struct TtkStubs {
int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); /* 40 */
} TtkStubs;
-#ifdef __cplusplus
-extern "C" {
-#endif
extern const TtkStubs *ttkStubsPtr;
+
#ifdef __cplusplus
}
#endif
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
index d2deee8..81f8126 100644
--- a/generic/ttk/ttkDefaultTheme.c
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -12,7 +12,7 @@
#include <X11/Xutil.h>
#include "ttkTheme.h"
-#if defined(WIN32)
+#if defined(_WIN32)
static const int WIN32_XDRAWLINE_HACK = 1;
#else
static const int WIN32_XDRAWLINE_HACK = 0;
@@ -722,8 +722,8 @@ static void MenubuttonArrowElementDraw(
int width = 0, height = 0;
Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
- Tcl_GetIndexFromObj(NULL, arrow->directionObj, directionStrings,
- ""/*message*/, 0/*flags*/, &postDirection);
+ Tcl_GetIndexFromObjStruct(NULL, arrow->directionObj, directionStrings,
+ sizeof(char *), ""/*message*/, 0/*flags*/, &postDirection);
/* ... this might not be such a great idea ... */
switch (postDirection) {
diff --git a/generic/ttk/ttkElements.c b/generic/ttk/ttkElements.c
index 22af1d6..5c95dba 100644
--- a/generic/ttk/ttkElements.c
+++ b/generic/ttk/ttkElements.c
@@ -1145,7 +1145,7 @@ static void TabElementDraw(
Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
pts, 6, Convex, CoordModeOrigin);
-#ifndef WIN32
+#ifndef _WIN32
/*
* Account for whether XDrawLines draws endpoints by platform
*/
@@ -1275,7 +1275,7 @@ void TtkElements_Init(Tcl_Interp *interp)
/*
* Register "default" as a user-loadable theme (for now):
*/
- Tcl_PkgProvide(interp, "ttk::theme::default", TTK_VERSION);
+ Tcl_PkgProvideEx(interp, "ttk::theme::default", TTK_VERSION, NULL);
}
/*EOF*/
diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c
index a962662..f395649 100644
--- a/generic/ttk/ttkEntry.c
+++ b/generic/ttk/ttkEntry.c
@@ -652,7 +652,7 @@ static void EntryRevalidateBG(Entry *entryPtr, VREASON reason)
{
Tcl_Interp *interp = entryPtr->core.interp;
if (EntryRevalidate(interp, entryPtr, reason) == TCL_ERROR) {
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, TCL_ERROR);
}
}
@@ -758,8 +758,8 @@ static int EntrySetValue(Entry *entryPtr, const char *value)
Tcl_GetString(entryPtr->entry.textVariableObj);
if (textVarName && *textVarName) {
entryPtr->core.flags |= SYNCING_VARIABLE;
- value = Tcl_SetVar(entryPtr->core.interp, textVarName,
- value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
+ value = Tcl_SetVar2(entryPtr->core.interp, textVarName,
+ NULL, value, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
entryPtr->core.flags &= ~SYNCING_VARIABLE;
if (!value || WidgetDestroyed(&entryPtr->core)) {
return TCL_ERROR;
@@ -786,7 +786,7 @@ static void EntryTextVariableTrace(void *recordPtr, const char *value)
}
if (entryPtr->core.flags & SYNCING_VARIABLE) {
- /* Trace was fired due to Tcl_SetVar call in EntrySetValue.
+ /* Trace was fired due to Tcl_SetVar2 call in EntrySetValue.
* Don't do anything.
*/
return;
@@ -1314,8 +1314,8 @@ EntryIndex(
int *indexPtr) /* Return value */
{
# define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
- int length;
- const char *string = Tcl_GetStringFromObj(indexObj, &length);
+ const char *string = Tcl_GetString(indexObj);
+ size_t length = indexObj->length;
if (strncmp(string, "end", length) == 0) {
*indexPtr = entryPtr->entry.numChars;
@@ -1644,6 +1644,14 @@ static int EntryXViewCommand(
void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
Entry *entryPtr = recordPtr;
+ if (objc == 3) {
+ int newFirst;
+ if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst);
+ return TCL_OK;
+ }
return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle);
}
diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl
index 269d3ef..56ba2fa 100644
--- a/generic/ttk/ttkGenStubs.tcl
+++ b/generic/ttk/ttkGenStubs.tcl
@@ -12,7 +12,7 @@
#
# SOURCE: tcl/tools/genStubs.tcl, revision 1.44
#
-# CHANGES:
+# CHANGES:
# + Second argument to "declare" is used as a status guard
# instead of a platform guard.
# + Allow trailing semicolon in function declarations
@@ -290,14 +290,14 @@ proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} {
set text ""
switch $plat {
win {
- append text "#ifdef __WIN32__ /* WIN */\n${iftxt}"
+ 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)\
+ append text "#if !defined(_WIN32) && !defined(MAC_OSX_TCL)\
/* UNIX */\n${iftxt}"
if {$eltxt ne ""} {
append text "#else /* UNIX */\n${eltxt}"
@@ -319,7 +319,7 @@ proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} {
append text "#endif /* AQUA */\n"
}
x11 {
- append text "#if !(defined(__WIN32__) || defined(MAC_OSX_TK))\
+ append text "#if !(defined(_WIN32) || defined(MAC_OSX_TK))\
/* X11 */\n${iftxt}"
if {$eltxt ne ""} {
append text "#else /* X11 */\n${eltxt}"
@@ -572,8 +572,8 @@ proc genStubs::makeSlot {name decl index} {
append text $rtype " *" $lfname "; /* $index */\n"
return $text
}
- if {[string range $rtype end-7 end] eq "CALLBACK"} {
- append text [string trim [string range $rtype 0 end-8]] " (CALLBACK *" $lfname ") "
+ 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 ") "
}
@@ -678,7 +678,7 @@ proc genStubs::addGuard {status text} {
set upName [string toupper $libraryName]
switch -- $status {
- current {
+ current {
# No change
}
deprecated {
@@ -691,7 +691,7 @@ proc genStubs::addGuard {status text} {
puts stderr "Unrecognized status code $status"
}
}
- return $text
+ return $text
}
proc genStubs::ifdeffed {macro text} {
@@ -769,10 +769,12 @@ proc genStubs::emitHeader {name} {
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 ${capName}StubHooks {\n"
+ append text "\ntypedef struct {\n"
foreach hook $hooks($name) {
set capHook [string toupper [string index $hook 0]]
append capHook [string range $hook 1 end]
@@ -786,14 +788,17 @@ proc genStubs::emitHeader {name} {
append text " int epoch;\n"
append text " int revision;\n"
}
- append text " const struct ${capName}StubHooks *hooks;\n\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 "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
- append text "extern const ${capName}Stubs *${name}StubsPtr;\n"
+ append text "extern const ${capName}Stubs *${name}StubsPtr;\n\n"
append text "#ifdef __cplusplus\n}\n#endif\n"
emitMacros $name text
diff --git a/generic/ttk/ttkImage.c b/generic/ttk/ttkImage.c
index 1d455d9..a5a3a52 100644
--- a/generic/ttk/ttkImage.c
+++ b/generic/ttk/ttkImage.c
@@ -36,7 +36,7 @@ static void NullImageChanged(ClientData clientData,
/* TtkGetImageSpec --
* Constructs a Ttk_ImageSpec * from a Tcl_Obj *.
- * Result must be released using TtkFreeImageSpec.
+ * Result must be released using TtkFreeImageSpec.
*
* TODO: Need a variant of this that takes a user-specified ImageChanged proc
*/
@@ -364,8 +364,8 @@ Ttk_CreateImageElement(
}
#endif
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
- "option", 0, &option) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
+ sizeof(char *), "option", 0, &option) != TCL_OK) {
goto error;
}
diff --git a/generic/ttk/ttkInit.c b/generic/ttk/ttkInit.c
index 78676c6..dc6e994 100644
--- a/generic/ttk/ttkInit.c
+++ b/generic/ttk/ttkInit.c
@@ -21,8 +21,8 @@ int Ttk_GetButtonDefaultStateFromObj(
Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
{
*statePtr = TTK_BUTTON_DEFAULT_DISABLED;
- return Tcl_GetIndexFromObj(interp, objPtr,
- ttkDefaultStrings, "default state", 0, statePtr);
+ return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
+ sizeof(char *), "default state", 0, statePtr);
}
/*
@@ -38,8 +38,8 @@ int Ttk_GetCompoundFromObj(
Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
{
*statePtr = TTK_COMPOUND_NONE;
- return Tcl_GetIndexFromObj(interp, objPtr,
- ttkCompoundStrings, "compound layout", 0, statePtr);
+ return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
+ sizeof(char *), "compound layout", 0, statePtr);
}
/*
@@ -54,8 +54,8 @@ int Ttk_GetOrientFromObj(
Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr)
{
*resultPtr = TTK_ORIENT_HORIZONTAL;
- return Tcl_GetIndexFromObj(interp, objPtr,
- ttkOrientStrings, "orientation", 0, resultPtr);
+ return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkOrientStrings,
+ sizeof(char *), "orientation", 0, resultPtr);
}
/*
@@ -65,18 +65,18 @@ int Ttk_GetOrientFromObj(
static const char *ttkStateStrings[] = {
"normal", "readonly", "disabled", "active", NULL
};
-enum {
+enum {
TTK_COMPAT_STATE_NORMAL,
TTK_COMPAT_STATE_READONLY,
TTK_COMPAT_STATE_DISABLED,
TTK_COMPAT_STATE_ACTIVE
};
-/* TtkCheckStateOption --
+/* TtkCheckStateOption --
* Handle -state compatibility option.
*
- * NOTE: setting -state disabled / -state enabled affects the
- * widget state, but the internal widget state does *not* affect
+ * NOTE: setting -state disabled / -state enabled affects the
+ * widget state, but the internal widget state does *not* affect
* the value of the -state option.
* This option is present for compatibility only.
*/
@@ -86,7 +86,8 @@ void TtkCheckStateOption(WidgetCore *corePtr, Tcl_Obj *objPtr)
unsigned all = TTK_STATE_DISABLED|TTK_STATE_READONLY|TTK_STATE_ACTIVE;
# define SETFLAGS(f) TtkWidgetChangeState(corePtr, f, all^f)
- (void)Tcl_GetIndexFromObj(NULL,objPtr,ttkStateStrings,"",0,&stateOption);
+ (void)Tcl_GetIndexFromObjStruct(NULL, objPtr, ttkStateStrings,
+ sizeof(char *), "", 0, &stateOption);
switch (stateOption) {
case TTK_COMPAT_STATE_NORMAL:
default:
@@ -174,7 +175,7 @@ int TtkGetOptionValue(
* type name dbName dbClass default objOffset intOffset flags clientData mask
*/
-/* public */
+/* public */
Tk_OptionSpec ttkCoreOptionSpecs[] =
{
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL,
diff --git a/generic/ttk/ttkLabel.c b/generic/ttk/ttkLabel.c
index 0f71970..1037840 100644
--- a/generic/ttk/ttkLabel.c
+++ b/generic/ttk/ttkLabel.c
@@ -293,6 +293,7 @@ static void ImageCleanup(ImageElement *image)
TtkFreeImageSpec(image->imageSpec);
}
+#ifndef MAC_OSX_TK
/*
* StippleOver --
* Draw a stipple over the image area, to make it look "grayed-out"
@@ -317,6 +318,7 @@ static void StippleOver(
Tk_FreeBitmapFromObj(tkwin, image->stippleObj);
}
}
+#endif
static void ImageDraw(
ImageElement *image, Tk_Window tkwin,Drawable d,Ttk_Box b,Ttk_State state)
@@ -486,6 +488,7 @@ static Ttk_ElementOptionSpec LabelElementOptions[] = {
* Calculate the text, image, and total width and height.
*/
+#undef MAX
#define MAX(a,b) ((a) > (b) ? a : b);
static void LabelSetup(
LabelElement *c, Tk_Window tkwin, Ttk_State state)
diff --git a/generic/ttk/ttkLayout.c b/generic/ttk/ttkLayout.c
index de9d795..ba24589 100644
--- a/generic/ttk/ttkLayout.c
+++ b/generic/ttk/ttkLayout.c
@@ -636,8 +636,8 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
if (optName[0] != '-')
break;
- if (Tcl_GetIndexFromObj(
- interp, objv[i], optStrings, "option", 0, &option)
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings,
+ sizeof(char *), "option", 0, &option)
!= TCL_OK)
{
goto error;
@@ -653,8 +653,8 @@ Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr)
switch (option) {
case OP_SIDE: /* <<NOTE-PACKSIDE>> */
- if (Tcl_GetIndexFromObj(interp, objv[i], packSideStrings,
- "side", 0, &value) != TCL_OK)
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], packSideStrings,
+ sizeof(char *), "side", 0, &value) != TCL_OK)
{
goto error;
}
diff --git a/generic/ttk/ttkManager.c b/generic/ttk/ttkManager.c
index cf98a6d..24a0fb1 100644
--- a/generic/ttk/ttkManager.c
+++ b/generic/ttk/ttkManager.c
@@ -237,7 +237,7 @@ void Ttk_DeleteManager(Ttk_Manager *mgr)
ckfree(mgr->slaves);
}
- Tk_CancelIdleCall(ManagerIdleProc, mgr);
+ Tcl_CancelIdleCall(ManagerIdleProc, mgr);
ckfree(mgr);
}
diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c
index 6849135..81a8b64 100644
--- a/generic/ttk/ttkNotebook.c
+++ b/generic/ttk/ttkNotebook.c
@@ -901,7 +901,7 @@ static int NotebookAddCommand(
if (tab->state == TAB_STATE_HIDDEN) {
tab->state = TAB_STATE_NORMAL;
}
- if (ConfigureTab(interp, nb, tab, slaveWindow, objc-4,objv+4) != TCL_OK) {
+ if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) {
return TCL_ERROR;
}
@@ -1058,9 +1058,8 @@ static int NotebookIdentifyCommand(
if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
- || (objc == 5 &&
- Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what)
- != TCL_OK)
+ || (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
+ sizeof(char *), "option", 0, &what) != TCL_OK)
) {
return TCL_ERROR;
}
diff --git a/generic/ttk/ttkPanedwindow.c b/generic/ttk/ttkPanedwindow.c
index f4b14c9..adc2aef 100644
--- a/generic/ttk/ttkPanedwindow.c
+++ b/generic/ttk/ttkPanedwindow.c
@@ -731,9 +731,8 @@ static int PanedIdentifyCommand(
if ( Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
|| Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK
- || (objc == 5 &&
- Tcl_GetIndexFromObj(interp, objv[2], whatTable, "option", 0, &what)
- != TCL_OK)
+ || (objc == 5 && Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
+ sizeof(char *), "option", 0, &what) != TCL_OK)
) {
return TCL_ERROR;
}
diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c
index c02b868..2bd3ddb 100644
--- a/generic/ttk/ttkScroll.c
+++ b/generic/ttk/ttkScroll.c
@@ -7,7 +7,7 @@
*
* Scrollable interface:
*
- * + 'first' is controlled by [xy]view widget command
+ * + 'first' is controlled by [xy]view widget command
* and other scrolling commands like 'see';
* + 'total' depends on widget contents;
* + 'last' depends on first, total, and widget size.
@@ -16,15 +16,15 @@
*
* 1. User adjusts scrollbar, scrollbar widget calls its -command
* 2. Scrollbar -command invokes the scrollee [xy]view widget method
- * 3. TtkScrollviewCommand calls TtkScrollTo(), which updates
+ * 3. TtkScrollviewCommand calls TtkScrollTo(), which updates
* 'first' and schedules a redisplay.
- * 4. Once the scrollee knows 'total' and 'last' (typically in
- * the LayoutProc), call TtkScrolled(h,first,last,total) to
+ * 4. Once the scrollee knows 'total' and 'last' (typically in
+ * the LayoutProc), call TtkScrolled(h,first,last,total) to
* synchronize the scrollbar.
* 5. The scrollee -[xy]scrollcommand is called (in an idle callback)
* 6. Which calls the scrollbar 'set' method and redisplays the scrollbar.
*
- * If the scrollee has internal scrolling (e.g., a 'see' method),
+ * If the scrollee has internal scrolling (e.g., a 'see' method),
* it should TtkScrollTo() directly (step 2).
*
* If the widget value changes, it should call TtkScrolled() (step 4).
@@ -34,7 +34,7 @@
* TtkScrollbarUpdateRequired, which will invoke step (5) (@@@ Fix this)
*/
-#include <tk.h>
+#include <tkInt.h>
#include "ttkTheme.h"
#include "ttkWidget.h"
@@ -78,6 +78,7 @@ static int UpdateScrollbar(Tcl_Interp *interp, ScrollHandle h)
char arg1[TCL_DOUBLE_SPACE + 2];
char arg2[TCL_DOUBLE_SPACE + 2];
int code;
+ Tcl_DString buf;
h->flags &= ~SCROLL_UPDATE_REQUIRED;
@@ -88,9 +89,14 @@ static int UpdateScrollbar(Tcl_Interp *interp, ScrollHandle h)
arg1[0] = arg2[0] = ' ';
Tcl_PrintDouble(interp, (double)s->first / s->total, arg1+1);
Tcl_PrintDouble(interp, (double)s->last / s->total, arg2+1);
+ Tcl_DStringInit(&buf);
+ Tcl_DStringAppend(&buf, s->scrollCmd, -1);
+ Tcl_DStringAppend(&buf, arg1, -1);
+ Tcl_DStringAppend(&buf, arg2, -1);
Tcl_Preserve(corePtr);
- code = Tcl_VarEval(interp, s->scrollCmd, arg1, arg2, NULL);
+ code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
+ Tcl_DStringFree(&buf);
if (WidgetDestroyed(corePtr)) {
Tcl_Release(corePtr);
return TCL_ERROR;
@@ -124,7 +130,7 @@ static void UpdateScrollbarBG(ClientData clientData)
Tcl_Preserve((ClientData) interp);
code = UpdateScrollbar(interp, h);
if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, code);
}
Tcl_Release((ClientData) interp);
}
@@ -135,7 +141,7 @@ static void UpdateScrollbarBG(ClientData clientData)
void TtkScrolled(ScrollHandle h, int first, int last, int total)
{
Scrollable *s = h->scrollPtr;
-
+
/* Sanity-check inputs:
*/
if (total <= 0) {
diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c
index 5097abc..2f95962 100644
--- a/generic/ttk/ttkTheme.c
+++ b/generic/ttk/ttkTheme.c
@@ -508,8 +508,9 @@ static void ThemeChangedProc(ClientData clientData)
static char ThemeChangedScript[] = "ttk::ThemeChanged";
StylePackageData *pkgPtr = clientData;
- if (Tcl_GlobalEval(pkgPtr->interp, ThemeChangedScript) != TCL_OK) {
- Tcl_BackgroundError(pkgPtr->interp);
+ int code = Tcl_EvalEx(pkgPtr->interp, ThemeChangedScript, -1, TCL_EVAL_GLOBAL);
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(pkgPtr->interp, code);
}
pkgPtr->themeChangePending = 0;
}
@@ -1393,8 +1394,8 @@ static int StyleThemeCreateCmd(
for (i=4; i < objc; i +=2) {
int option;
- if (Tcl_GetIndexFromObj(
- interp, objv[i], optStrings, "option", 0, &option) != TCL_OK)
+ if (Tcl_GetIndexFromObjStruct(interp, objv[i], optStrings,
+ sizeof(char *), "option", 0, &option) != TCL_OK)
{
return TCL_ERROR;
}
@@ -1673,7 +1674,7 @@ StyleObjCmd(
return Ttk_InvokeEnsemble(StyleEnsemble, 1, clientData,interp,objc,objv);
}
-MODULE_SCOPE
+MODULE_SCOPE
int Ttk_InvokeEnsemble( /* Run an ensemble command */
const Ttk_Ensemble *ensemble, int cmdIndex,
void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
diff --git a/generic/ttk/ttkTrace.c b/generic/ttk/ttkTrace.c
index e6234b8..ba66db4 100644
--- a/generic/ttk/ttkTrace.c
+++ b/generic/ttk/ttkTrace.c
@@ -54,7 +54,7 @@ VarTraceProc(
ckfree((ClientData)tracePtr);
return NULL;
}
- Tcl_TraceVar(interp, name,
+ Tcl_TraceVar2(interp, name, NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
VarTraceProc, clientData);
tracePtr->callback(tracePtr->clientData, NULL);
@@ -94,8 +94,8 @@ Ttk_TraceHandle *Ttk_TraceVariable(
h->clientData = clientData;
h->callback = callback;
- status = Tcl_TraceVar(interp, Tcl_GetString(varnameObj),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ status = Tcl_TraceVar2(interp, Tcl_GetString(varnameObj),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
VarTraceProc, (ClientData)h);
if (status != TCL_OK) {
@@ -150,8 +150,8 @@ void Ttk_UntraceVariable(Ttk_TraceHandle *h)
h->interp = NULL;
return;
}
- Tcl_UntraceVar(h->interp, Tcl_GetString(h->varnameObj),
- TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+ Tcl_UntraceVar2(h->interp, Tcl_GetString(h->varnameObj),
+ NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
VarTraceProc, (ClientData)h);
Tcl_DecrRefCount(h->varnameObj);
ckfree(h);
diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c
index dc0206c..d957ad2 100644
--- a/generic/ttk/ttkTreeview.c
+++ b/generic/ttk/ttkTreeview.c
@@ -340,8 +340,8 @@ static int GetEnumSetFromObj(
for (i = 0; i < objc; ++i) {
int index;
- if (TCL_OK != Tcl_GetIndexFromObj(
- interp, objv[i], table, "value", TCL_EXACT, &index))
+ if (TCL_OK != Tcl_GetIndexFromObjStruct(interp, objv[i], table,
+ sizeof(char *), "value", TCL_EXACT, &index))
{
return TCL_ERROR;
}
@@ -2287,8 +2287,8 @@ static int TreeviewIdentifyCommand(
return TCL_ERROR;
}
- if ( Tcl_GetIndexFromObj(interp, objv[2],
- submethodStrings, "command", TCL_EXACT, &submethod) != TCL_OK
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], submethodStrings,
+ sizeof(char *), "command", TCL_EXACT, &submethod) != TCL_OK
|| Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK
|| Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK
) {
@@ -2955,8 +2955,8 @@ static int TreeviewSelectionCommand(
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[2], selopStrings,
- "selection operation", 0, &selop) != TCL_OK) {
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], selopStrings,
+ sizeof(char *), "selection operation", 0, &selop) != TCL_OK) {
return TCL_ERROR;
}
@@ -3170,6 +3170,8 @@ static int TreeviewTagAddCommand(
AddTag(items[i], tag);
}
+ TtkRedisplayWidget(&tv->core);
+
return TCL_OK;
}
@@ -3214,6 +3216,9 @@ static int TreeviewTagRemoveCommand(
item=NextPreorder(item);
}
}
+
+ TtkRedisplayWidget(&tv->core);
+
return TCL_OK;
}
diff --git a/generic/ttk/ttkWidget.c b/generic/ttk/ttkWidget.c
index 016653d..c50efc5 100644
--- a/generic/ttk/ttkWidget.c
+++ b/generic/ttk/ttkWidget.c
@@ -198,7 +198,7 @@ WidgetInstanceObjCmdDeleted(ClientData clientData)
* Final cleanup for widget; called via Tcl_EventuallyFree().
*/
static void
-FreeWidget(char *memPtr)
+FreeWidget(void *memPtr)
{
ckfree(memPtr);
}
@@ -231,7 +231,7 @@ DestroyWidget(WidgetCore *corePtr)
/* NB: this can reenter the interpreter via a command traces */
Tcl_DeleteCommandFromToken(corePtr->interp, cmd);
}
- Tcl_EventuallyFree(corePtr, FreeWidget);
+ Tcl_EventuallyFree(corePtr, (Tcl_FreeProc *) FreeWidget);
}
/*
@@ -766,8 +766,8 @@ int TtkWidgetIdentifyCommand(
}
if (objc == 5) {
/* $w identify element $x $y */
- if (Tcl_GetIndexFromObj(interp,objv[2],whatTable,"option",0,&what)
- != TCL_OK)
+ if (Tcl_GetIndexFromObjStruct(interp, objv[2], whatTable,
+ sizeof(char *), "option", 0, &what) != TCL_OK)
{
return TCL_ERROR;
}
diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h
index 9e9ab69..e4dd712 100644
--- a/generic/ttk/ttkWidget.h
+++ b/generic/ttk/ttkWidget.h
@@ -260,7 +260,7 @@ MODULE_SCOPE int TtkGetLabelAnchorFromObj(
* Platform-specific initialization.
*/
-#if defined(__WIN32__)
+#ifdef _WIN32
#define Ttk_PlatformInit Ttk_WinPlatformInit
MODULE_SCOPE int Ttk_PlatformInit(Tcl_Interp *);
#elif defined(MAC_OSX_TK)