summaryrefslogtreecommitdiffstats
path: root/generic/tkText.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkText.c')
-rw-r--r--generic/tkText.c1090
1 files changed, 643 insertions, 447 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index 8edf82d..412a7f2 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -73,6 +73,16 @@ static const char *const tabStyleStrings[] = {
};
/*
+ * The 'TkTextInsertUnfocussed' enum in tkText.h is used to define a type for
+ * the -insertunfocussed option of the Text widget. These values are used as
+ * indice into the string table below.
+ */
+
+static const char *const insertUnfocussedStrings[] = {
+ "hollow", "none", "solid", NULL
+};
+
+/*
* The following functions and custom option type are used to define the
* "line" option type, and thereby handle the text widget '-startline',
* '-endline' configuration options which are of that type.
@@ -112,15 +122,16 @@ static const Tk_ObjCustomOption lineOption = {
static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators",
"AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1,
- Tk_Offset(TkText, autoSeparators), 0, 0, 0},
+ Tk_Offset(TkText, autoSeparators),
+ TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BORDER, "-background", "background", "Background",
DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border),
- 0, (ClientData) DEF_TEXT_BG_MONO, 0},
+ 0, DEF_TEXT_BG_MONO, 0},
{TK_OPTION_SYNONYM, "-bd", NULL, NULL,
- NULL, 0, -1, 0, (ClientData) "-borderwidth",
+ NULL, 0, -1, 0, "-borderwidth",
TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_SYNONYM, "-bg", NULL, NULL,
- NULL, 0, -1, 0, (ClientData) "-background", 0},
+ NULL, 0, -1, 0, "-background", 0},
{TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor",
"BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1,
Tk_Offset(TkText, insertCursorType), 0, 0, 0},
@@ -132,12 +143,12 @@ static const Tk_OptionSpec optionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_CUSTOM, "-endline", NULL, NULL,
NULL, -1, Tk_Offset(TkText, end), TK_OPTION_NULL_OK,
- (ClientData) &lineOption, TK_TEXT_LINE_RANGE},
+ &lineOption, TK_TEXT_LINE_RANGE},
{TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
"ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1,
Tk_Offset(TkText, exportSelection), 0, 0, 0},
{TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
- NULL, 0, -1, 0, (ClientData) "-foreground", 0},
+ NULL, 0, -1, 0, "-foreground", 0},
{TK_OPTION_FONT, "-font", "font", "Font",
DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0,
TK_TEXT_LINE_GEOMETRY},
@@ -160,7 +171,7 @@ static const Tk_OptionSpec optionSpecs[] = {
"Foreground",
DEF_TEXT_INACTIVE_SELECT_COLOR,
-1, Tk_Offset(TkText, inactiveSelBorder),
- TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_MONO, 0},
+ TK_OPTION_NULL_OK, DEF_TEXT_SELECT_MONO, 0},
{TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
DEF_TEXT_INSERT_BG,
-1, Tk_Offset(TkText, insertBorder),
@@ -175,11 +186,16 @@ static const Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime),
0, 0, 0},
+ {TK_OPTION_STRING_TABLE,
+ "-insertunfocussed", "insertUnfocussed", "InsertUnfocussed",
+ DEF_TEXT_INSERT_UNFOCUSSED, -1, Tk_Offset(TkText, insertUnfocussed),
+ 0, insertUnfocussedStrings, 0},
{TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth),
0, 0, 0},
{TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo",
- DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0},
+ DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo),
+ TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0,
TK_TEXT_LINE_GEOMETRY},
@@ -189,15 +205,15 @@ static const Tk_OptionSpec optionSpecs[] = {
DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder),
- 0, (ClientData) DEF_TEXT_SELECT_MONO, 0},
+ 0, DEF_TEXT_SELECT_MONO, 0},
{TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
"BorderWidth", DEF_TEXT_SELECT_BD_COLOR,
Tk_Offset(TkText, selBorderWidthPtr),
Tk_Offset(TkText, selBorderWidth),
- TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0},
+ 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_OPTION_NULL_OK, (ClientData) 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",
@@ -211,27 +227,28 @@ static const Tk_OptionSpec optionSpecs[] = {
0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_CUSTOM, "-startline", NULL, NULL,
NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK,
- (ClientData) &lineOption, TK_TEXT_LINE_RANGE},
+ &lineOption, TK_TEXT_LINE_RANGE},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
DEF_TEXT_STATE, -1, Tk_Offset(TkText, state),
- 0, (ClientData) stateStrings, 0},
+ 0, stateStrings, 0},
{TK_OPTION_STRING, "-tabs", "tabs", "Tabs",
DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1,
TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_STRING_TABLE, "-tabstyle", "tabStyle", "TabStyle",
DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle),
- 0, (ClientData) tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
+ 0, tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus),
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_BOOLEAN, "-undo", "undo", "Undo",
- DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0},
+ DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo),
+ TK_OPTION_DONT_SET_DEFAULT, 0 , 0},
{TK_OPTION_INT, "-width", "width", "Width",
DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0,
TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap",
DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode),
- 0, (ClientData) wrapStrings, TK_TEXT_LINE_GEOMETRY},
+ 0, wrapStrings, TK_TEXT_LINE_GEOMETRY},
{TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd),
TK_OPTION_NULL_OK, 0, 0},
@@ -387,7 +404,9 @@ static Tcl_Obj * TextGetText(const TkText *textPtr,
const TkTextIndex *index1,
const TkTextIndex *index2, int visibleOnly);
static void GenerateModifiedEvent(TkText *textPtr);
+static void GenerateUndoStackEvent(TkText *textPtr);
static void UpdateDirtyFlag(TkSharedText *sharedPtr);
+static void RunAfterSyncCmd(ClientData clientData);
static void TextPushUndoAction(TkText *textPtr,
Tcl_Obj *undoString, int insert,
const TkTextIndex *index1Ptr,
@@ -412,7 +431,7 @@ static SearchLineIndexProc TextSearchGetLineIndex;
* can be invoked from generic window code.
*/
-static Tk_ClassProcs textClass = {
+static const Tk_ClassProcs textClass = {
sizeof(Tk_ClassProcs), /* size */
TextWorldChangedCallback, /* worldChangedProc */
NULL, /* createProc */
@@ -443,10 +462,10 @@ Tk_TextObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Tk_Window tkwin = (Tk_Window) clientData;
+ Tk_Window tkwin = clientData;
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
+ Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
return TCL_ERROR;
}
@@ -505,7 +524,7 @@ CreateWidget(
* and 'insert', 'current' mark pointers are all NULL to start.
*/
- textPtr = (TkText *) ckalloc(sizeof(TkText));
+ textPtr = ckalloc(sizeof(TkText));
memset(textPtr, 0, sizeof(TkText));
textPtr->tkwin = newWin;
@@ -513,10 +532,10 @@ CreateWidget(
textPtr->interp = interp;
textPtr->widgetCmd = Tcl_CreateObjCommand(interp,
Tk_PathName(textPtr->tkwin), TextWidgetObjCmd,
- (ClientData) textPtr, TextCmdDeletedProc);
+ textPtr, TextCmdDeletedProc);
if (sharedPtr == NULL) {
- sharedPtr = (TkSharedText *) ckalloc(sizeof(TkSharedText));
+ sharedPtr = ckalloc(sizeof(TkSharedText));
memset(sharedPtr, 0, sizeof(TkSharedText));
sharedPtr->refCount = 0;
@@ -528,7 +547,7 @@ CreateWidget(
Tcl_InitHashTable(&sharedPtr->windowTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&sharedPtr->imageTable, TCL_STRING_KEYS);
sharedPtr->undoStack = TkUndoInitStack(interp,0);
- sharedPtr->undo = 1;
+ sharedPtr->undo = 0;
sharedPtr->isDirty = 0;
sharedPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
sharedPtr->autoSeparators = 1;
@@ -614,7 +633,7 @@ CreateWidget(
*/
textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel", NULL);
- textPtr->selTagPtr->reliefString = (char *)
+ textPtr->selTagPtr->reliefString =
ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF));
strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF);
Tk_GetRelief(interp, DEF_TEXT_SELECT_RELIEF, &textPtr->selTagPtr->relief);
@@ -629,18 +648,18 @@ CreateWidget(
optionTable = Tk_CreateOptionTable(interp, optionSpecs);
Tk_SetClass(textPtr->tkwin, "Text");
- Tk_SetClassProcs(textPtr->tkwin, &textClass, (ClientData) textPtr);
+ Tk_SetClassProcs(textPtr->tkwin, &textClass, textPtr);
textPtr->optionTable = optionTable;
Tk_CreateEventHandler(textPtr->tkwin,
ExposureMask|StructureNotifyMask|FocusChangeMask,
- TextEventProc, (ClientData) textPtr);
+ TextEventProc, textPtr);
Tk_CreateEventHandler(textPtr->tkwin, KeyPressMask|KeyReleaseMask
|ButtonPressMask|ButtonReleaseMask|EnterWindowMask
|LeaveWindowMask|PointerMotionMask|VirtualEventMask,
- TkTextBindProc, (ClientData) textPtr);
+ TkTextBindProc, textPtr);
Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING,
- TextFetchSelection, (ClientData) textPtr, XA_STRING);
+ TextFetchSelection, textPtr, XA_STRING);
if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin)
!= TCL_OK) {
@@ -652,8 +671,7 @@ CreateWidget(
return TCL_ERROR;
}
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1));
+ Tcl_SetObjResult(interp, TkNewWindowObj(textPtr->tkwin));
return TCL_OK;
}
@@ -682,31 +700,32 @@ TextWidgetObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
int result = TCL_OK;
int index;
- static const char *optionStrings[] = {
+ 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) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ 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;
}
textPtr->refCount++;
@@ -747,13 +766,13 @@ TextWidgetObjCmd(
} else {
Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr,
textPtr->optionTable, objv[2], textPtr->tkwin);
+
if (objPtr == NULL) {
result = TCL_ERROR;
goto done;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
}
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
}
break;
case TEXT_COMPARE: {
@@ -779,12 +798,7 @@ TextWidgetObjCmd(
if ((p[1] == '=') && (p[2] == 0)) {
value = (relation <= 0);
} else if (p[1] != 0) {
- compareError:
- Tcl_AppendResult(interp, "bad comparison operator \"",
- Tcl_GetString(objv[3]),
- "\": must be <, <=, ==, >=, >, or !=", NULL);
- result = TCL_ERROR;
- goto done;
+ goto compareError;
}
} else if (p[0] == '>') {
value = (relation > 0);
@@ -802,18 +816,26 @@ TextWidgetObjCmd(
}
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
break;
+
+ compareError:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad comparison operator \"%s\": must be"
+ " <, <=, ==, >=, >, or !=", Tcl_GetString(objv[3])));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "COMPARISON", NULL);
+ result = TCL_ERROR;
+ goto done;
}
case TEXT_CONFIGURE:
if (objc <= 3) {
Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr,
textPtr->optionTable, ((objc == 3) ? objv[2] : NULL),
textPtr->tkwin);
+
if (objPtr == NULL) {
result = TCL_ERROR;
goto done;
- } else {
- Tcl_SetObjResult(interp, objPtr);
}
+ Tcl_SetObjResult(interp, objPtr);
} else {
result = ConfigureText(interp, textPtr, objc-2, objv+2);
}
@@ -824,7 +846,8 @@ TextWidgetObjCmd(
Tcl_Obj *objPtr = NULL;
if (objc < 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "?options? index1 index2");
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-option value ...? index1 index2");
result = TCL_ERROR;
goto done;
}
@@ -842,19 +865,12 @@ 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] != '-') {
- badOption:
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad option \"",
- Tcl_GetString(objv[i]),
- "\" must be -chars, -displaychars, -displayindices, ",
- "-displaylines, -indices, -lines, -update, ",
- "-xpixels, or -ypixels", NULL);
- result = TCL_ERROR;
- goto done;
+ goto badOption;
}
c = option[1];
if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) {
@@ -907,43 +923,43 @@ TextWidgetObjCmd(
* We're going to count up all display lines in the logical
* line of 'indexFromPtr' up to, but not including the logical
* line of 'indexToPtr' (except if this line is elided), and
- * then subtract off what came in too much from elided lines,
- * also subtract off what we didn't want from 'from' and add
+ * then subtract off what came in too much from elided lines,
+ * also subtract off what we didn't want from 'from' and add
* on what we didn't count from 'to'.
*/
- while (TkTextIndexCmp(&index,indexToPtr) < 0) {
+ while (TkTextIndexCmp(&index,indexToPtr) < 0) {
value += TkTextUpdateOneLine(textPtr, index.linePtr,
- 0, &index, 0);
+ 0, &index, 0);
}
- index2 = index;
-
- /*
- * Now we need to adjust the count to:
- * - subtract off the number of display lines between
- * indexToPtr and index2, since we might have skipped past
- * indexToPtr, if we have several logical lines in a
- * single display line
- * - subtract off the number of display lines overcounted
- * in the first logical line
- * - add on the number of display lines in the last logical
- * line
- * This logic is still ok if both indexFromPtr and indexToPtr
- * are in the same logical line.
- */
-
- index = *indexToPtr;
- index.byteIndex = 0;
- while (TkTextIndexCmp(&index,&index2) < 0) {
- value -= TkTextUpdateOneLine(textPtr, index.linePtr,
- 0, &index, 0);
- }
+ index2 = index;
+
+ /*
+ * Now we need to adjust the count to:
+ * - subtract off the number of display lines between
+ * indexToPtr and index2, since we might have skipped past
+ * indexToPtr, if we have several logical lines in a
+ * single display line
+ * - subtract off the number of display lines overcounted
+ * in the first logical line
+ * - add on the number of display lines in the last logical
+ * line
+ * This logic is still ok if both indexFromPtr and indexToPtr
+ * are in the same logical line.
+ */
+
+ index = *indexToPtr;
+ index.byteIndex = 0;
+ while (TkTextIndexCmp(&index,&index2) < 0) {
+ value -= TkTextUpdateOneLine(textPtr, index.linePtr,
+ 0, &index, 0);
+ }
index.linePtr = indexFromPtr->linePtr;
index.byteIndex = 0;
while (1) {
TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
- if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
+ if (TkTextIndexCmp(&index,indexFromPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -955,7 +971,7 @@ TextWidgetObjCmd(
index.byteIndex = 0;
while (1) {
TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL);
- if (TkTextIndexCmp(&index,indexToPtr) >= 0) {
+ if (TkTextIndexCmp(&index,indexToPtr) >= 0) {
break;
}
TkTextIndexForwBytes(textPtr, &index, 1, &index);
@@ -1033,6 +1049,15 @@ TextWidgetObjCmd(
Tcl_SetObjResult(interp, objPtr);
}
break;
+
+ badOption:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad option \"%s\" must be -chars, -displaychars, "
+ "-displayindices, -displaylines, -indices, -lines, -update, "
+ "-xpixels, or -ypixels", Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_OPTION", NULL);
+ result = TCL_ERROR;
+ goto done;
}
case TEXT_DEBUG:
if (objc > 3) {
@@ -1101,8 +1126,7 @@ TextWidgetObjCmd(
objc -= 2;
objv += 2;
- indices = (TkTextIndex *)
- ckalloc((objc + 1) * sizeof(TkTextIndex));
+ indices = ckalloc((objc + 1) * sizeof(TkTextIndex));
/*
* First pass verifies that all indices are valid.
@@ -1114,7 +1138,7 @@ TextWidgetObjCmd(
if (indexPtr == NULL) {
result = TCL_ERROR;
- ckfree((char *) indices);
+ ckfree(indices);
goto done;
}
indices[i] = *indexPtr;
@@ -1130,7 +1154,7 @@ TextWidgetObjCmd(
COUNT_INDICES);
objc++;
}
- useIdx = (char *) ckalloc((unsigned) objc);
+ useIdx = ckalloc(objc);
memset(useIdx, 0, (unsigned) objc);
/*
@@ -1194,7 +1218,7 @@ TextWidgetObjCmd(
&indices[i+1], 1);
}
}
- ckfree((char *) indices);
+ ckfree(indices);
}
}
break;
@@ -1252,12 +1276,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) {
+ 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++;
@@ -1372,6 +1398,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;
@@ -1392,9 +1428,10 @@ TextWidgetObjCmd(
goto done;
}
if (TkTextIndexCmp(indexFromPtr, indexToPtr) > 0) {
- Tcl_AppendResult(interp, "Index \"", Tcl_GetString(objv[3]),
- "\" before \"", Tcl_GetString(objv[2]),
- "\" in the text", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "index \"%s\" before \"%s\" in the text",
+ Tcl_GetString(objv[3]), Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL);
result = TCL_ERROR;
goto done;
}
@@ -1485,6 +1522,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;
@@ -1502,7 +1572,7 @@ TextWidgetObjCmd(
done:
textPtr->refCount--;
if (textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
}
return result;
}
@@ -1534,11 +1604,11 @@ SharedTextObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- register TkSharedText *sharedPtr = (TkSharedText *) clientData;
+ register TkSharedText *sharedPtr = clientData;
int result = TCL_OK;
int index;
- static const char *optionStrings[] = {
+ static const char *const optionStrings[] = {
"delete", "insert", NULL
};
enum options {
@@ -1546,12 +1616,12 @@ SharedTextObjCmd(
};
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ 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;
}
@@ -1643,7 +1713,7 @@ TextPeerCmd(
Tk_Window tkwin = textPtr->tkwin;
int index;
- static const char *peerOptionStrings[] = {
+ static const char *const peerOptionStrings[] = {
"create", "names", NULL
};
enum peerOptions {
@@ -1651,36 +1721,40 @@ TextPeerCmd(
};
if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
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;
}
- switch ((enum peerOptions)index) {
+ switch ((enum peerOptions) index) {
case PEER_CREATE:
if (objc < 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "pathName ?options?");
+ Tcl_WrongNumArgs(interp, 3, objv, "pathName ?-option value ...?");
return TCL_ERROR;
}
return CreateWidget(textPtr->sharedTextPtr, tkwin, interp, textPtr,
objc-2, objv+2);
case PEER_NAMES: {
TkText *tPtr = textPtr->sharedTextPtr->peers;
+ Tcl_Obj *peersObj;
if (objc > 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ peersObj = Tcl_NewObj();
while (tPtr != NULL) {
if (tPtr != textPtr) {
- Tcl_AppendElement(interp, Tk_PathName(tPtr->tkwin));
+ Tcl_ListObjAppendElement(NULL, peersObj,
+ TkNewWindowObj(tPtr->tkwin));
}
tPtr = tPtr->next;
}
+ Tcl_SetObjResult(interp, peersObj);
}
}
@@ -1877,10 +1951,10 @@ DestroyText(
TkTextDeleteTag(textPtr, textPtr->selTagPtr);
TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
textPtr->insertMarkPtr->body.mark.linePtr);
- ckfree((char *) textPtr->insertMarkPtr);
+ ckfree(textPtr->insertMarkPtr);
TkBTreeUnlinkSegment(textPtr->currentMarkPtr,
textPtr->currentMarkPtr->body.mark.linePtr);
- ckfree((char *) textPtr->currentMarkPtr);
+ ckfree(textPtr->currentMarkPtr);
/*
* Now we've cleaned up everything of relevance to us in the B-tree, so we
@@ -1902,7 +1976,7 @@ DestroyText(
for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->windowTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
TkTextEmbWindowClient *loop;
- TkTextSegment *ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr);
+ TkTextSegment *ewPtr = Tcl_GetHashValue(hPtr);
loop = ewPtr->body.ew.clients;
if (loop->textPtr == textPtr) {
@@ -1934,7 +2008,7 @@ DestroyText(
for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
+ tagPtr = Tcl_GetHashValue(hPtr);
/*
* No need to use 'TkTextDeleteTag' since we've already removed
@@ -1946,7 +2020,7 @@ DestroyText(
Tcl_DeleteHashTable(&sharedTextPtr->tagTable);
for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->markTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- ckfree((char *) Tcl_GetHashValue(hPtr));
+ ckfree(Tcl_GetHashValue(hPtr));
}
Tcl_DeleteHashTable(&sharedTextPtr->markTable);
TkUndoFreeStack(sharedTextPtr->undoStack);
@@ -1957,11 +2031,11 @@ DestroyText(
if (sharedTextPtr->bindingTable != NULL) {
Tk_DeleteBindingTable(sharedTextPtr->bindingTable);
}
- ckfree((char *) sharedTextPtr);
+ ckfree(sharedTextPtr);
}
if (textPtr->tabArrayPtr != NULL) {
- ckfree((char *) textPtr->tabArrayPtr);
+ ckfree(textPtr->tabArrayPtr);
}
if (textPtr->insertBlinkHandler != NULL) {
Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
@@ -1970,8 +2044,12 @@ DestroyText(
textPtr->tkwin = NULL;
textPtr->refCount--;
Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);
+ if (textPtr->afterSyncCmd){
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
+ }
if (textPtr->refCount == 0) {
- ckfree((char *) textPtr);
+ ckfree(textPtr);
}
}
@@ -2019,7 +2097,7 @@ ConfigureText(
textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo;
textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators;
- TkUndoSetDepth(textPtr->sharedTextPtr->undoStack,
+ TkUndoSetMaxDepth(textPtr->sharedTextPtr->undoStack,
textPtr->sharedTextPtr->maxUndo);
/*
@@ -2051,9 +2129,9 @@ ConfigureText(
end = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL);
}
if (start > end) {
- Tcl_AppendResult(interp,
- "-startline must be less than or equal to -endline",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "-startline must be less than or equal to -endline", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "INDEX_ORDER", NULL);
Tk_RestoreSavedOptions(&savedOptions);
return TCL_ERROR;
}
@@ -2086,6 +2164,7 @@ ConfigureText(
/* Nothing tagged with "sel" */
} else {
int line = TkBTreeLinesTo(NULL, search.curIndex.linePtr);
+
if (line < start) {
selChanged = 1;
} else {
@@ -2116,10 +2195,10 @@ ConfigureText(
* Also, clamp the insert and current (unshared) marks to the new
* -startline/-endline range limits of the widget. All other (shared)
* marks are unchanged.
- * The return value of TkTextMarkNameToIndex does not need to be
- * checked: "insert" and "current" marks always exist, and the
- * purpose of the code below precisely is to move them inside the
- * -startline/-endline range.
+ * The return value of TkTextMarkNameToIndex does not need to be
+ * checked: "insert" and "current" marks always exist, and the
+ * purpose of the code below precisely is to move them inside the
+ * -startline/-endline range.
*/
textPtr->sharedTextPtr->stateEpoch++;
@@ -2158,7 +2237,7 @@ ConfigureText(
*/
if (textPtr->tabArrayPtr != NULL) {
- ckfree((char *) textPtr->tabArrayPtr);
+ ckfree(textPtr->tabArrayPtr);
textPtr->tabArrayPtr = NULL;
}
if (textPtr->tabOptionPtr != NULL) {
@@ -2178,12 +2257,20 @@ ConfigureText(
* replaced in the widget record.
*/
- textPtr->selTagPtr->border = textPtr->selBorder;
+ if (textPtr->selTagPtr->selBorder == NULL) {
+ textPtr->selTagPtr->border = textPtr->selBorder;
+ } else {
+ textPtr->selTagPtr->selBorder = textPtr->selBorder;
+ }
if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) {
textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr;
textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth;
}
- textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
+ if (textPtr->selTagPtr->selFgColor == NULL) {
+ textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr;
+ } else {
+ textPtr->selTagPtr->selFgColor = textPtr->selFgColorPtr;
+ }
textPtr->selTagPtr->affectsDisplay = 0;
textPtr->selTagPtr->affectsDisplayGeometry = 0;
if ((textPtr->selTagPtr->elideString != NULL)
@@ -2202,12 +2289,18 @@ ConfigureText(
textPtr->selTagPtr->affectsDisplayGeometry = 1;
}
if ((textPtr->selTagPtr->border != NULL)
+ || (textPtr->selTagPtr->selBorder != NULL)
|| (textPtr->selTagPtr->reliefString != NULL)
|| (textPtr->selTagPtr->bgStipple != None)
|| (textPtr->selTagPtr->fgColor != NULL)
+ || (textPtr->selTagPtr->selFgColor != NULL)
|| (textPtr->selTagPtr->fgStipple != None)
|| (textPtr->selTagPtr->overstrikeString != NULL)
- || (textPtr->selTagPtr->underlineString != NULL)) {
+ || (textPtr->selTagPtr->overstrikeColor != NULL)
+ || (textPtr->selTagPtr->underlineString != NULL)
+ || (textPtr->selTagPtr->underlineColor != NULL)
+ || (textPtr->selTagPtr->lMarginColor != NULL)
+ || (textPtr->selTagPtr->rMarginColor != NULL)) {
textPtr->selTagPtr->affectsDisplay = 1;
}
TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1);
@@ -2230,7 +2323,7 @@ ConfigureText(
if (TkBTreeCharTagged(&first, textPtr->selTagPtr)
|| TkBTreeNextTag(&search)) {
Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection,
- (ClientData) textPtr);
+ textPtr);
textPtr->flags |= GOT_SELECTION;
}
}
@@ -2241,8 +2334,8 @@ ConfigureText(
if (textPtr->flags & GOT_FOCUS) {
Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
- textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
- TextBlinkProc((ClientData) textPtr);
+ textPtr->insertBlinkHandler = NULL;
+ TextBlinkProc(textPtr);
}
/*
@@ -2285,9 +2378,8 @@ static void
TextWorldChangedCallback(
ClientData instanceData) /* Information about widget. */
{
- TkText *textPtr;
+ TkText *textPtr = instanceData;
- textPtr = (TkText *) instanceData;
TextWorldChanged(textPtr, TK_TEXT_LINE_GEOMETRY);
}
@@ -2332,7 +2424,7 @@ TextWorldChanged(
textPtr->charHeight = 1;
}
if (textPtr->charHeight != oldCharHeight) {
- TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
+ TkBTreeClientRangeChanged(textPtr, textPtr->charHeight);
}
border = textPtr->borderWidth + textPtr->highlightWidth;
Tk_GeometryRequest(textPtr->tkwin,
@@ -2377,7 +2469,7 @@ TextEventProc(
ClientData clientData, /* Information about window. */
register XEvent *eventPtr) /* Information about event. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TkTextIndex index, index2;
if (eventPtr->type == Expose) {
@@ -2437,12 +2529,11 @@ TextEventProc(
textPtr->flags |= GOT_FOCUS | INSERT_ON;
if (textPtr->insertOffTime != 0) {
textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
- textPtr->insertOnTime, TextBlinkProc,
- (ClientData) textPtr);
+ textPtr->insertOnTime, TextBlinkProc, textPtr);
}
} else {
textPtr->flags &= ~(GOT_FOCUS | INSERT_ON);
- textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL;
+ textPtr->insertBlinkHandler = NULL;
}
if (textPtr->inactiveSelBorder != textPtr->selBorder) {
TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr,
@@ -2487,7 +2578,7 @@ static void
TextCmdDeletedProc(
ClientData clientData) /* Pointer to widget record for widget. */
{
- TkText *textPtr = (TkText *) clientData;
+ TkText *textPtr = clientData;
Tk_Window tkwin = textPtr->tkwin;
/*
@@ -2544,9 +2635,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;
}
@@ -2572,8 +2663,7 @@ InsertChars(
resetViewCount = 0;
if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
- lineAndByteIndex = (int *)
- ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
+ lineAndByteIndex = ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
} else {
lineAndByteIndex = pixels;
}
@@ -2635,7 +2725,7 @@ InsertChars(
resetViewCount += 2;
}
if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
- ckfree((char *) lineAndByteIndex);
+ ckfree(lineAndByteIndex);
}
/*
@@ -2683,6 +2773,7 @@ TextPushUndoAction(
/* Index describing second location. */
{
TkUndoSubAtom *iAtom, *dAtom;
+ int canUndo, canRedo;
/*
* Create the helpers.
@@ -2755,13 +2846,13 @@ TextPushUndoAction(
* underlying data shared by all peers.
*/
- iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback,
- (ClientData)textPtr->sharedTextPtr, insertCmdObj, NULL);
+ iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr,
+ insertCmdObj, NULL);
TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom);
TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom);
- dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback,
- (ClientData)textPtr->sharedTextPtr, deleteCmdObj, NULL);
+ dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr,
+ deleteCmdObj, NULL);
TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom);
TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom);
@@ -2769,6 +2860,9 @@ TextPushUndoAction(
Tcl_DecrRefCount(index1Obj);
Tcl_DecrRefCount(index2Obj);
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+
/*
* Depending whether the action is to insert or delete, we provide the
* appropriate second and third arguments to TkUndoPushAction. (The first
@@ -2780,6 +2874,10 @@ TextPushUndoAction(
} else {
TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom);
}
+
+ if (!canUndo || canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
}
/*
@@ -2810,7 +2908,7 @@ TextUndoRedoCallback(
Tcl_Obj *objPtr) /* Arguments of a command to be handled by the
* shared text data structure. */
{
- TkSharedText *sharedPtr = (TkSharedText *) clientData;
+ TkSharedText *sharedPtr = clientData;
int res, objc;
Tcl_Obj **objv;
TkText *textPtr;
@@ -2875,7 +2973,7 @@ TextUndoRedoCallback(
* the Tcl level.
*/
- return SharedTextObjCmd((ClientData)sharedPtr, interp, objc+1, objv-1);
+ return SharedTextObjCmd(sharedPtr, interp, objc+1, objv-1);
}
/*
@@ -2944,7 +3042,7 @@ CountIndices(
* If 'viewUpdate' is true, we may adjust the window contents'
* y-position, and scrollbar setting.
*
- * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex
+ * If 'viewUpdate' is true we can guarantee that textPtr->topIndex
* points to a valid TkTextLine after this function returns. However, if
* 'viewUpdate' is false, then there is no such guarantee (since
* topIndex.linePtr can be garbage). The caller is expected to take
@@ -3034,7 +3132,7 @@ DeleteIndexRange(
for (i = 0; i < arraySize; i++) {
TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
}
- ckfree((char *) arrayPtr);
+ ckfree(arrayPtr);
}
}
@@ -3051,7 +3149,7 @@ DeleteIndexRange(
for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
- TkTextTag *tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr);
+ TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);
TkBTreeTag(&index1, &index2, tagPtr, 0);
}
@@ -3088,8 +3186,7 @@ DeleteIndexRange(
resetViewCount = 0;
if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
- lineAndByteIndex = (int *)
- ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
+ lineAndByteIndex = ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount);
} else {
lineAndByteIndex = pixels;
}
@@ -3117,11 +3214,11 @@ DeleteIndexRange(
resetView = 1;
line = line1;
byteIndex = tPtr->topIndex.byteIndex;
- } else {
- /*
- * Deletion range starts after the top line. This peers's view
- * will not need to be reset. Nothing to do.
- */
+ } else {
+ /*
+ * Deletion range starts after the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
}
} else if (index2.linePtr == tPtr->topIndex.linePtr) {
/*
@@ -3138,11 +3235,11 @@ DeleteIndexRange(
} else {
byteIndex -= (index2.byteIndex - index1.byteIndex);
}
- } else {
- /*
- * Deletion range ends before the top line. This peers's view
- * will not need to be reset. Nothing to do.
- */
+ } else {
+ /*
+ * Deletion range ends before the top line. This peers's view
+ * will not need to be reset. Nothing to do.
+ */
}
if (resetView) {
lineAndByteIndex[resetViewCount] = line;
@@ -3150,7 +3247,7 @@ DeleteIndexRange(
} else {
lineAndByteIndex[resetViewCount] = -1;
}
- resetViewCount+=2;
+ resetViewCount += 2;
}
/*
@@ -3187,50 +3284,50 @@ DeleteIndexRange(
TkTextIndex indexTmp;
if (tPtr == textPtr) {
- if (viewUpdate) {
- /*
- * line cannot be before -startline of textPtr because
- * this line corresponds to an index which is necessarily
- * between "1.0" and "end" relative to textPtr.
- * Therefore no need to clamp line to the -start/-end
- * range.
- */
+ if (viewUpdate) {
+ /*
+ * line cannot be before -startline of textPtr because
+ * this line corresponds to an index which is necessarily
+ * between "1.0" and "end" relative to textPtr.
+ * Therefore no need to clamp line to the -start/-end
+ * range.
+ */
TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line,
byteIndex, &indexTmp);
TkTextSetYView(tPtr, &indexTmp, 0);
}
} else {
- TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
+ TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
byteIndex, &indexTmp);
- /*
- * line may be before -startline of tPtr and must be
- * clamped to -startline before providing it to
- * TkTextSetYView otherwise lines before -startline
- * would be displayed.
- * There is no need to worry about -endline however,
- * because the view will only be reset if the deletion
- * involves the TOP line of the screen
- */
-
- if (tPtr->start != NULL) {
- int start;
- TkTextIndex indexStart;
-
- start = TkBTreeLinesTo(NULL, tPtr->start);
- TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start,
+ /*
+ * line may be before -startline of tPtr and must be
+ * clamped to -startline before providing it to
+ * TkTextSetYView otherwise lines before -startline
+ * would be displayed.
+ * There is no need to worry about -endline however,
+ * because the view will only be reset if the deletion
+ * involves the TOP line of the screen
+ */
+
+ if (tPtr->start != NULL) {
+ int start;
+ TkTextIndex indexStart;
+
+ start = TkBTreeLinesTo(NULL, tPtr->start);
+ TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start,
0, &indexStart);
- if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) {
- indexTmp = indexStart;
- }
- }
+ if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) {
+ indexTmp = indexStart;
+ }
+ }
TkTextSetYView(tPtr, &indexTmp, 0);
}
}
resetViewCount += 2;
}
if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
- ckfree((char *) lineAndByteIndex);
+ ckfree(lineAndByteIndex);
}
if (line1 >= line2) {
@@ -3278,7 +3375,7 @@ TextFetchSelection(
* not including terminating NULL
* character. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TkTextIndex eof;
int count, chunkSize, offsetInSeg;
TkTextSearch search;
@@ -3409,7 +3506,7 @@ void
TkTextLostSelection(
ClientData clientData) /* Information about text widget. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
if (TkpAlwaysShowSelection(textPtr->tkwin)) {
TkTextIndex start, end;
@@ -3469,16 +3566,7 @@ TkTextSelectionEvent(
* event generate $textWidget <<Selection>>
*/
- union {XEvent general; XVirtualEvent virtual;} event;
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(textPtr->tkwin);
- event.general.xany.display = Tk_Display(textPtr->tkwin);
- event.virtual.name = Tk_GetUid("Selection");
- Tk_HandleEvent(&event.general);
+ TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL);
}
/*
@@ -3503,12 +3591,22 @@ static void
TextBlinkProc(
ClientData clientData) /* Pointer to record describing text. */
{
- register TkText *textPtr = (TkText *) clientData;
+ register TkText *textPtr = clientData;
TkTextIndex index;
int x, y, w, h, charWidth;
if ((textPtr->state == TK_TEXT_STATE_DISABLED) ||
!(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) {
+ if (!(textPtr->flags & GOT_FOCUS) &&
+ (textPtr->insertUnfocussed != TK_TEXT_INSERT_NOFOCUS_NONE)) {
+ /*
+ * The widget doesn't have the focus yet it is configured to
+ * display the cursor when it doesn't have the focus. Act now!
+ */
+
+ textPtr->flags |= INSERT_ON;
+ goto redrawInsert;
+ }
if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) {
/*
* The widget was configured to have zero offtime while the
@@ -3523,11 +3621,11 @@ TextBlinkProc(
if (textPtr->flags & INSERT_ON) {
textPtr->flags &= ~INSERT_ON;
textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
- textPtr->insertOffTime, TextBlinkProc, (ClientData) textPtr);
+ textPtr->insertOffTime, TextBlinkProc, textPtr);
} else {
textPtr->flags |= INSERT_ON;
textPtr->insertBlinkHandler = Tcl_CreateTimerHandler(
- textPtr->insertOnTime, TextBlinkProc, (ClientData) textPtr);
+ textPtr->insertOnTime, TextBlinkProc, textPtr);
}
redrawInsert:
TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
@@ -3606,7 +3704,7 @@ TextInsertCmd(
for (i = 0; i < numTags; i++) {
TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0);
}
- ckfree((char *) oldTagArrayPtr);
+ ckfree(oldTagArrayPtr);
}
if (Tcl_ListObjGetElements(interp, objv[j+1], &numTags,
&tagNamePtrs) != TCL_OK) {
@@ -3654,14 +3752,15 @@ TextSearchCmd(
int i, argsLeft, code;
SearchSpec searchSpec;
- static const char *switchStrings[] = {
+ static const char *const switchStrings[] = {
+ "-hidden",
"--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards",
- "-hidden", "-nocase", "-nolinestop", "-overlap", "-regexp",
- "-strictlimits", NULL
+ "-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL
};
enum SearchSwitches {
+ SEARCH_HIDDEN,
SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE,
- SEARCH_EXACT, SEARCH_FWD, SEARCH_HIDDEN, SEARCH_NOCASE,
+ SEARCH_EXACT, SEARCH_FWD, SEARCH_NOCASE,
SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS
};
@@ -3683,7 +3782,7 @@ TextSearchCmd(
searchSpec.strictLimits = 0;
searchSpec.numLines =
TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
- searchSpec.clientData = (ClientData)textPtr;
+ searchSpec.clientData = textPtr;
searchSpec.addLineProc = &TextSearchAddNextLine;
searchSpec.foundMatchProc = &TextSearchFoundMatch;
searchSpec.lineIndexProc = &TextSearchGetLineIndex;
@@ -3694,21 +3793,20 @@ TextSearchCmd(
for (i=2 ; i<objc ; i++) {
int index;
+
if (Tcl_GetString(objv[i])[0] != '-') {
break;
}
- if (Tcl_GetIndexFromObj(interp, 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.
+ * Hide the -hidden option, generating the error description with
+ * the side effects of T_GIFO.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad switch \"", Tcl_GetString(objv[i]),
- "\": must be --, -all, -backward, -count, -elide, ",
- "-exact, -forward, -nocase, -nolinestop, -overlap, ",
- "-regexp, or -strictlimits", NULL);
+ (void) Tcl_GetIndexFromObjStruct(interp, objv[i], switchStrings+1,
+ sizeof(char *), "switch", 0, &index);
return TCL_ERROR;
}
@@ -3724,8 +3822,9 @@ TextSearchCmd(
break;
case SEARCH_COUNT:
if (i >= objc-1) {
- Tcl_SetResult(interp, "no value given for \"-count\" option",
- TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "no value given for \"-count\" option", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "VALUE", NULL);
return TCL_ERROR;
}
i++;
@@ -3776,14 +3875,18 @@ TextSearchCmd(
}
if (searchSpec.noLineStop && searchSpec.exact) {
- Tcl_SetResult(interp, "the \"-nolinestop\" option requires the "
- "\"-regexp\" option to be present", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "the \"-nolinestop\" option requires the \"-regexp\" option"
+ " to be present", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL);
return TCL_ERROR;
}
if (searchSpec.overlap && !searchSpec.all) {
- Tcl_SetResult(interp, "the \"-overlap\" option requires the "
- "\"-all\" option to be present", TCL_STATIC);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "the \"-overlap\" option requires the \"-all\" option"
+ " to be present", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "SEARCH_USAGE", NULL);
return TCL_ERROR;
}
@@ -3868,7 +3971,7 @@ TextSearchGetLineIndex(
{
const TkTextIndex *indexPtr;
int line;
- TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ TkText *textPtr = searchSpecPtr->clientData;
indexPtr = TkTextGetIndexFromObj(interp, textPtr, objPtr);
if (indexPtr == NULL) {
@@ -3933,7 +4036,7 @@ TextSearchIndexInLine(
TkTextSegment *segPtr;
TkTextIndex curIndex;
int index, leftToScan;
- TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ TkText *textPtr = searchSpecPtr->clientData;
index = 0;
curIndex.tree = textPtr->sharedTextPtr->tree;
@@ -4003,7 +4106,7 @@ TextSearchAddNextLine(
TkTextLine *linePtr, *thisLinePtr;
TkTextIndex curIndex;
TkTextSegment *segPtr;
- TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ TkText *textPtr = searchSpecPtr->clientData;
int nothingYet = 1;
/*
@@ -4075,12 +4178,13 @@ TextSearchAddNextLine(
if (lenPtr != NULL) {
if (searchSpecPtr->exact) {
- Tcl_GetStringFromObj(theLine, lenPtr);
+ (void)Tcl_GetString(theLine);
+ *lenPtr = theLine->length;
} else {
*lenPtr = Tcl_GetCharLength(theLine);
}
}
- return (ClientData)linePtr;
+ return linePtr;
}
/*
@@ -4124,7 +4228,7 @@ TextSearchFoundMatch(
TkTextIndex curIndex, foundIndex;
TkTextSegment *segPtr;
TkTextLine *linePtr;
- TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ TkText *textPtr = searchSpecPtr->clientData;
if (lineNum == searchSpecPtr->stopLine) {
/*
@@ -4175,7 +4279,7 @@ TextSearchFoundMatch(
* reached the end of the match or we have reached the end of the line.
*/
- linePtr = (TkTextLine *)clientData;
+ linePtr = clientData;
if (linePtr == NULL) {
linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr,
lineNum);
@@ -4355,12 +4459,12 @@ TkTextGetTabs(
Tcl_Obj **objv;
TkTextTabArray *tabArrayPtr;
TkTextTab *tabPtr;
- Tcl_UniChar ch;
+ int ch;
double prevStop, lastStop;
/*
* Map these strings to TkTextTabAlign values.
*/
- static const char *tabOptionStrings[] = {
+ static const char *const tabOptionStrings[] = {
"left", "right", "center", "numeric", NULL
};
@@ -4375,6 +4479,7 @@ TkTextGetTabs(
count = 0;
for (i = 0; i < objc; i++) {
char c = Tcl_GetString(objv[i])[0];
+
if ((c != 'l') && (c != 'r') && (c != 'c') && (c != 'n')) {
count++;
}
@@ -4384,8 +4489,8 @@ TkTextGetTabs(
* Parse the elements of the list one at a time to fill in the array.
*/
- tabArrayPtr = (TkTextTabArray *) ckalloc((unsigned)
- (sizeof(TkTextTabArray) + (count-1)*sizeof(TkTextTab)));
+ tabArrayPtr = ckalloc(sizeof(TkTextTabArray)
+ + (count - 1) * sizeof(TkTextTab));
tabArrayPtr->numTabs = 0;
prevStop = 0.0;
lastStop = 0.0;
@@ -4403,14 +4508,16 @@ TkTextGetTabs(
}
if (tabPtr->location <= 0) {
- Tcl_AppendResult(interp, "tab stop \"", Tcl_GetString(objv[i]),
- "\" is not at a positive distance", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "tab stop \"%s\" is not at a positive distance",
+ Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL);
goto error;
}
prevStop = lastStop;
- if (Tk_GetDoublePixelsFromObj (interp, textPtr->tkwin, objv[i],
- &lastStop) != TCL_OK) {
+ if (Tk_GetDoublePixelsFromObj(interp, textPtr->tkwin, objv[i],
+ &lastStop) != TCL_OK) {
goto error;
}
@@ -4434,11 +4541,11 @@ TkTextGetTabs(
}
lastStop = tabPtr->location;
#else
- Tcl_AppendResult(interp,
- "tabs must be monotonically increasing, but \"",
- Tcl_GetString(objv[i]),
- "\" is smaller than or equal to the previous tab",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "tabs must be monotonically increasing, but \"%s\" is "
+ "smaller than or equal to the previous tab",
+ Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "TAB_STOP", NULL);
goto error;
#endif /* _TK_ALLOW_DECREASING_TABS */
}
@@ -4459,17 +4566,17 @@ TkTextGetTabs(
* There may be a more efficient way of getting this.
*/
- Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch);
+ TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch);
if (!Tcl_UniCharIsAlpha(ch)) {
continue;
}
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);
+ tabPtr->alignment = (TkTextTabAlign) index;
}
/*
@@ -4484,7 +4591,7 @@ TkTextGetTabs(
return tabArrayPtr;
error:
- ckfree((char *) tabArrayPtr);
+ ckfree(tabArrayPtr);
return NULL;
}
@@ -4530,7 +4637,7 @@ TextDumpCmd(
#define TK_DUMP_IMG 0x10
#define TK_DUMP_ALL (TK_DUMP_TEXT|TK_DUMP_MARK|TK_DUMP_TAG| \
TK_DUMP_WIN|TK_DUMP_IMG)
- static const char *optStrings[] = {
+ static const char *const optStrings[] = {
"-all", "-command", "-image", "-mark", "-tag", "-text", "-window",
NULL
};
@@ -4543,8 +4650,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) {
@@ -4569,10 +4676,7 @@ TextDumpCmd(
case DUMP_CMD:
arg++;
if (arg >= objc) {
- Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]),
- " dump ?-all -image -text -mark -tag -window? ",
- "?-command script? index ?index2?", NULL);
- return TCL_ERROR;
+ goto wrongArgs;
}
command = objv[arg];
break;
@@ -4581,9 +4685,11 @@ TextDumpCmd(
}
}
if (arg >= objc || arg+2 < objc) {
- Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]),
- " dump ?-all -image -text -mark -tag -window? ",
- "?-command script? index ?index2?", NULL);
+ wrongArgs:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "Usage: %s dump ?-all -image -text -mark -tag -window? "
+ "?-command script? index ?index2?", Tcl_GetString(objv[0])));
+ Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
return TCL_ERROR;
}
if (what == 0) {
@@ -4598,13 +4704,14 @@ TextDumpCmd(
TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
} else {
int length;
- char *str;
+ const char *str;
if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
return TCL_ERROR;
}
- str = Tcl_GetStringFromObj(objv[arg], &length);
- if (strncmp(str, "end", (unsigned)length) == 0) {
+ str = Tcl_GetString(objv[arg]);
+ length = objv[arg]->length;
+ if (strncmp(str, "end", (unsigned) length) == 0) {
atEnd = 1;
}
}
@@ -4637,8 +4744,8 @@ TextDumpCmd(
if (lineno == lineend) {
break;
}
- textChanged = DumpLine(interp, textPtr, what, linePtr, 0, 32000000,
- lineno, command);
+ textChanged = DumpLine(interp, textPtr, what, linePtr, 0,
+ 32000000, lineno, command);
if (textChanged) {
if (textPtr->flags & DESTROYED) {
return TCL_OK;
@@ -4747,10 +4854,9 @@ DumpLine(
*/
int length = last - first;
- char *range = ckalloc((length + 1) * sizeof(char));
+ char *range = ckalloc(length + 1);
- memcpy(range, segPtr->body.chars + first,
- length * sizeof(char));
+ memcpy(range, segPtr->body.chars + first, length);
range[length] = '\0';
TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
@@ -4765,9 +4871,11 @@ DumpLine(
segPtr->body.chars + first, command, &index, what);
}
} else if ((offset >= startByte)) {
- if ((what & TK_DUMP_MARK) && (segPtr->typePtr->name[0] == 'm')) {
- char *name;
- TkTextMark *markPtr = (TkTextMark *) &segPtr->body;
+ if ((what & TK_DUMP_MARK)
+ && (segPtr->typePtr == &tkTextLeftMarkType
+ || segPtr->typePtr == &tkTextRightMarkType)) {
+ const char *name;
+ TkTextMark *markPtr = &segPtr->body.mark;
if (segPtr == textPtr->insertMarkPtr) {
name = "insert";
@@ -4801,18 +4909,18 @@ DumpLine(
segPtr->body.toggle.tagPtr->name, command, &index,
what);
} else if ((what & TK_DUMP_IMG) &&
- (segPtr->typePtr->name[0] == 'i')) {
- TkTextEmbImage *eiPtr = (TkTextEmbImage *)&segPtr->body;
- char *name = (eiPtr->name == NULL) ? "" : eiPtr->name;
+ (segPtr->typePtr == &tkTextEmbImageType)) {
+ TkTextEmbImage *eiPtr = &segPtr->body.ei;
+ const char *name = (eiPtr->name == NULL) ? "" : eiPtr->name;
TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
lineno, offset, &index);
lineChanged = DumpSegment(textPtr, interp, "image", name,
command, &index, what);
} else if ((what & TK_DUMP_WIN) &&
- (segPtr->typePtr->name[0] == 'w')) {
- TkTextEmbWindow *ewPtr = (TkTextEmbWindow *)&segPtr->body;
- char *pathname;
+ (segPtr->typePtr == &tkTextEmbWindowType)) {
+ TkTextEmbWindow *ewPtr = &segPtr->body.ew;
+ const char *pathname;
if (ewPtr->tkwin == (Tk_Window) NULL) {
pathname = "";
@@ -4825,6 +4933,7 @@ DumpLine(
command, &index, what);
}
}
+
offset += currentSize;
if (lineChanged) {
TkTextSegment *newSegPtr;
@@ -4842,9 +4951,7 @@ DumpLine(
linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree,
textPtr, lineno);
newSegPtr = linePtr->segPtr;
- if (segPtr == newSegPtr) {
- segPtr = segPtr->nextPtr;
- } else {
+ if (segPtr != newSegPtr) {
while ((newOffset < endByte) && (newOffset < offset)
&& (newSegPtr != NULL)) {
newOffset += currentSize;
@@ -4866,11 +4973,9 @@ DumpLine(
}
}
segPtr = newSegPtr;
- if (segPtr != NULL) {
- segPtr = segPtr->nextPtr;
- }
}
- } else {
+ }
+ if (segPtr != NULL) {
segPtr = segPtr->nextPtr;
}
}
@@ -4909,31 +5014,36 @@ DumpSegment(
int what) /* Look for TK_DUMP_INDEX bit. */
{
char buffer[TK_POS_CHARS];
+ Tcl_Obj *values[3], *tuple;
TkTextPrintIndex(textPtr, index, buffer);
+ values[0] = Tcl_NewStringObj(key, -1);
+ values[1] = Tcl_NewStringObj(value, -1);
+ values[2] = Tcl_NewStringObj(buffer, -1);
+ tuple = Tcl_NewListObj(3, values);
if (command == NULL) {
- Tcl_AppendElement(interp, key);
- Tcl_AppendElement(interp, value);
- Tcl_AppendElement(interp, buffer);
+ Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple);
+ Tcl_DecrRefCount(tuple);
return 0;
} else {
- const char *argv[4];
- char *list;
int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree);
-
- argv[0] = key;
- argv[1] = value;
- argv[2] = buffer;
- argv[3] = NULL;
- list = Tcl_Merge(3, argv);
- Tcl_VarEval(interp, Tcl_GetString(command), " ", list, NULL);
- ckfree(list);
- if ((textPtr->flags & DESTROYED) ||
- TkBTreeEpoch(textPtr->sharedTextPtr->tree) != oldStateEpoch) {
- return 1;
- } else {
- return 0;
- }
+ 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);
}
}
@@ -5056,63 +5166,84 @@ TextEditCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int index;
+ int index, setModified, oldModified;
+ int canRedo = 0;
+ int canUndo = 0;
- static const char *editOptionStrings[] = {
- "modified", "redo", "reset", "separator", "undo", NULL
+ static const char *const editOptionStrings[] = {
+ "canundo", "canredo", "modified", "redo", "reset", "separator",
+ "undo", NULL
};
enum editOptions {
- EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO
+ EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET,
+ EDIT_SEPARATOR, EDIT_UNDO
};
if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg ...?");
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;
}
switch ((enum editOptions) index) {
+ case EDIT_CANREDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo));
+ break;
+ case EDIT_CANUNDO:
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ if (textPtr->sharedTextPtr->undo) {
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo));
+ break;
case EDIT_MODIFIED:
if (objc == 3) {
Tcl_SetObjResult(interp,
Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty));
+ return TCL_OK;
} else if (objc != 4) {
Tcl_WrongNumArgs(interp, 3, objv, "?boolean?");
return TCL_ERROR;
- } else {
- int setModified, oldModified;
-
- if (Tcl_GetBooleanFromObj(interp, objv[3],
- &setModified) != TCL_OK) {
- return TCL_ERROR;
- }
+ } else if (Tcl_GetBooleanFromObj(interp, objv[3],
+ &setModified) != TCL_OK) {
+ return TCL_ERROR;
+ }
- /*
- * Set or reset the dirty info, and trigger a Modified event.
- */
+ /*
+ * Set or reset the dirty info, and trigger a Modified event.
+ */
- setModified = setModified ? 1 : 0;
+ setModified = setModified ? 1 : 0;
- oldModified = textPtr->sharedTextPtr->isDirty;
- textPtr->sharedTextPtr->isDirty = setModified;
- if (setModified) {
- textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
- } else {
- textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
- }
+ oldModified = textPtr->sharedTextPtr->isDirty;
+ textPtr->sharedTextPtr->isDirty = setModified;
+ if (setModified) {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_FIXED;
+ } else {
+ textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL;
+ }
- /*
- * Only issue the <<Modified>> event if the flag actually changed.
- * However, degree of modified-ness doesn't matter. [Bug 1799782]
- */
+ /*
+ * Only issue the <<Modified>> event if the flag actually changed.
+ * However, degree of modified-ness doesn't matter. [Bug 1799782]
+ */
- if ((!oldModified) != (!setModified)) {
- GenerateModifiedEvent(textPtr);
- }
+ if ((!oldModified) != (!setModified)) {
+ GenerateModifiedEvent(textPtr);
}
break;
case EDIT_REDO:
@@ -5120,17 +5251,28 @@ TextEditCmd(
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
if (TextEditRedo(textPtr)) {
- Tcl_AppendResult(interp, "nothing to redo", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL);
return TCL_ERROR;
}
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
+ if (!canUndo || !canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_RESET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
TkUndoClearStacks(textPtr->sharedTextPtr->undoStack);
+ if (canUndo || canRedo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
case EDIT_SEPARATOR:
if (objc != 3) {
@@ -5144,10 +5286,16 @@ TextEditCmd(
Tcl_WrongNumArgs(interp, 3, objv, NULL);
return TCL_ERROR;
}
+ canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack);
if (TextEditUndo(textPtr)) {
- Tcl_AppendResult(interp, "nothing to undo", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1));
+ Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL);
return TCL_ERROR;
}
+ canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack);
+ if (!canRedo || !canUndo) {
+ GenerateUndoStackEvent(textPtr);
+ }
break;
}
return TCL_OK;
@@ -5205,11 +5353,10 @@ TextGetText(
if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) {
while (1) {
- int offset, last;
- TkTextSegment *segPtr;
+ int offset;
+ TkTextSegment *segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
+ int last = segPtr->size, last2;
- segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
- last = segPtr->size;
if (tmpIndex.linePtr == indexPtr2->linePtr) {
/*
* The last line that was requested must be handled carefully,
@@ -5219,21 +5366,17 @@ TextGetText(
if (indexPtr2->byteIndex == tmpIndex.byteIndex) {
break;
- } else {
- int last2 = indexPtr2->byteIndex - tmpIndex.byteIndex
- + offset;
-
- if (last2 < last) {
- last = last2;
- }
}
- }
- if (segPtr->typePtr == &tkTextCharType) {
- if (!visibleOnly || !TkTextIsElided(textPtr,&tmpIndex,NULL)) {
- Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset,
- last - offset);
+ last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset;
+ if (last2 < last) {
+ last = last2;
}
}
+ if (segPtr->typePtr == &tkTextCharType &&
+ !(visibleOnly && TkTextIsElided(textPtr,&tmpIndex,NULL))){
+ Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset,
+ last - offset);
+ }
TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex);
}
}
@@ -5245,8 +5388,9 @@ TextGetText(
*
* GenerateModifiedEvent --
*
- * Send an event that the text was modified. This is equivalent to
+ * Send an event that the text was modified. This is equivalent to:
* event generate $textWidget <<Modified>>
+ * for all peers of $textWidget.
*
* Results:
* None
@@ -5261,18 +5405,41 @@ static void
GenerateModifiedEvent(
TkText *textPtr) /* Information about text widget. */
{
- union {XEvent general; XVirtualEvent virtual;} event;
-
- Tk_MakeWindowExist(textPtr->tkwin);
-
- memset(&event, 0, sizeof(event));
- event.general.xany.type = VirtualEvent;
- event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
- event.general.xany.send_event = False;
- event.general.xany.window = Tk_WindowId(textPtr->tkwin);
- event.general.xany.display = Tk_Display(textPtr->tkwin);
- event.virtual.name = Tk_GetUid("Modified");
- Tk_HandleEvent(&event.general);
+ for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ Tk_MakeWindowExist(textPtr->tkwin);
+ TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateUndoStackEvent --
+ *
+ * Send an event that the undo or redo stack became empty or unempty.
+ * This is equivalent to:
+ * event generate $textWidget <<UndoStack>>
+ * for all peers of $textWidget.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * May force the text window (and all peers) into existence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateUndoStackEvent(
+ TkText *textPtr) /* Information about text widget. */
+{
+ for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL;
+ textPtr = textPtr->next) {
+ Tk_MakeWindowExist(textPtr->tkwin);
+ TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
+ }
}
/*
@@ -5296,7 +5463,6 @@ UpdateDirtyFlag(
TkSharedText *sharedTextPtr)/* Information about text widget. */
{
int oldDirtyFlag;
- TkText *textPtr;
/*
* If we've been forced to be dirty, we stay dirty (until explicitly
@@ -5327,11 +5493,54 @@ UpdateDirtyFlag(
}
if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) {
- for (textPtr = sharedTextPtr->peers; textPtr != NULL;
- textPtr = textPtr->next) {
- GenerateModifiedEvent(textPtr);
+ GenerateModifiedEvent(sharedTextPtr->peers);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
}
/*
@@ -5371,7 +5580,7 @@ SearchPerform(
* for regexp search, utf-8 bytes for exact search).
*/
- if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr,
+ if (searchSpecPtr->lineIndexProc(interp, fromPtr, searchSpecPtr,
&searchSpecPtr->startLine,
&searchSpecPtr->startOffset) != TCL_OK) {
return TCL_ERROR;
@@ -5383,7 +5592,7 @@ SearchPerform(
if (toPtr != NULL) {
const TkTextIndex *indexToPtr, *indexFromPtr;
- TkText *textPtr = (TkText *) searchSpecPtr->clientData;
+ TkText *textPtr = searchSpecPtr->clientData;
indexToPtr = TkTextGetIndexFromObj(interp, textPtr, toPtr);
if (indexToPtr == NULL) {
@@ -5397,17 +5606,12 @@ SearchPerform(
* wrap when given a negative search range).
*/
- if (searchSpecPtr->backwards) {
- if (TkTextIndexCmp(indexFromPtr, indexToPtr) == -1) {
- return TCL_OK;
- }
- } else {
- if (TkTextIndexCmp(indexFromPtr, indexToPtr) == 1) {
- return TCL_OK;
- }
+ if (TkTextIndexCmp(indexFromPtr, indexToPtr) ==
+ (searchSpecPtr->backwards ? -1 : 1)) {
+ return TCL_OK;
}
- if ((*searchSpecPtr->lineIndexProc)(interp, toPtr, searchSpecPtr,
+ if (searchSpecPtr->lineIndexProc(interp, toPtr, searchSpecPtr,
&searchSpecPtr->stopLine,
&searchSpecPtr->stopOffset) != TCL_OK) {
return TCL_ERROR;
@@ -5542,7 +5746,8 @@ SearchCore(
* it has dual purpose.
*/
- pattern = Tcl_GetStringFromObj(patObj, &matchLength);
+ pattern = Tcl_GetString(patObj);
+ matchLength = patObj->length;
nl = strchr(pattern, '\n');
/*
@@ -5593,8 +5798,8 @@ SearchCore(
* this line, which is what 'lastOffset' represents.
*/
- lineInfo = (*searchSpecPtr->addLineProc)(lineNum, searchSpecPtr,
- theLine, &lastOffset, &linesSearched);
+ lineInfo = searchSpecPtr->addLineProc(lineNum, searchSpecPtr, theLine,
+ &lastOffset, &linesSearched);
if (lineInfo == NULL) {
/*
@@ -5673,8 +5878,9 @@ SearchCore(
int maxExtraLines = 0;
const char *startOfLine = Tcl_GetString(theLine);
+ CLANG_ASSERT(pattern);
do {
- Tcl_UniChar ch;
+ int ch;
const char *p;
int lastFullLine = lastOffset;
@@ -5710,7 +5916,7 @@ SearchCore(
}
while (p >= startOfLine + firstOffset) {
if (p[0] == c && !strncmp(p, pattern,
- (unsigned)matchLength)) {
+ (unsigned) matchLength)) {
goto backwardsMatch;
}
p--;
@@ -5739,7 +5945,7 @@ SearchCore(
*/
p = startOfLine + lastOffset - firstNewLine - 1;
- if (strncmp(p, pattern, (unsigned)(firstNewLine + 1))) {
+ if (strncmp(p, pattern, (unsigned) firstNewLine + 1)) {
/*
* No match.
*/
@@ -5778,7 +5984,7 @@ SearchCore(
*/
if (extraLines > maxExtraLines) {
- if ((*searchSpecPtr->addLineProc)(lineNum
+ if (searchSpecPtr->addLineProc(lineNum
+ extraLines, searchSpecPtr, theLine,
&lastTotal, &extraLines) == NULL) {
p = NULL;
@@ -5858,9 +6064,8 @@ SearchCore(
matchOffset = p - startOfLine;
if (searchSpecPtr->all &&
- !(*searchSpecPtr->foundMatchProc)(lineNum,
- searchSpecPtr, lineInfo, theLine, matchOffset,
- matchLength)) {
+ !searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr,
+ lineInfo, theLine, matchOffset, matchLength)) {
/*
* We reached the end of the search.
*/
@@ -5905,7 +6110,7 @@ SearchCore(
}
} else {
firstOffset = p - startOfLine +
- Tcl_UtfToUniChar(startOfLine+matchOffset,&ch);
+ TkUtfToUniChar(startOfLine+matchOffset,&ch);
}
}
} while (searchSpecPtr->all);
@@ -6001,7 +6206,7 @@ SearchCore(
*/
if (extraLines > maxExtraLines) {
- if ((*searchSpecPtr->addLineProc)(lineNum
+ if (searchSpecPtr->addLineProc(lineNum
+ extraLines, searchSpecPtr, theLine,
&lastTotal, &extraLines) == NULL) {
/*
@@ -6180,9 +6385,9 @@ SearchCore(
if (lastBackwardsLineMatch != -1) {
recordBackwardsMatch:
- (*searchSpecPtr->foundMatchProc)(
- lastBackwardsLineMatch, searchSpecPtr, NULL,
- NULL, lastBackwardsMatchOffset, matchLength);
+ searchSpecPtr->foundMatchProc(lastBackwardsLineMatch,
+ searchSpecPtr, NULL, NULL,
+ lastBackwardsMatchOffset, matchLength);
lastBackwardsLineMatch = -1;
if (!searchSpecPtr->all) {
goto searchDone;
@@ -6225,13 +6430,13 @@ SearchCore(
* matches on the heap.
*/
- int *newArray = (int *)
+ int *newArray =
ckalloc(4 * matchNum * sizeof(int));
memcpy(newArray, storeMatch, matchNum*sizeof(int));
memcpy(newArray + 2*matchNum, storeLength,
matchNum * sizeof(int));
if (storeMatch != smArray) {
- ckfree((char *) storeMatch);
+ ckfree(storeMatch);
}
matchNum *= 2;
storeMatch = newArray;
@@ -6247,7 +6452,7 @@ SearchCore(
*/
if (searchSpecPtr->all &&
- !(*searchSpecPtr->foundMatchProc)(lineNum,
+ !searchSpecPtr->foundMatchProc(lineNum,
searchSpecPtr, lineInfo, theLine, matchOffset,
matchLength)) {
/*
@@ -6338,7 +6543,7 @@ SearchCore(
continue;
}
}
- (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr,
+ searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr,
lineInfo, theLine, matchOffset, matchLength);
if (!searchSpecPtr->all) {
goto searchDone;
@@ -6353,7 +6558,7 @@ SearchCore(
* non-all case.
*/
- (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr,
+ searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr,
lineInfo, theLine, matchOffset, matchLength);
} else {
lastBackwardsLineMatch = lineNum;
@@ -6372,7 +6577,7 @@ SearchCore(
if ((lastBackwardsLineMatch == -1) && (matchOffset >= 0)
&& !searchSpecPtr->all) {
- (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, lineInfo,
+ searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo,
theLine, matchOffset, matchLength);
goto searchDone;
}
@@ -6399,7 +6604,7 @@ SearchCore(
if (lastBackwardsLineMatch != -1
&& ((lineNum < 0)
|| (lineNum + 2 < lastBackwardsLineMatch))) {
- (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch,
+ searchSpecPtr->foundMatchProc(lastBackwardsLineMatch,
searchSpecPtr, NULL, NULL,
lastBackwardsMatchOffset, matchLength);
lastBackwardsLineMatch = -1;
@@ -6445,7 +6650,7 @@ SearchCore(
searchDone:
if (lastBackwardsLineMatch != -1) {
- (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, searchSpecPtr,
+ searchSpecPtr->foundMatchProc(lastBackwardsLineMatch, searchSpecPtr,
NULL, NULL, lastBackwardsMatchOffset, matchLength);
}
@@ -6461,7 +6666,7 @@ SearchCore(
*/
if (storeMatch != smArray) {
- ckfree((char *) storeMatch);
+ ckfree(storeMatch);
}
return code;
@@ -6496,9 +6701,8 @@ GetLineStartEnd(
if (linePtr == NULL) {
return Tcl_NewObj();
- } else {
- return Tcl_NewIntObj(1+TkBTreeLinesTo(NULL, linePtr));
}
+ return Tcl_NewIntObj(1 + TkBTreeLinesTo(NULL, linePtr));
}
/*
@@ -6611,16 +6815,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);
}
/*
@@ -6645,8 +6847,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;
@@ -6655,45 +6857,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 = (TkText *) info.objClientData;
- } else {
- textPtr = (TkText *) 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;
@@ -6701,9 +6899,7 @@ TkpTesttextCmd(
TkTextSetMark(textPtr, "insert", &index);
TkTextPrintIndex(textPtr, &index, buf);
- sprintf(buf + strlen(buf), " %d", index.byteIndex);
- Tcl_AppendResult(interp, buf, NULL);
-
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s %d", buf, index.byteIndex));
return TCL_OK;
}