#!/bin/sh # This is `snmp2.26' (part 26 of snmp2). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `snmp2/snmptcl/graph.c' is being continued... # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 26; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping snmp2/snmptcl/graph.c' else echo 'x - continuing file snmp2/snmptcl/graph.c' sed 's/^X//' << 'SHAR_EOF' >> 'snmp2/snmptcl/graph.c' && X } X *p++ = '\0'; X if (Tk_GetPixels(interp, tkwin, argv[i], &width) != TCL_OK) X return TCL_ERROR; X if (Tk_GetPixels(interp, tkwin, p, &height) != TCL_OK) X return TCL_ERROR; X } else { X Tcl_AppendResult(interp, "Missing ", argv[i - 1], X " argument", (char *)NULL); X return TCL_ERROR; X } X } else { X Tcl_AppendResult(interp, "Unknown ", argv[0], " option \"", X argv[i], "\"", (char *)NULL); X return TCL_ERROR; X } X } X } X /* */ X graphPtr->psWidth = (width > 0) ? width : graphPtr->width; X graphPtr->psHeight = (height > 0) ? height : graphPtr->height; X ComputeLayout(graphPtr, graphPtr->psWidth, graphPtr->psHeight); X PSPreamble(graphPtr, &options); X PSTags(graphPtr); X PSLegend(graphPtr); X if (!NULLSTR(graphPtr->title)) { X PSText(graphPtr, graphPtr->fontPtr, graphPtr->title, X GX(graphPtr, 0.5), X PADY + graphPtr->borderWidth + FONTHEIGHT(graphPtr->fontPtr), X TK_ANCHOR_CENTER); X } X switch (graphPtr->type) { X case XYGRAPH_TYPE: X PSGraph(graphPtr); X break; X case BARCHART_TYPE: X PSBarchart(graphPtr); X break; X case PIECHART_TYPE: X fprintf(stderr, "postscript: Not implemented yet\n"); X break; X } X fputs("showpage\n", f); X fputs("%%Trailer\n", f); X fputs("%%EOF\n", f); X X fclose(f); X Tcl_SetResult(interp, options.fileName, TCL_VOLATILE); X return TCL_OK; } X /* X *---------------------------------------------------------------------- X * X * CreateGraph -- X * X * This procedure creates and initializes a new widget. X * X * Results: X * The return value is a pointer to a structure describing X * the new widget. If an error occurred, then the return X * value is NULL and an error message is left in interp->result. X * X * Side effects: X * Memory is allocated, a Tk_Window is created, etc. X * X *---------------------------------------------------------------------- X */ static Graph * CreateGraph(interp, tkwin, pathName, type) X Tcl_Interp *interp; X Tk_Window tkwin; X char *pathName; X int type; { X register Graph *graphPtr; X Tk_Window new; X X graphPtr = (Graph *) calloc(1, sizeof(Graph)); X if (graphPtr == NULL) { X return (NULL); X } X /* Create the window. */ X new = Tk_CreateWindowFromPath(interp, tkwin, pathName, NULL); X if (new == NULL) { X ckfree((char *)graphPtr); X return (NULL); X } X Tk_SetClass(new, classNames[type]); X X /* Initialize the data structure for the graph. */ X graphPtr->tkwin = new; X graphPtr->interp = interp; X graphPtr->type = type; X graphPtr->X.reqMinimum = graphPtr->Y.reqMinimum = NegativeInfinity; X graphPtr->X.reqMaximum = graphPtr->Y.reqMaximum = PositiveInfinity; X graphPtr->X.major.stepSize = graphPtr->Y.major.stepSize = 1.0; X Tk_CreateEventHandler(graphPtr->tkwin, ExposureMask | StructureNotifyMask, X GraphEventProc, (ClientData) graphPtr); X Tcl_CreateCommand(interp, Tk_PathName(graphPtr->tkwin), GraphWidgetCmd, X (ClientData) graphPtr, (Tcl_CmdDeleteProc *) NULL); X return (graphPtr); } X /* X *---------------------------------------------------------------------- X * X * DestroyGraph -- X * X * This procedure is invoked by Tk_EventuallyFree or Tk_Release X * to clean up the internal structure of a graph at a safe time X * (when no-one is using it anymore). X * X * Results: X * None. X * X * Side effects: X * Everything associated with the widget is freed up. X * X *---------------------------------------------------------------------- X */ static void DestroyGraph(clientData) X ClientData clientData; { X register Graph *graphPtr = (Graph *) clientData; X register Line *linePtr; X ListEntry *searchId; X X /* Remove the individual line data structures and then the lists */ X for (linePtr = (Line *) FirstListEntry(&(graphPtr->allLines), &searchId); X linePtr != NULL; linePtr = (Line *) NextListEntry(&searchId)) { X DestroyLine(linePtr); X } X ClearList(&(graphPtr->allLines)); X ClearList(&(graphPtr->drawnLines)); X if (graphPtr->border) /* 3D border */ X Tk_Free3DBorder(graphPtr->border); X if (graphPtr->geometry) /* Geometry */ X free(graphPtr->geometry); X if (graphPtr->gc != None)/* Graphics context of graph */ X Tk_FreeGC(graphPtr->gc); X if (graphPtr->title) /* Graph title */ X free(graphPtr->title); X if (graphPtr->fontPtr) /* Normal font */ X Tk_FreeFontStruct(graphPtr->fontPtr); X if (graphPtr->numberFontPtr) /* Axis/number font */ X Tk_FreeFontStruct(graphPtr->numberFontPtr); X if (graphPtr->numberFg) /* Axis/number color */ X Tk_FreeColor(graphPtr->numberFg); X if (graphPtr->numberGC != None) /* Graphics context of axis */ X Tk_FreeGC(graphPtr->numberGC); X if (graphPtr->fgColor) /* Foreground color */ X Tk_FreeColor(graphPtr->fgColor); X if (graphPtr->cursor != None) /* cursor */ X Tk_FreeCursor(graphPtr->cursor); X if (graphPtr->X.label) /* X axis label */ X ckfree(graphPtr->X.label); X if (graphPtr->Y.label) /* Y axis label */ X ckfree(graphPtr->Y.label); X if (graphPtr->legend.border) /* Legend 3D border */ X Tk_Free3DBorder(graphPtr->legend.border); X free((char *)graphPtr); } X /* X *---------------------------------------------------------------------- X * X * ConfigureGraph -- X * X * This procedure is called to process an argv/argc list, plus X * the Tk option database, in order to configure (or X * reconfigure) a graph widget. X * X * Results: X * The return value is a standard Tcl result. If TCL_ERROR is X * returned, then interp->result contains an error message. X * X * Side effects: X * Configuration information, such as text string, colors, font, X * etc. get set for graphPtr; old resources get freed, if there X * were any. The graph is redisplayed. X * X *---------------------------------------------------------------------- X */ static int ConfigureGraph(interp, graphPtr, argc, argv, flags) X Tcl_Interp *interp; /* Interpreter to report results back to */ X register Graph *graphPtr;/* Graph widget record */ X int argc; /* Number of configuration arguments */ X char **argv; /* Configuration arguments */ X int flags; /* Configuration flags */ { X XColor *borderColor; X GC newGC; X XGCValues gcValues; X unsigned int valueMask; X X if (Tk_ConfigureWidget(interp, graphPtr->tkwin, configSpecs, X argc, argv, (char *)graphPtr, flags) != TCL_OK) { X return TCL_ERROR; X } X if (graphPtr->geometry != NULL) { X int height, width; X X if (sscanf(graphPtr->geometry, "%dx%d", &width, &height) != 2) { X Tcl_AppendResult(interp, "bad geometry \"", graphPtr->geometry, X "\": expected widthxheight", (char *)NULL); X return TCL_ERROR; X } X Tk_GeometryRequest(graphPtr->tkwin, width, height); X graphPtr->width = width, graphPtr->height = height; X } X if (graphPtr->axisThickness <= 1) X graphPtr->axisThickness = 0; X /* Check requested X and Y axis limits */ X if (graphPtr->X.reqMinimum >= graphPtr->X.reqMaximum) { X sprintf(interp->result, "invalid X axis limits (min %g >= max %g)", X graphPtr->X.reqMinimum, graphPtr->X.reqMaximum); X return TCL_ERROR; X } X if (graphPtr->Y.reqMinimum >= graphPtr->Y.reqMaximum) { X sprintf(interp->result, "invalid Y axis limits (min %g >= max %g)", X graphPtr->Y.reqMinimum, graphPtr->Y.reqMaximum); X return TCL_ERROR; X } X borderColor = Tk_3DBorderColor(graphPtr->border); X Tk_SetInternalBorder(graphPtr->tkwin, graphPtr->borderWidth); X Tk_SetBackgroundFromBorder(graphPtr->tkwin, graphPtr->border); X X /* Create graph GC */ X gcValues.line_width = graphPtr->axisThickness; X gcValues.foreground = graphPtr->fgColor->pixel; X gcValues.background = borderColor->pixel; X gcValues.font = graphPtr->fontPtr->fid; X valueMask = (GCForeground | GCBackground | GCFont | GCLineWidth); X newGC = Tk_GetGC(graphPtr->tkwin, valueMask, &gcValues); X if (graphPtr->gc != None) X Tk_FreeGC(graphPtr->gc); X graphPtr->gc = newGC; X X /* Create axis GC */ X gcValues.font = graphPtr->numberFontPtr->fid; X gcValues.foreground = graphPtr->numberFg->pixel; X newGC = Tk_GetGC(graphPtr->tkwin, valueMask, &gcValues); X if (graphPtr->numberGC != None) X Tk_FreeGC(graphPtr->numberGC); X graphPtr->numberGC = newGC; X X return TCL_OK; } X /* X *-------------------------------------------------------------- X * X * GraphCmd -- X * X * X * Results: X * A standard Tcl result. X * X * Side effects: X * See the user documentation. X * X *-------------------------------------------------------------- X */ int GraphCmd(clientData, interp, argc, argv) X ClientData clientData; X Tcl_Interp *interp; X int argc; X char **argv; { X Tk_Window tkwin = (Tk_Window) clientData; X register Graph *graphPtr; X char c; X int type; X X if (argc < 2) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " pathName ?options?\"", (char *)NULL); X return TCL_ERROR; X } X c = argv[0][0]; X if ((c == 'x') && strcmp(argv[0], "xygraph") == 0) X type = XYGRAPH_TYPE; X else if ((c == 'b') && strcmp(argv[0], "barchart") == 0) X type = BARCHART_TYPE; X else if ((c == 'p') && strcmp(argv[0], "piechart") == 0) X type = PIECHART_TYPE; X else { X Tcl_AppendResult(interp, "Unknown graph-creation command ", X argv[0], NULL); X return TCL_ERROR; X } X /* Initialize infinity constants */ X NegativeInfinity = -HUGE_VAL; X PositiveInfinity = HUGE_VAL; X X graphPtr = CreateGraph(interp, tkwin, argv[1], type); X if (graphPtr == NULL) X return TCL_ERROR; X if (ConfigureGraph(interp, graphPtr, argc - 2, argv + 2, X configFlags[type]) != TCL_OK) { X Tk_DestroyWindow(graphPtr->tkwin); X return TCL_ERROR; X } X interp->result = Tk_PathName(graphPtr->tkwin); X return TCL_OK; } X /* X *-------------------------------------------------------------- X * X * GraphWidgetCmd -- X * X * This procedure is invoked to process the Tcl command X * that corresponds to a widget managed by this module. X * See the user documentation for details on what it does. X * X * Results: X * A standard Tcl result. X * X * Side effects: X * See the user documentation. X * X *-------------------------------------------------------------- X */ static int GraphWidgetCmd(clientData, interp, argc, argv) X ClientData clientData; X Tcl_Interp *interp; X int argc; X char **argv; { X register Graph *graphPtr = (Graph *) clientData; X register Line *linePtr; X int result = TCL_ERROR; X int redrawFlag = FALSE; X Tk_Window tkwin = graphPtr->tkwin; X char c; X int length; X int flags; X int type; X X if (argc < 2) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " option ?arg arg ...?\"", (char *)NULL); X return TCL_ERROR; X } X Tk_Preserve((ClientData) graphPtr); X X c = argv[1][0]; X length = strlen(argv[1]); X type = graphPtr->type; X flags = configFlags[type]; X if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) { X if (argc == 2) X result = Tk_ConfigureInfo(interp, tkwin, configSpecs, X (char *)graphPtr, (char *)NULL, flags); X else if (argc == 3) X result = Tk_ConfigureInfo(interp, tkwin, configSpecs, X (char *)graphPtr, argv[2], flags); X else { X result = ConfigureGraph(interp, graphPtr, argc - 2, argv + 2, X TK_CONFIG_ARGV_ONLY | flags); X redrawFlag = TRUE; X } X } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0)) { X result = GraphInsert(interp, graphPtr, argc, argv, flags, &redrawFlag); X if (result != TCL_OK) X goto error; X } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) { X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " delete name\"", NULL); X goto error; X } X result = DeleteLine(interp, graphPtr, argv[2], &redrawFlag); X } else if ((c == 't') && (strncmp(argv[1], "tagconfigure", length) == 0)) { X Tag *tagPtr; X X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " tagconfigure tagName ?arg arg ...?\"", NULL); X goto error; X } X tagPtr = (Tag *) FindListEntry(&(graphPtr->tags), argv[2]); X if (tagPtr == NULL) X goto error; X if (argc == 3) X result = Tk_ConfigureInfo(interp, tkwin, tagConfigSpecs, X (char *)tagPtr, (char *)NULL, flags); X else if (argc == 4) X result = Tk_ConfigureInfo(interp, tkwin, tagConfigSpecs, X (char *)tagPtr, argv[3], flags); X else { X result = ConfigureTag(interp, graphPtr, tagPtr, argc - 3, argv + 3, X TK_CONFIG_ARGV_ONLY | flags); X redrawFlag = TRUE; X } X } else if ((c == 'n') && (strncmp(argv[1], "newtag", length) == 0)) { X result = GraphNewTag(interp, graphPtr, argc, argv, flags, &redrawFlag); X if (result != TCL_OK) X goto error; X } else if ((c == 'u') && (strncmp(argv[1], "untag", length) == 0)) { X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " untag tagName\"", NULL); X goto error; X } X result = DeleteTag(interp, graphPtr, argv[2], &redrawFlag); X } else if ((c == 'b') && (type == BARCHART_TYPE) && X (strncmp(argv[1], "barconfigure", length) == 0)) { X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " barconfigure name ?arg arg ...?\"", NULL); X goto error; X } X goto lineconfig; X } else if ((c == 'l') && (length > 2) && X (strncmp(argv[1], "lineconfigure", length) == 0) && X (type == XYGRAPH_TYPE)) { X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " lineconfigure name ?arg arg ...?\"", NULL); X goto error; X } X lineconfig: X linePtr = (Line *) FindListEntry(&(graphPtr->allLines), argv[2]); X if (linePtr == NULL) { X Tcl_AppendResult(interp, "Can't find \"", argv[2], "\"", X NULL); X goto error; X } X if (argc == 3) X result = Tk_ConfigureInfo(interp, tkwin, lineConfigSpecs, X (char *)linePtr, (char *)NULL, flags); X else if (argc == 4) X result = Tk_ConfigureInfo(interp, tkwin, lineConfigSpecs, X (char *)linePtr, argv[3], flags); X else { X result = ConfigureLine(interp, linePtr, argc - 3, argv + 3, X TK_CONFIG_ARGV_ONLY | flags); X /* If the line is being displayed, redraw the graph */ X if (linePtr->isVisible) X redrawFlag = TRUE; X } X } else if ((c == 'l') && (length > 1) X && (strncmp(argv[1], "locate", length) == 0)) { X if (argc != 4) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " locate x y\"", NULL); X goto error; X } X result = GraphLocate(interp, graphPtr, argv[2], argv[3]); X } else if ((c == 's') && (strncmp(argv[1], "show", length) == 0)) { X if (argc == 3) { X GraphLineNames(interp, graphPtr, argv[2]); X redrawFlag = TRUE; X } else if (argc != 2) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " show ?nameList?\"", NULL); X goto error; X } X result = GetLineNames(interp, &(graphPtr->drawnLines)); X } else if ((c == 'l') && (length > 2) && X (strncmp(argv[1], "limits", length) == 0)) { X if (argc != 2) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " limits\"", NULL); X goto error; X } X result = GraphLimits(interp, graphPtr); X } else if ((c == 'n') && (strncmp(argv[1], "names", length) == 0)) { X if (argc != 2) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " names\"", NULL); X goto error; X } X result = GetLineNames(interp, &(graphPtr->allLines)); X } else if ((c == 'p') && (strncmp(argv[1], "postscript", length) == 0)) { X if (argc < 3) { X Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], X " postscript file ?options?\"", NULL); X goto error; X } X result = GraphPrint(interp, tkwin, graphPtr, argc - 1, argv + 1); X } else { X Tcl_AppendResult(interp, "bad option \"", argv[1], "\": should be ", X configNames[type], "configure, configure, delete, \ insert, limits, locate, newtag, postscript, show, tagconfigure, or untag ", X NULL); X goto error; X } X /* If plot was reconfigured, recalculate the layout of the graph */ X graphPtr->flags |= LAYOUT_NEEDED; X if (result == TCL_OK && redrawFlag == TRUE) X EventuallyRedraw(graphPtr); /* Redraw the graph */ X error: X Tk_Release((ClientData) graphPtr); X return result; } X /* X *---------------------------------------------------------------------- X * X * DisplayGraph -- X * X * This procedure is invoked to display a graph widget. X * X * Results: X * None. X * X * Side effects: X * Commands are output to X to display the graph in its X * current mode. X * X *---------------------------------------------------------------------- X */ static void DisplayGraph(clientData) X ClientData clientData; { X register Graph *graphPtr = (Graph *) clientData; X Tk_Window tkwin = graphPtr->tkwin; X Drawable draw; X Pixmap pixMap = None; X int result; X X graphPtr->flags &= ~REDRAW_PENDING; X if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) X return; X /* Reset width/height */ X graphPtr->width = Tk_Width(graphPtr->tkwin); X graphPtr->height = Tk_Height(graphPtr->tkwin); X X draw = Tk_WindowId(tkwin); X if (graphPtr->doubleBuffered) { X int depth = DefaultDepth(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); X pixMap = XCreatePixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), X graphPtr->width, graphPtr->height, depth); X draw = pixMap; X } X graphPtr->output = (ClientData) draw; /* Output device/resource */ X X /* Clear the window or pixmap */ X Tk_Fill3DRectangle(Tk_Display(tkwin), draw, graphPtr->border, X 0, 0, graphPtr->width, graphPtr->height, X graphPtr->borderWidth, graphPtr->relief); X X if (graphPtr->drawnLines.numEntries <= 0) { X if (graphPtr->doubleBuffered) { X /* Finally copy the pixmap out */ X XCopyArea(Tk_Display(tkwin), pixMap, Tk_WindowId(tkwin), X graphPtr->gc, 0, 0, graphPtr->width, graphPtr->height, X 0, 0); X XFreePixmap(Tk_Display(tkwin), pixMap); X } X return; /* No visible lines, get out */ X } X if (graphPtr->flags & LAYOUT_NEEDED) { X if (ComputeLayout(graphPtr, graphPtr->width, X graphPtr->height) != TCL_OK) { X return; /* Not enough room to plot graph, get out */ X } X graphPtr->flags &= ~LAYOUT_NEEDED; X } X DrawTags(graphPtr); X DrawLegend(graphPtr); X if (!NULLSTR(graphPtr->title)) { /* Display title */ X int y = PADY + graphPtr->borderWidth + FONTHEIGHT(graphPtr->fontPtr); X DrawText(graphPtr, graphPtr->fontPtr, graphPtr->gc, graphPtr->title, X GX(graphPtr, 0.5), y, TK_ANCHOR_CENTER); X } X switch (graphPtr->type) { X case XYGRAPH_TYPE: X result = DrawXYGraph(graphPtr); X break; X case BARCHART_TYPE: X result = DrawBarchart(graphPtr); X break; X case PIECHART_TYPE: X result = TCL_OK; X break; X } X if (result != TCL_OK) { X TkBindError(graphPtr->interp); X return; X } X if (graphPtr->doubleBuffered) { X XCopyArea(Tk_Display(tkwin), pixMap, Tk_WindowId(tkwin), X graphPtr->gc, 0, 0, graphPtr->width, graphPtr->height, 0, 0); X XFreePixmap(Tk_Display(tkwin), pixMap); X } } SHAR_EOF echo 'File snmp2/snmptcl/graph.c is complete' && $shar_touch -am 1015123693 'snmp2/snmptcl/graph.c' && chmod 0644 'snmp2/snmptcl/graph.c' || echo 'restore of snmp2/snmptcl/graph.c failed' shar_count="`wc -c < 'snmp2/snmptcl/graph.c'`" test 177403 -eq "$shar_count" || echo "snmp2/snmptcl/graph.c: original size 177403, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/snmptcl/htext2.c ============== if test -f 'snmp2/snmptcl/htext2.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/snmptcl/htext2.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/snmptcl/htext2.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/snmptcl/htext2.c' && /* X * htext.c -- X * X * Copyright 1990 Regents of the University of California. X * Permission to use, copy, modify, and distribute this X * software and its documentation for any purpose and without X * fee is hereby granted, provided that the above copyright X * notice appear in all copies. The University of California X * makes no representations about the suitability of this X * software for any purpose. It is provided "as is" without X * express or implied warranty. X * X * Copyright 1991,1992 by AT&T Bell Laboratories. X * Permission to use, copy, modify, and distribute this software X * and its documentation for any purpose and without fee is hereby X * granted, provided that the above copyright notice appear in all X * copies and that both that the copyright notice and warranty X * disclaimer appear in supporting documentation, and that the X * names of AT&T Bell Laboratories any of their entities not be used X * in advertising or publicity pertaining to distribution of the X * software without specific, written prior permission. X * X * AT&T disclaims all warranties with regard to this software, including X * all implied warranties of merchantability and fitness. In no event X * shall AT&T be liable for any special, indirect or consequential X * damages or any damages whatsoever resulting from loss of use, data X * or profits, whether in an action of contract, negligence or other X * tortious action, arising out of or in connection with the use or X * performance of this software. X * X * Hypertext widget created by George Howlett. X */ X /* X * To do: X * X * 1) Fix scroll unit round off errors. X * X * 2) Bug in reporting errors in Tcl evaluations. X * X * 3) Selections of text. (characters, word, line) X * X * 4) Tabstops for easier placement of text and child widgets. X * Use variable "tabstops" to set/reset tabstops. X * X * 5) Better error checking. X * X */ X #include #include #include #include #include #include #include #include X #define TRUE 1 #define FALSE 0 #define NULLSTR(s) ((s)==NULL || *(s)=='\0') #define LINES_ALLOC_CHUNK 512 #define MAX_WIN_SIZE 3000 X #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) X #ifdef DEBUG #include #endif X #ifdef __GNUG__ #define INLINE inline #else #define INLINE #endif X /* X * Flags passed to TkMeasureChars: taken from tkInt.h X */ #define TK_WHOLE_WORDS 1 #define TK_AT_LEAST_ONE 2 #define TK_PARTIAL_OK 4 X #define BLACK "Black" #define WHITE "White" #define BISQUE1 "#ffe4c4" #define BISQUE2 "#eed5b7" #define BISQUE3 "#cdb79e" #define LIGHTBLUE2 "#b2dfee" #define LIGHTPINK1 "#ffaeb9" #define MAROON "#b03060" X /* X * Flag bits children subwindows: X * X * VISIBLE: Child is in the viewport. X * MAPPED: Child is mapped on the screen. X */ #define MAPPED 2 #define VISIBLE 4 /* X * Flag bits for the hypertext widget: X * X * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has already been X * queued to redraw this window. X * X * LAYOUT_NEEDED: Something has happened which requires the layout of X * the text and child window positions to be recalculated. X * The following actions may cause this: X * X * - the contents of the hypertext has changed by X * either the -file or -text options. X * - a text attribute has changed (line spacing, font, etc) X * - a subwindow has changed (resized or moved). X * - a child configuration option has changed. X * X * LAYOUT_CHANGED: The layout was recalculated and the size of the world X * (text layout) has changed. X * X * VIEWPORT_MOVED: The position of the viewport has moved. The occurs X * when scrolling or goto-ing a new line. X * X * VIEWPORT_RESIZED: The size of the viewport (i.e. window size) has changed. X * X * IGNORE_EXPOSURES: Ignore exposure events in the text window. Potentially X * many expose events may occur when unmapping, rearranging, X * or resizing child subwindows during a single call to X * the text display routine. This flag is examined in the X * event handler to determine if a call to the display X * routine is necessary. X * X * GOTO_PENDING: Non-zero means that the widget should move to a new X * starting line number when redrawing. X * X */ #define REDRAW_PENDING 1 #define IGNORE_EXPOSURES 2 #define VIEWPORT_RESIZED 4 #define VIEWPORT_MOVED 8 #define LAYOUT_NEEDED 0x10 #define LAYOUT_CHANGED 0x20 #define GOTO_PENDING 0x40 X typedef struct Child { X X /* private: */ X struct Hypertext *parent;/* Parent widget */ X Tk_Window tkwin; /* Widget window */ X int flags; X X int x, y; /* Origin of child subwindow */ X short int width, height; /* Size of child region */ X X int precedingTextEnd; /* Number of characters of text */ X int precedingTextWidth; /* Width of normal text preceding child */ X X struct Child *nextPtr; /* Next child in list */ X X /* public: */ X int widthWanted; /* Constraint for width */ X int heightWanted; /* Constraint for height */ X int padX; /* Pad to child width */ X int padY; /* Pad to height */ X Tk_Anchor anchor; } Child; X /* X * Information used for parsing configuration specs: X */ X /* X * Defaults for children: X */ #define DEF_CHILD_WIDTH_WANTED "0" #define DEF_CHILD_HEIGHT_WANTED "0" #define DEF_CHILD_ANCHOR "center" #define DEF_CHILD_PADX "0" #define DEF_CHILD_PADY "0" X static Tk_ConfigSpec childConfigSpecs[]= { X {TK_CONFIG_ANCHOR, "-anchor", "anchor", "anchor", X DEF_CHILD_ANCHOR, Tk_Offset (Child, anchor), 0}, X {TK_CONFIG_PIXELS, "-height", "height", "Height", X DEF_CHILD_HEIGHT_WANTED, Tk_Offset (Child, heightWanted), 0}, X {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", X DEF_CHILD_PADX, Tk_Offset (Child, padX), 0}, X {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", X DEF_CHILD_PADY, Tk_Offset (Child, padY), 0}, X {TK_CONFIG_PIXELS, "-width", "width", "Width", X DEF_CHILD_WIDTH_WANTED, Tk_Offset (Child, widthWanted), 0}, X {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, X (char *)NULL, 0, 0} }; X /* X * Structure to contain the contents of a single line of text and the X * children on that line. X * X * Individual lines are not configureable, although changes to the X * size of children do effect its values. X */ X typedef struct { X /* private: */ X int offset; /* offset (in pixels) from world coordinate 0,0 */ X X short int height; /* Height of line */ X short int width; /* Width of line */ X short int baseline; /* Baseline of text */ X short int textLength; /* Number of characters in normal text */ X char *text; /* The plain text on the line */ X X Child *children; /* List of children for the line */ X Child *lastChild; /* Last child in list */ X } Line; X /* X * Hypertext widget. X */ typedef struct Hypertext { X /* private: */ X Tk_Window tkwin; /* Window that embodies the child. NULL means X * that the window has been destroyed. */ X Tcl_Interp *interp; /* Interpreter associated with child. */ X int flags; X X GC gc; /* Graphics context for normal text */ X Tk_3DBorder border; /* used ?? */ X XColor *normalFg; X X Line **lineArr; /* Array of text lines */ X int numLines; /* Number of filled entries in array */ X int arraySize; /* Number of entries allocated for array */ X int height; /* Height of text in pixels */ X int width; /* Width of text in pixels */ X X /* X * The view port is the width and height of the window and the origin of X * the viewport (upper left corner) in world coordinates. X */ X int x, y; X int newX, newY; X int lineRequested; /* Line requested by "gotoline" command */ X int first, last; /* Range of lines displayed */ X X /* X * Selections: X */ X Tk_3DBorder selBorder; /* Border and background for selected X * characters. */ X int selBorderWidth; /* Width of border around selection. */ X XColor *selFgColorPtr; /* Foreground color for selected text. */ X GC selTextGC; /* For drawing selected text. */ X X /* X * Information about what's selected, if any. X */ X X int selectFirst; /* Position of first selected character (-1 X * means nothing selected). */ X int selectLast; /* Position of last selected character (-1 means X * nothing selected). */ X int selectAnchor; /* Fixed end of selection (i.e. "select to" X * operation will use this as one end of the X * selection). */ X X /* X * Information for scanning: X */ X X int scanMarkX; /* X-position at which scan started (e.g. button X * was pressed here). */ X int scanPtX; /* Position (x-offset) of the viewport when the X * scan started. */ X X int scanMarkY; /* Y-position at which scan started (e.g. button X * was pressed here). */ X int scanPtY; /* Position (y-offset) of the viewport when the X * scan started. */ X X /* public: */ X char *geometry; X char *yScrollCmd; /* Name of vertical scrollbar to invoke */ X int yScrollUnits; /* # of pixels per vert scroll */ X char *xScrollCmd; /* Name of horizontal scroll bar to invoke */ X int xScrollUnits; /* # of pixels per horiz scroll */ X int lineSpacing; /* # of pixels between lines */ X int specChar; /* Special character designating a TCL command X * block in a hypertext file. */ X XFontStruct *fontPtr; /* Font for normal text */ X X char *fileName; /* Name of hypertext file */ X char *text; /* Text */ X Cursor cursor; /* X Cursor for child */ X } Hypertext; X #define DEF_HTEXT_ACTIVE_BG_COLOR BISQUE2 #define DEF_HTEXT_ACTIVE_BG_MONO BLACK #define DEF_HTEXT_ACTIVE_FG_COLOR BLACK #define DEF_HTEXT_ACTIVE_FG_MONO WHITE #define DEF_HTEXT_BG_COLOR BISQUE1 #define DEF_HTEXT_BG_MONO WHITE #define DEF_HTEXT_COMMAND ((char *) NULL) #define DEF_HTEXT_CURSOR "pencil" #define DEF_HTEXT_FONT "*-Helvetica-Bold-R-Normal-*-120-*" #define DEF_HTEXT_FG BLACK #define DEF_HTEXT_GEOMETRY "500x500" #define DEF_HTEXT_OFF_VALUE "0" #define DEF_HTEXT_ON_VALUE "1" #define DEF_HTEXT_RELIEF "sunken" #define DEF_HTEXT_SCROLL_UNITS "10" #define DEF_HTEXT_LINE_SPACING "1" #define DEF_HTEXT_SPEC_CHAR "0x25" X X static Tk_ConfigSpec configSpecs[]= { X {TK_CONFIG_BORDER, "-background", "background", "Background", X DEF_HTEXT_BG_COLOR, Tk_Offset (Hypertext, border), TK_CONFIG_COLOR_ONLY}, X {TK_CONFIG_BORDER, "-background", "background", "Background", X DEF_HTEXT_BG_MONO, Tk_Offset (Hypertext, border), TK_CONFIG_MONO_ONLY}, X {TK_CONFIG_SYNONYM, "-bg", "background", (char *)NULL, X (char *)NULL, 0, 0}, X {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *)NULL, X (char *)NULL, 0, 0}, X {TK_CONFIG_FONT, "-font", "font", "Font", X DEF_HTEXT_FONT, Tk_Offset (Hypertext, fontPtr), 0}, X {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", X DEF_HTEXT_FG, Tk_Offset (Hypertext, normalFg), 0}, X {TK_CONFIG_STRING, "-geometry", "geometry", "Geometry", X DEF_HTEXT_GEOMETRY, Tk_Offset (Hypertext, geometry), 0}, X {TK_CONFIG_STRING, "-text", "text", "Text", X (char *)NULL, Tk_Offset (Hypertext, text), 0}, X {TK_CONFIG_STRING, "-filename", "fileName", "FileName", X (char *)NULL, Tk_Offset (Hypertext, fileName), 0}, X {TK_CONFIG_INT, "-specialchar", "specialChar", "SpecialChar", X DEF_HTEXT_SPEC_CHAR, Tk_Offset (Hypertext, specChar), 0}, X {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", X (char *)NULL, Tk_Offset (Hypertext, yScrollCmd), 0}, X {TK_CONFIG_PIXELS, "-yscrollunits", "yScrollUnits", "yScrollUnits", X DEF_HTEXT_SCROLL_UNITS, Tk_Offset (Hypertext, yScrollUnits), 0}, X {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", X (char *)NULL, Tk_Offset (Hypertext, xScrollCmd), 0}, X {TK_CONFIG_PIXELS, "-xscrollunits", "xScrollUnits", "ScrollUnits", X DEF_HTEXT_SCROLL_UNITS, Tk_Offset (Hypertext, xScrollUnits), 0}, X {TK_CONFIG_PIXELS, "-linespacing", "lineSpacing", "LineSpacing", X DEF_HTEXT_LINE_SPACING, Tk_Offset (Hypertext, lineSpacing), 0}, X {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", X DEF_HTEXT_CURSOR, Tk_Offset (Hypertext, cursor), TK_CONFIG_NULL_OK}, X {TK_CONFIG_END, (char *)NULL, (char *)NULL, (char *)NULL, X (char *)NULL, 0, 0} }; X /* Forward Declarations */ static Hypertext *CreateText _ANSI_ARGS_ ((Tcl_Interp * interp, X Tk_Window tkwin, char *name)); static void DestroyText _ANSI_ARGS_ ((ClientData clientdata)); static int ConfigureText _ANSI_ARGS_ ((Tcl_Interp * interp, X Hypertext * textPtr, int argc, char **argv, int flags)); static void TextEventProc _ANSI_ARGS_ ((ClientData clientdata, X XEvent * eventPtr)); static void EventuallyRedraw _ANSI_ARGS_ ((Hypertext * textPtr)); static void TextScanTo _ANSI_ARGS_ ((Hypertext * textPtr, int x, int y)); static int ParseText _ANSI_ARGS_ ((Tcl_Interp * interp, Hypertext * textPtr)); static int ReadFile _ANSI_ARGS_ ((Tcl_Interp * interp, Hypertext * textPtr)); static int AppendChild _ANSI_ARGS_ ((Hypertext * textPtr, char *childName, X int argc, char **argv)); static Child *CreateChild _ANSI_ARGS_ ((Tcl_Interp * interp, X Hypertext * textPtr, char *childName)); static void DestroyChild _ANSI_ARGS_ ((Child * childPtr)); static void ChildStructureProc _ANSI_ARGS_ ((ClientData clientdata, X XEvent * eventPtr)); static int ConfigureChild _ANSI_ARGS_ ((Hypertext * textPtr, Child * childPtr, X int argc, char **argv, int flags)); static Child *FindChild _ANSI_ARGS_ ((Tcl_Interp * interp, Hypertext * textPtr, X char *childName)); static char *GetTclCommand _ANSI_ARGS_ ((Hypertext * textPtr, int *curPos, X char *command)); static Line *GetLine _ANSI_ARGS_ ((Hypertext * textPtr)); static void DestroyLine _ANSI_ARGS_ ((Line * linePtr)); static void SetLineText _ANSI_ARGS_ ((Line * linePtr, char *line, int size)); static void ComputeLayout _ANSI_ARGS_ ((Hypertext * textPtr, int *width, X int *height)); static void GetLineExtents _ANSI_ARGS_ ((Hypertext * textPtr, Line * linePtr)); static void FreeLines _ANSI_ARGS_ ((Hypertext * textPtr)); static void AdjustLinesAllocated _ANSI_ARGS_ ((Hypertext * textPtr)); static void DisplayText _ANSI_ARGS_ ((ClientData clientData)); static void DrawPage _ANSI_ARGS_ ((Hypertext * textPtr, int deltaY)); static void MoveChild _ANSI_ARGS_ ((Child * childPtr, int x, int y)); static void TextUpdateScrollBar _ANSI_ARGS_ ((Tcl_Interp * interp, char *cmd, X int total, int window, int first, int units)); static int GetVisibleLines _ANSI_ARGS_ ((Hypertext * textPtr)); static int LineSearch _ANSI_ARGS_ ((Hypertext * textPtr, int position, X int low, int high)); static char *reallocate _ANSI_ARGS_ ((char *object, unsigned int newSize, X unsigned int oldSize)); static void CreateTraces _ANSI_ARGS_ ((Hypertext * textPtr)); static void DeleteTraces _ANSI_ARGS_ ((Hypertext * textPtr)); static void ChildGeometryProc _ANSI_ARGS_ ((ClientData clientData, X Tk_Window tkwin)); static void SendExposeEvent _ANSI_ARGS_ ((Tk_Window tkwin)); X extern void TkDisplayChars _ANSI_ARGS_ ((Display * display, Drawable drawable, X GC gc, XFontStruct * fontStructPtr, char *string, int numChars, X int x, int y, int flags)); extern int TkMeasureChars _ANSI_ARGS_ ((XFontStruct * fontStructPtr, X char *source, int maxChars, int startX, int maxX, int flags, X int *nextXPtr)); extern void TkBindError _ANSI_ARGS_ ((Tcl_Interp * interp)); X /* end of Forward Declarations */ X extern char *sys_errlist[]; X static int OptionChanged (offset, specs) X register int offset; X Tk_ConfigSpec specs[]; { X register Tk_ConfigSpec *specPtr; X X for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { X if (offset == specPtr->offset) X return (specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED); X } X /* Can't be here */ X fprintf (stderr, "Unknown option specified\n"); X return (0); } X /* X * -------------------------------------------------------------- X * X * HypertextCmd -- X * X * This procedure is invoked to process the "htext" Tcl command. X * See the user documentation for details on what it does. X * X * Results: X * A standard Tcl result. X * X * Side effects: X * See the user documentation. X * X * -------------------------------------------------------------- X */ X int HypertextCmd (clientData, interp, argc, argv) X ClientData clientData; /* Main window associated with interpreter. */ X Tcl_Interp *interp; /* Current interpreter. */ X int argc; /* Number of arguments. */ X char **argv; /* Argument strings. */ { X register Hypertext *textPtr; X Tk_Window tkwin = (Tk_Window) clientData; X X if (argc < 2) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " pathName ?options?\"", NULL); X return TCL_ERROR; X } X textPtr = CreateText (interp, tkwin, argv[1]); X if (textPtr == NULL) { X return TCL_ERROR; X } X if (ConfigureText (interp, textPtr, argc - 2, argv + 2, 0) != TCL_OK) { X Tk_DestroyWindow (textPtr->tkwin); X return TCL_ERROR; X } X interp->result = Tk_PathName (textPtr->tkwin); X return TCL_OK; } X /* X * -------------------------------------------------------------- X * X * TextWidgetCmd -- X * X * This procedure is invoked to process the Tcl command that X * corresponds to a widget managed by this module. See the user X * documentation for details on what it does. X * X * Results: X * A standard Tcl result. X * X * Side effects: X * See the user documentation. X * X * -------------------------------------------------------------- X */ X static int TextWidgetCmd (clientData, interp, argc, argv) X ClientData clientData; /* Information about hypertext widget. */ X Tcl_Interp *interp; /* Current interpreter. */ X int argc; /* Number of arguments. */ X char **argv; /* Argument strings. */ { X register Hypertext *textPtr = (Hypertext *) clientData; X Tk_Window tkwin = textPtr->tkwin; X int result = TCL_OK; X int length; X char c; X X if (argc < 2) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " option ?arg arg ...?\"", NULL); X return TCL_ERROR; X } X Tk_Preserve ((ClientData) textPtr); X c = argv[1][0]; X length = strlen (argv[1]); X X if ((c == 'a') && (strncmp (argv[1], "append", length) == 0)) { X if (argc < 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " append pathName ?options?\"", NULL); X goto error; X } X if (AppendChild (textPtr, argv[2], argc - 3, argv + 3) != TCL_OK) X goto error; X goto redisplay; X } else if ((c == 'c') && (length > 1) && X (strncmp (argv[1], "childconfigure", length) == 0)) { X Child *childPtr; X X if (argc < 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " childconfigure childName ?args...?\"", NULL); X goto error; X } X childPtr = FindChild (interp, textPtr, argv[2]); X if (childPtr == NULL) { X Tcl_AppendResult (interp, X "Can't find any child window matching \"", argv[2], "\" in \"", X Tk_PathName (tkwin), "\"", NULL); X goto error; X } X if (argc == 3) { X return (Tk_ConfigureInfo (interp, tkwin, childConfigSpecs, X (char *)childPtr, (char *)NULL, 0)); X } else if (argc == 4) { X return (Tk_ConfigureInfo (interp, tkwin, childConfigSpecs, X (char *)childPtr, argv[3], 0)); X } else { X result = ConfigureChild (textPtr, childPtr, argc - 3, argv + 3, X TK_CONFIG_ARGV_ONLY); X } X goto redisplay; X X } else if ((c == 'c') && (length > 1) && X (strncmp (argv[1], "configure", length) == 0)) { X if (argc == 2) { X result = Tk_ConfigureInfo (interp, tkwin, configSpecs, X (char *)textPtr, (char *)NULL, 0); X } else if (argc == 3) { X result = Tk_ConfigureInfo (interp, tkwin, configSpecs, X (char *)textPtr, argv[2], 0); X } else { X result = ConfigureText (interp, textPtr, argc - 2, argv + 2, X TK_CONFIG_ARGV_ONLY); X goto redisplay; X } X } else if ((c == 'g') && (strncmp (argv[1], "gotoline", length) == 0)) { X char buf[80]; X int lineNumber; X X if (argc > 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " gotoline lineNumber\"", NULL); X goto error; X } X lineNumber = textPtr->first; X if (argc == 3) { X if (Tcl_GetInt (interp, argv[2], &lineNumber) != TCL_OK) X goto error; X if (lineNumber <= 0) X lineNumber = 0; X else if (lineNumber > textPtr->numLines) X lineNumber = textPtr->numLines - 1; X else X lineNumber--; X } X sprintf (buf, "%d", lineNumber + 1); X Tcl_SetResult (interp, buf, TCL_VOLATILE); X result = TCL_OK; X if ((textPtr->flags & GOTO_PENDING) || lineNumber != textPtr->first) { X /* X * Defer performing the actual scroll to later since the layout may X * may not be correct or the window may be unmapped. X */ X textPtr->lineRequested = lineNumber; X textPtr->flags |= (GOTO_PENDING | VIEWPORT_MOVED); X goto redisplay; X } X } else if ((c == 'x') && (strncmp (argv[1], "xview", length) == 0)) { X char buf[80]; X int newX; X X if (argc > 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " xview ?position?\"", NULL); X goto error; X } X newX = textPtr->x; X if (argc == 3) { X if (Tk_GetPixels (interp, tkwin, argv[2], &newX) != TCL_OK) X goto error; X newX *= textPtr->xScrollUnits; /* Convert to pixels */ X if (newX > textPtr->width) X newX = textPtr->width - 1; X else if (newX < 0) X newX = 0; X } X sprintf (buf, "%d", newX / textPtr->xScrollUnits); X Tcl_SetResult (interp, buf, TCL_VOLATILE); X result = TCL_OK; X if (newX != textPtr->x) { X textPtr->newX = newX; X textPtr->flags |= VIEWPORT_MOVED; X goto redisplay; X } X } else if ((c == 'y') && (strncmp (argv[1], "yview", length) == 0)) { X char buf[80]; X int newY; X X if (argc > 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " yview ?position?\"", NULL); X goto error; X } X newY = textPtr->y; X if (argc == 3) { X if (Tk_GetPixels (interp, tkwin, argv[2], &newY) != TCL_OK) X goto error; X newY *= textPtr->yScrollUnits; X if (newY > textPtr->height) X newY = textPtr->height - 1; X else if (newY < 0) X newY = 0; X } X sprintf (buf, "%d", newY / textPtr->yScrollUnits); X Tcl_SetResult (interp, buf, TCL_VOLATILE); X result = TCL_OK; X if (newY != textPtr->y) { X textPtr->newY = newY; X textPtr->flags |= VIEWPORT_MOVED; X goto redisplay; X } X } else if ((c == 'm') && (strncmp (argv[1], "map", length) == 0)) { X Child *childPtr; X X if (argc != 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " map childName\"", NULL); X goto error; X } X childPtr = FindChild (interp, textPtr, argv[2]); X if (childPtr == NULL) { X Tcl_AppendResult (interp, X "Can't find any child window matching \"", argv[2], "\" in \"", X Tk_PathName (tkwin), "\"", NULL); X goto error; X } X if (childPtr->tkwin != NULL) { X Tk_MapWindow (childPtr->tkwin); X childPtr->flags |= MAPPED; X } X } else if ((c == 'u') && (strncmp (argv[1], "unmap", length) == 0)) { X Child *childPtr; X X if (argc != 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", argv[0], X " unmap childName\"", NULL); X goto error; X } X childPtr = FindChild (interp, textPtr, argv[2]); X if (childPtr == NULL) { X Tcl_AppendResult (interp, X "Can't find any child window matching \"", argv[2], "\" in \"", X Tk_PathName (tkwin), "\"", NULL); X goto error; X } X if (childPtr->tkwin != NULL) { X Tk_UnmapWindow (childPtr->tkwin); X childPtr->flags &= ~MAPPED; X } X } else if ((c == 's') && (length > 1) X && (strncmp (argv[1], "scan", length) == 0)) { X int x, y; X X if (argc != 5) { X Tcl_AppendResult (interp, "wrong # args: should be \"", X argv[0], " scan mark|dragto x y\"", (char *)NULL); X goto error; X } X if (Tcl_GetInt (interp, argv[3], &x) != TCL_OK || X Tcl_GetInt (interp, argv[4], &y) != TCL_OK) { X goto error; X } X c = argv[2][0]; X length = strlen (argv[2]); X if ((c == 'm') && (strncmp (argv[2], "mark", length) == 0)) { X textPtr->scanMarkX = x; X textPtr->scanMarkY = y; X textPtr->scanPtX = textPtr->x; X textPtr->scanPtY = textPtr->y; X } else if ((c == 'd') && (strncmp (argv[2], "dragto", length) == 0)) { X TextScanTo (textPtr, x, y); X } else { X Tcl_AppendResult (interp, "bad scan option \"", argv[2], X "\": must be mark or dragto", (char *)NULL); X goto error; X } #ifdef notdef X } else if ((c == 's') && (length > 1) && X strncmp (argv[1], "select", length) == 0) { X int index; X X if (argc < 3) { X Tcl_AppendResult (interp, "too few args: should be \"", X argv[0], " select option ?index?\"", (char *)NULL); X goto error; X } X length = strlen (argv[2]); X c = argv[2][0]; X if ((c == 'c') && (strncmp (argv[2], "clear", length) == 0)) { X if (argc != 3) { X Tcl_AppendResult (interp, "wrong # args: should be \"", X argv[0], " select clear\"", (char *)NULL); X goto error; X } X if (textPtr->selectFirst != -1) { X textPtr->selectFirst = textPtr->selectLast = -1; X goto redisplay; X } X goto error; X } X if (argc >= 4) { X if (GetTextIndex (interp, textPtr, argv[3], &index) != TCL_OK) { X goto error; X } X } X if ((c == 'a') && (strncmp (argv[2], "adjust", length) == 0)) { X if (argc != 4) { X Tcl_AppendResult (interp, "wrong # args: should be \"", X argv[0], " select adjust index\"", X (char *)NULL); X goto error; X } X TextSelectTo (textPtr, index); X } else if ((c == 'f') && (strncmp (argv[2], "from", length) == 0)) { X if (argc != 4) { X Tcl_AppendResult (interp, "wrong # args: should be \"", X argv[0], " select from index\"", X (char *)NULL); X goto error; X } X textPtr->selectAnchor = index; X } else if ((c == 't') && (strncmp (argv[2], "to", length) == 0)) { X if (argc != 4) { X Tcl_AppendResult (interp, "wrong # args: should be \"", X argv[0], " select to index\"", X (char *)NULL); X goto error; X } X TextSelectTo (textPtr, index); X } else { X Tcl_AppendResult (interp, "bad select option \"", argv[2], X "\": must be adjust, clear, from, or to", (char *)NULL); X goto error; X } #endif X } else { X Tcl_AppendResult (interp, "bad option \"", argv[1], "\":", SHAR_EOF : || echo 'restore of snmp2/snmptcl/htext2.c failed' fi echo 'End of snmp2 part 26' echo 'File snmp2/snmptcl/htext2.c is continued in part 27' echo 27 > _sharseq.tmp exit 0