summaryrefslogtreecommitdiffstats
path: root/generic/tkTextWind.c
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-05-19 13:04:21 (GMT)
committervincentdarley <vincentdarley>2003-05-19 13:04:21 (GMT)
commitcf597519de1f5e18be3c07e6988cb6e91300ed6e (patch)
treeff3118e296016bb30e790c80a6e787ef78969042 /generic/tkTextWind.c
parent20218318b32692b54a27224fbd7676d7483732e0 (diff)
downloadtk-cf597519de1f5e18be3c07e6988cb6e91300ed6e.zip
tk-cf597519de1f5e18be3c07e6988cb6e91300ed6e.tar.gz
tk-cf597519de1f5e18be3c07e6988cb6e91300ed6e.tar.bz2
tip 113 implementation
Diffstat (limited to 'generic/tkTextWind.c')
-rw-r--r--generic/tkTextWind.c456
1 files changed, 188 insertions, 268 deletions
diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c
index 6137b14..cc0449e 100644
--- a/generic/tkTextWind.c
+++ b/generic/tkTextWind.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkTextWind.c,v 1.6 2002/08/05 04:30:40 dgp Exp $
+ * RCS: @(#) $Id: tkTextWind.c,v 1.7 2003/05/19 13:04:24 vincentdarley Exp $
*/
#include "tk.h"
@@ -35,15 +35,6 @@ static Tk_GeomMgr textGeomType = {
};
/*
- * Definitions for alignment values:
- */
-
-#define ALIGN_BOTTOM 0
-#define ALIGN_CENTER 1
-#define ALIGN_TOP 2
-#define ALIGN_BASELINE 3
-
-/*
* Macro that determines the size of an embedded window segment:
*/
@@ -54,12 +45,6 @@ static Tk_GeomMgr textGeomType = {
* Prototypes for procedures defined in this file:
*/
-static int AlignParseProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin,
- CONST char *value, char *widgRec, int offset));
-static char * AlignPrintProc _ANSI_ARGS_((ClientData clientData,
- Tk_Window tkwin, char *widgRec, int offset,
- Tcl_FreeProc **freeProcPtr));
static TkTextSegment * EmbWinCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr,
TkTextLine *linePtr));
static void EmbWinCheckProc _ANSI_ARGS_((TkTextSegment *segPtr,
@@ -69,7 +54,7 @@ static void EmbWinBboxProc _ANSI_ARGS_((TkTextDispChunk *chunkPtr,
int *xPtr, int *yPtr, int *widthPtr,
int *heightPtr));
static int EmbWinConfigure _ANSI_ARGS_((TkText *textPtr,
- TkTextSegment *ewPtr, int argc, CONST char **argv));
+ TkTextSegment *ewPtr, int objc, Tcl_Obj *CONST objv[]));
static void EmbWinDelayedUnmap _ANSI_ARGS_((
ClientData clientData));
static int EmbWinDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr,
@@ -104,32 +89,41 @@ static Tk_SegType tkTextEmbWindowType = {
};
/*
+ * Definitions for alignment values:
+ */
+
+static char *alignStrings[] = {
+ "baseline", "bottom", "center", "top", (char *) NULL
+};
+
+typedef enum {
+ ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP
+} alignMode;
+
+/*
* Information used for parsing window configuration options:
*/
-static Tk_CustomOption alignOption = {AlignParseProc, AlignPrintProc,
- (ClientData) NULL};
-
-static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_CUSTOM, "-align", (char *) NULL, (char *) NULL,
- "center", 0, TK_CONFIG_DONT_SET_DEFAULT, &alignOption},
- {TK_CONFIG_STRING, "-create", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbWindow, create),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_INT, "-padx", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, padX),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_INT, "-pady", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, padY),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_BOOLEAN, "-stretch", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(TkTextEmbWindow, stretch),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(TkTextEmbWindow, tkwin),
- TK_CONFIG_DONT_SET_DEFAULT|TK_CONFIG_NULL_OK},
- {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
- (char *) NULL, 0, 0}
+static Tk_OptionSpec optionSpecs[] = {
+ {TK_OPTION_STRING_TABLE, "-align", (char *) NULL, (char *) NULL,
+ "center", -1, Tk_Offset(TkTextEmbWindow, align),
+ 0, (ClientData) alignStrings, 0},
+ {TK_OPTION_STRING, "-create", (char *) NULL, (char *) NULL,
+ (char *) NULL, -1, Tk_Offset(TkTextEmbWindow, create),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_PIXELS, "-padx", (char *) NULL, (char *) NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, padX),
+ 0, 0, 0},
+ {TK_OPTION_PIXELS, "-pady", (char *) NULL, (char *) NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, padY),
+ 0, 0, 0},
+ {TK_OPTION_BOOLEAN, "-stretch", (char *) NULL, (char *) NULL,
+ "0", -1, Tk_Offset(TkTextEmbWindow, stretch),
+ 0, 0, 0},
+ {TK_OPTION_WINDOW, "-window", (char *) NULL, (char *) NULL,
+ (char *) NULL, -1, Tk_Offset(TkTextEmbWindow, tkwin),
+ TK_OPTION_NULL_OK, 0, 0},
+ {TK_OPTION_END}
};
/*
@@ -151,152 +145,171 @@ static Tk_ConfigSpec configSpecs[] = {
*/
int
-TkTextWindowCmd(textPtr, interp, argc, argv)
+TkTextWindowCmd(textPtr, interp, objc, objv)
register TkText *textPtr; /* Information about text widget. */
Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- CONST char **argv; /* Argument strings. Someone else has already
+ int objc; /* Number of arguments. */
+ Tcl_Obj *CONST objv[]; /* Argument objects. Someone else has already
* parsed this command enough to know that
- * argv[1] is "window". */
+ * objv[1] is "window". */
{
- size_t length;
+ int optionIndex;
+
+ static CONST char *windOptionStrings[] = {
+ "cget", "configure", "create", "names", (char *) NULL
+ };
+ enum windOptions {
+ WIND_CGET, WIND_CONFIGURE, WIND_CREATE, WIND_NAMES
+ };
+
register TkTextSegment *ewPtr;
- if (argc < 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window option ?arg arg ...?\"", (char *) NULL);
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?");
return TCL_ERROR;
}
- length = strlen(argv[2]);
- if ((strncmp(argv[2], "cget", length) == 0) && (length >= 2)) {
- TkTextIndex index;
- TkTextSegment *ewPtr;
-
- if (argc != 5) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window cget index option\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
- return TCL_ERROR;
- }
- ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
- if (ewPtr->typePtr != &tkTextEmbWindowType) {
- Tcl_AppendResult(interp, "no embedded window at index \"",
- argv[3], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- return Tk_ConfigureValue(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, argv[4], 0);
- } else if ((strncmp(argv[2], "configure", length) == 0) && (length >= 2)) {
- TkTextIndex index;
- TkTextSegment *ewPtr;
-
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window configure index ?option value ...?\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
- return TCL_ERROR;
- }
- ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
- if (ewPtr->typePtr != &tkTextEmbWindowType) {
- Tcl_AppendResult(interp, "no embedded window at index \"",
- argv[3], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- if (argc == 4) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, (char *) NULL, 0);
- } else if (argc == 5) {
- return Tk_ConfigureInfo(interp, textPtr->tkwin, configSpecs,
- (char *) &ewPtr->body.ew, argv[4], 0);
- } else {
- TkTextChanged(textPtr, &index, &index);
- return EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4);
+ if (Tcl_GetIndexFromObj(interp, objv[2], windOptionStrings,
+ "window option", 0, &optionIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum windOptions)optionIndex) {
+ case WIND_CGET: {
+ TkTextIndex index;
+ TkTextSegment *ewPtr;
+ Tcl_Obj *objPtr;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index option");
+ return TCL_ERROR;
+ }
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ if (ewPtr->typePtr != &tkTextEmbWindowType) {
+ Tcl_AppendResult(interp, "no embedded window at index \"",
+ Tcl_GetString(objv[3]), "\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew,
+ ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
+ break;
}
- } else if ((strncmp(argv[2], "create", length) == 0) && (length >= 2)) {
- TkTextIndex index;
- int lineIndex;
-
- /*
- * Add a new window. Find where to put the new window, and
- * mark that position for redisplay.
- */
+ case WIND_CONFIGURE: {
+ TkTextIndex index;
+ TkTextSegment *ewPtr;
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window create index ?option value ...?\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) {
- return TCL_ERROR;
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
+ return TCL_ERROR;
+ }
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ ewPtr = TkTextIndexToSeg(&index, (int *) NULL);
+ if (ewPtr->typePtr != &tkTextEmbWindowType) {
+ Tcl_AppendResult(interp, "no embedded window at index \"",
+ Tcl_GetString(objv[3]), "\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (objc <= 5) {
+ Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) &ewPtr->body.ew,
+ ewPtr->body.ew.optionTable,
+ (objc == 5) ? objv[4] : (Tcl_Obj *) NULL,
+ textPtr->tkwin);
+ if (objPtr == NULL) {
+ return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, objPtr);
+ return TCL_OK;
+ }
+ } else {
+ TkTextChanged(textPtr, &index, &index);
+ return EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4);
+ }
+ break;
}
+ case WIND_CREATE: {
+ TkTextIndex index;
+ int lineIndex;
- /*
- * Don't allow insertions on the last (dummy) line of the text.
- */
-
- lineIndex = TkBTreeLineIndex(index.linePtr);
- if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
- lineIndex--;
- TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index);
- }
+ /*
+ * Add a new window. Find where to put the new window, and
+ * mark that position for redisplay.
+ */
- /*
- * Create the new window segment and initialize it.
- */
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?");
+ return TCL_ERROR;
+ }
+ if (TkTextGetObjIndex(interp, textPtr, objv[3], &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
- ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE);
- ewPtr->typePtr = &tkTextEmbWindowType;
- ewPtr->size = 1;
- ewPtr->body.ew.textPtr = textPtr;
- ewPtr->body.ew.linePtr = NULL;
- ewPtr->body.ew.tkwin = NULL;
- ewPtr->body.ew.create = NULL;
- ewPtr->body.ew.align = ALIGN_CENTER;
- ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0;
- ewPtr->body.ew.stretch = 0;
- ewPtr->body.ew.chunkCount = 0;
- ewPtr->body.ew.displayed = 0;
+ /*
+ * Don't allow insertions on the last (dummy) line of the text.
+ */
+
+ lineIndex = TkBTreeLineIndex(index.linePtr);
+ if (lineIndex == TkBTreeNumLines(textPtr->tree)) {
+ lineIndex--;
+ TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index);
+ }
- /*
- * Link the segment into the text widget, then configure it (delete
- * it again if the configuration fails).
- */
+ /*
+ * Create the new window segment and initialize it.
+ */
- TkTextChanged(textPtr, &index, &index);
- TkBTreeLinkSegment(ewPtr, &index);
- if (EmbWinConfigure(textPtr, ewPtr, argc-4, argv+4) != TCL_OK) {
- TkTextIndex index2;
+ ewPtr = (TkTextSegment *) ckalloc(EW_SEG_SIZE);
+ ewPtr->typePtr = &tkTextEmbWindowType;
+ ewPtr->size = 1;
+ ewPtr->body.ew.textPtr = textPtr;
+ ewPtr->body.ew.linePtr = NULL;
+ ewPtr->body.ew.tkwin = NULL;
+ ewPtr->body.ew.create = NULL;
+ ewPtr->body.ew.align = ALIGN_CENTER;
+ ewPtr->body.ew.padX = ewPtr->body.ew.padY = 0;
+ ewPtr->body.ew.stretch = 0;
+ ewPtr->body.ew.chunkCount = 0;
+ ewPtr->body.ew.displayed = 0;
+ ewPtr->body.ew.optionTable = Tk_CreateOptionTable(interp, optionSpecs);
+ /*
+ * Link the segment into the text widget, then configure it (delete
+ * it again if the configuration fails).
+ */
- TkTextIndexForwChars(&index, 1, &index2);
- TkBTreeDeleteChars(&index, &index2);
- return TCL_ERROR;
- }
- } else if (strncmp(argv[2], "names", length) == 0) {
- Tcl_HashSearch search;
- Tcl_HashEntry *hPtr;
+ TkTextChanged(textPtr, &index, &index);
+ TkBTreeLinkSegment(ewPtr, &index);
+ if (EmbWinConfigure(textPtr, ewPtr, objc-4, objv+4) != TCL_OK) {
+ TkTextIndex index2;
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " window names\"", (char *) NULL);
- return TCL_ERROR;
+ TkTextIndexForwChars(&index, 1, &index2);
+ TkBTreeDeleteChars(&index, &index2);
+ return TCL_ERROR;
+ }
+ break;
}
- for (hPtr = Tcl_FirstHashEntry(&textPtr->windowTable, &search);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- Tcl_AppendElement(interp,
- Tcl_GetHashKey(&textPtr->markTable, hPtr));
+ case WIND_NAMES: {
+ Tcl_HashSearch search;
+ Tcl_HashEntry *hPtr;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 3, objv, NULL);
+ return TCL_ERROR;
+ }
+ for (hPtr = Tcl_FirstHashEntry(&textPtr->windowTable, &search);
+ hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ Tcl_AppendElement(interp,
+ Tcl_GetHashKey(&textPtr->markTable, hPtr));
+ }
+ break;
}
- } else {
- Tcl_AppendResult(interp, "bad window option \"", argv[2],
- "\": must be cget, configure, create, or names",
- (char *) NULL);
- return TCL_ERROR;
}
return TCL_OK;
}
@@ -307,7 +320,7 @@ TkTextWindowCmd(textPtr, interp, argc, argv)
* EmbWinConfigure --
*
* This procedure is called to handle configuration options
- * for an embedded window, using an argc/argv list.
+ * for an embedded window, using an objc/objv list.
*
* Results:
* The return value is a standard Tcl result. If TCL_ERROR is
@@ -322,12 +335,12 @@ TkTextWindowCmd(textPtr, interp, argc, argv)
*/
static int
-EmbWinConfigure(textPtr, ewPtr, argc, argv)
+EmbWinConfigure(textPtr, ewPtr, objc, objv)
TkText *textPtr; /* Information about text widget that
* contains embedded window. */
TkTextSegment *ewPtr; /* Embedded window to be configured. */
- int argc; /* Number of strings in argv. */
- CONST char **argv; /* Array of strings describing configuration
+ int objc; /* Number of strings in objv. */
+ Tcl_Obj *CONST objv[]; /* Array of objects describing configuration
* options. */
{
Tk_Window oldWindow;
@@ -335,9 +348,9 @@ EmbWinConfigure(textPtr, ewPtr, argc, argv)
int new;
oldWindow = ewPtr->body.ew.tkwin;
- if (Tk_ConfigureWidget(textPtr->interp, textPtr->tkwin, configSpecs,
- argc, argv, (char *) &ewPtr->body.ew, TK_CONFIG_ARGV_ONLY)
- != TCL_OK) {
+ if (Tk_SetOptions(textPtr->interp, (char*)&ewPtr->body.ew,
+ ewPtr->body.ew.optionTable,
+ objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) {
return TCL_ERROR;
}
if (oldWindow != ewPtr->body.ew.tkwin) {
@@ -414,99 +427,6 @@ EmbWinConfigure(textPtr, ewPtr, argc, argv)
/*
*--------------------------------------------------------------
*
- * AlignParseProc --
- *
- * This procedure is invoked by Tk_ConfigureWidget during
- * option processing to handle "-align" options for embedded
- * windows.
- *
- * Results:
- * A standard Tcl return value.
- *
- * Side effects:
- * The alignment for the embedded window may change.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static int
-AlignParseProc(clientData, interp, tkwin, value, widgRec, offset)
- ClientData clientData; /* Not used.*/
- Tcl_Interp *interp; /* Used for reporting errors. */
- Tk_Window tkwin; /* Window for text widget. */
- CONST char *value; /* Value of option. */
- char *widgRec; /* Pointer to TkTextEmbWindow
- * structure. */
- int offset; /* Offset into item (ignored). */
-{
- register TkTextEmbWindow *embPtr = (TkTextEmbWindow *) widgRec;
-
- if (strcmp(value, "baseline") == 0) {
- embPtr->align = ALIGN_BASELINE;
- } else if (strcmp(value, "bottom") == 0) {
- embPtr->align = ALIGN_BOTTOM;
- } else if (strcmp(value, "center") == 0) {
- embPtr->align = ALIGN_CENTER;
- } else if (strcmp(value, "top") == 0) {
- embPtr->align = ALIGN_TOP;
- } else {
- Tcl_AppendResult(interp, "bad alignment \"", value,
- "\": must be baseline, bottom, center, or top",
- (char *) NULL);
- return TCL_ERROR;
- }
- return TCL_OK;
-}
-
-/*
- *--------------------------------------------------------------
- *
- * AlignPrintProc --
- *
- * This procedure is invoked by the Tk configuration code
- * to produce a printable string for the "-align" configuration
- * option for embedded windows.
- *
- * Results:
- * The return value is a string describing the embedded
- * window's current alignment.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- /* ARGSUSED */
-static char *
-AlignPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
- ClientData clientData; /* Ignored. */
- Tk_Window tkwin; /* Window for text widget. */
- char *widgRec; /* Pointer to TkTextEmbWindow
- * structure. */
- int offset; /* Ignored. */
- Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
- * information about how to reclaim
- * storage for return string. */
-{
- switch (((TkTextEmbWindow *) widgRec)->align) {
- case ALIGN_BASELINE:
- return "baseline";
- case ALIGN_BOTTOM:
- return "bottom";
- case ALIGN_CENTER:
- return "center";
- case ALIGN_TOP:
- return "top";
- default:
- return "??";
- }
-}
-
-/*
- *--------------------------------------------------------------
- *
* EmbWinStructureProc --
*
* This procedure is invoked by the Tk event loop whenever
@@ -678,8 +598,8 @@ EmbWinDeleteProc(ewPtr, linePtr, treeGone)
Tk_DestroyWindow(ewPtr->body.ew.tkwin);
}
Tcl_CancelIdleCall(EmbWinDelayedUnmap, (ClientData) ewPtr);
- Tk_FreeOptions(configSpecs, (char *) &ewPtr->body.ew,
- ewPtr->body.ew.textPtr->display, 0);
+ Tk_FreeConfigOptions((char *) &ewPtr->body.ew, ewPtr->body.ew.optionTable,
+ ewPtr->body.ew.tkwin);
ckfree((char *) ewPtr);
return 0;
}