diff options
Diffstat (limited to 'generic')
95 files changed, 19945 insertions, 14756 deletions
diff --git a/generic/prolog.ps b/generic/prolog.ps new file mode 100644 index 0000000..2971a8a --- /dev/null +++ b/generic/prolog.ps @@ -0,0 +1,284 @@ +%%BeginProlog +50 dict begin + +% This is a standard prolog for Postscript generated by Tk's canvas +% widget. +% RCS: @(#) $Id: prolog.ps,v 1.2 1999/04/16 01:51:09 stanton Exp $ + +% The definitions below just define all of the variables used in +% any of the procedures here. This is needed for obscure reasons +% explained on p. 716 of the Postscript manual (Section H.2.7, +% "Initializing Variables," in the section on Encapsulated Postscript). + +/baseline 0 def +/stipimage 0 def +/height 0 def +/justify 0 def +/lineLength 0 def +/spacing 0 def +/stipple 0 def +/strings 0 def +/xoffset 0 def +/yoffset 0 def +/tmpstip null def + +% Define the array ISOLatin1Encoding (which specifies how characters are +% encoded for ISO-8859-1 fonts), if it isn't already present (Postscript +% level 2 is supposed to define it, but level 1 doesn't). + +systemdict /ISOLatin1Encoding known not { + /ISOLatin1Encoding [ + /space /space /space /space /space /space /space /space + /space /space /space /space /space /space /space /space + /space /space /space /space /space /space /space /space + /space /space /space /space /space /space /space /space + /space /exclam /quotedbl /numbersign /dollar /percent /ampersand + /quoteright + /parenleft /parenright /asterisk /plus /comma /minus /period /slash + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /space + /space /space /space /space /space /space /space /space + /space /space /space /space /space /space /space /space + /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent + /dieresis /space /ring /cedilla /space /hungarumlaut /ogonek /caron + /space /exclamdown /cent /sterling /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen + /registered /macron + /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph + /periodcentered + /cedillar /onesuperior /ordmasculine /guillemotright /onequarter + /onehalf /threequarters /questiondown + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex + /Idieresis + /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn + /germandbls + /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex + /idieresis + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn + /ydieresis + ] def +} if + +% font ISOEncode font +% This procedure changes the encoding of a font from the default +% Postscript encoding to ISOLatin1. It's typically invoked just +% before invoking "setfont". The body of this procedure comes from +% Section 5.6.1 of the Postscript book. + +/ISOEncode { + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding ISOLatin1Encoding def + currentdict + end + + % I'm not sure why it's necessary to use "definefont" on this new + % font, but it seems to be important; just use the name "Temporary" + % for the font. + + /Temporary exch definefont +} bind def + +% StrokeClip +% +% This procedure converts the current path into a clip area under +% the assumption of stroking. It's a bit tricky because some Postscript +% interpreters get errors during strokepath for dashed lines. If +% this happens then turn off dashes and try again. + +/StrokeClip { + {strokepath} stopped { + (This Postscript printer gets limitcheck overflows when) = + (stippling dashed lines; lines will be printed solid instead.) = + [] 0 setdash strokepath} if + clip +} bind def + +% desiredSize EvenPixels closestSize +% +% The procedure below is used for stippling. Given the optimal size +% of a dot in a stipple pattern in the current user coordinate system, +% compute the closest size that is an exact multiple of the device's +% pixel size. This allows stipple patterns to be displayed without +% aliasing effects. + +/EvenPixels { + % Compute exact number of device pixels per stipple dot. + dup 0 matrix currentmatrix dtransform + dup mul exch dup mul add sqrt + + % Round to an integer, make sure the number is at least 1, and compute + % user coord distance corresponding to this. + dup round dup 1 lt {pop 1} if + exch div mul +} bind def + +% width height string StippleFill -- +% +% Given a path already set up and a clipping region generated from +% it, this procedure will fill the clipping region with a stipple +% pattern. "String" contains a proper image description of the +% stipple pattern and "width" and "height" give its dimensions. Each +% stipple dot is assumed to be about one unit across in the current +% user coordinate system. This procedure trashes the graphics state. + +/StippleFill { + % The following code is needed to work around a NeWSprint bug. + + /tmpstip 1 index def + + % Change the scaling so that one user unit in user coordinates + % corresponds to the size of one stipple dot. + 1 EvenPixels dup scale + + % Compute the bounding box occupied by the path (which is now + % the clipping region), and round the lower coordinates down + % to the nearest starting point for the stipple pattern. Be + % careful about negative numbers, since the rounding works + % differently on them. + + pathbbox + 4 2 roll + 5 index div dup 0 lt {1 sub} if cvi 5 index mul 4 1 roll + 6 index div dup 0 lt {1 sub} if cvi 6 index mul 3 2 roll + + % Stack now: width height string y1 y2 x1 x2 + % Below is a doubly-nested for loop to iterate across this area + % in units of the stipple pattern size, going up columns then + % across rows, blasting out a stipple-pattern-sized rectangle at + % each position + + 6 index exch { + 2 index 5 index 3 index { + % Stack now: width height string y1 y2 x y + + gsave + 1 index exch translate + 5 index 5 index true matrix tmpstip imagemask + grestore + } for + pop + } for + pop pop pop pop pop +} bind def + +% -- AdjustColor -- +% Given a color value already set for output by the caller, adjusts +% that value to a grayscale or mono value if requested by the CL +% variable. + +/AdjustColor { + CL 2 lt { + currentgray + CL 0 eq { + .5 lt {0} {1} ifelse + } if + setgray + } if +} bind def + +% x y strings spacing xoffset yoffset justify stipple DrawText -- +% This procedure does all of the real work of drawing text. The +% color and font must already have been set by the caller, and the +% following arguments must be on the stack: +% +% x, y - Coordinates at which to draw text. +% strings - An array of strings, one for each line of the text item, +% in order from top to bottom. +% spacing - Spacing between lines. +% xoffset - Horizontal offset for text bbox relative to x and y: 0 for +% nw/w/sw anchor, -0.5 for n/center/s, and -1.0 for ne/e/se. +% yoffset - Vertical offset for text bbox relative to x and y: 0 for +% nw/n/ne anchor, +0.5 for w/center/e, and +1.0 for sw/s/se. +% justify - 0 for left justification, 0.5 for center, 1 for right justify. +% stipple - Boolean value indicating whether or not text is to be +% drawn in stippled fashion. If text is stippled, +% procedure StippleText must have been defined to call +% StippleFill in the right way. +% +% Also, when this procedure is invoked, the color and font must already +% have been set for the text. + +/DrawText { + /stipple exch def + /justify exch def + /yoffset exch def + /xoffset exch def + /spacing exch def + /strings exch def + + % First scan through all of the text to find the widest line. + + /lineLength 0 def + strings { + stringwidth pop + dup lineLength gt {/lineLength exch def} {pop} ifelse + newpath + } forall + + % Compute the baseline offset and the actual font height. + + 0 0 moveto (TXygqPZ) false charpath + pathbbox dup /baseline exch def + exch pop exch sub /height exch def pop + newpath + + % Translate coordinates first so that the origin is at the upper-left + % corner of the text's bounding box. Remember that x and y for + % positioning are still on the stack. + + translate + lineLength xoffset mul + strings length 1 sub spacing mul height add yoffset mul translate + + % Now use the baseline and justification information to translate so + % that the origin is at the baseline and positioning point for the + % first line of text. + + justify lineLength mul baseline neg translate + + % Iterate over each of the lines to output it. For each line, + % compute its width again so it can be properly justified, then + % display it. + + strings { + dup stringwidth pop + justify neg mul 0 moveto + stipple { + + % The text is stippled, so turn it into a path and print + % by calling StippledText, which in turn calls StippleFill. + % Unfortunately, many Postscript interpreters will get + % overflow errors if we try to do the whole string at + % once, so do it a character at a time. + + gsave + /char (X) def + { + char 0 3 -1 roll put + currentpoint + gsave + char true charpath clip StippleText + grestore + char stringwidth translate + moveto + } forall + grestore + } {show} ifelse + 0 spacing neg translate + } forall +} bind def + +%%EndProlog diff --git a/generic/tk.decls b/generic/tk.decls index 6d301f5..9fb67fd 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -10,7 +10,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: tk.decls,v 1.2 1999/03/10 07:04:38 stanton Exp $ +# RCS: @(#) $Id: tk.decls,v 1.3 1999/04/16 01:51:09 stanton Exp $ library tk @@ -77,7 +77,7 @@ declare 8 generic { declare 9 generic { int Tk_CanvasGetCoord (Tcl_Interp *interp, \ - Tk_Canvas canvas, char *string, double *doublePtr) + Tk_Canvas canvas, char *str, double *doublePtr) } declare 10 generic { @@ -186,7 +186,7 @@ declare 30 generic { declare 31 generic { Tk_TextLayout Tk_ComputeTextLayout (Tk_Font font, \ - CONST char *string, int numChars, int wrapLength, \ + CONST char *str, int numChars, int wrapLength, \ Tk_Justify justify, int flags, int *widthPtr, \ int *heightPtr) } @@ -198,7 +198,7 @@ declare 32 generic { declare 33 generic { unsigned long Tk_CreateBinding (Tcl_Interp *interp, \ Tk_BindingTable bindingTable, ClientData object, \ - char *eventString, char *command, int append) + char *eventStr, char *command, int append) } declare 34 generic { @@ -251,8 +251,8 @@ declare 43 generic { } declare 44 generic { - int Tk_DefineBitmap (Tcl_Interp *interp, \ - Tk_Uid name, char *source, int width, int height) + int Tk_DefineBitmap (Tcl_Interp *interp, CONST char *name, char *source, \ + int width, int height) } declare 45 generic { @@ -266,7 +266,7 @@ declare 46 generic { declare 47 generic { int Tk_DeleteBinding (Tcl_Interp *interp, \ Tk_BindingTable bindingTable, ClientData object, \ - char *eventString) + char *eventStr) } declare 48 generic { @@ -315,22 +315,19 @@ declare 57 generic { } declare 58 generic { - void Tk_Draw3DRectangle (Tk_Window tkwin, \ - Drawable drawable, Tk_3DBorder border, int x, \ - int y, int width, int height, int borderWidth, \ - int relief) + void Tk_Draw3DRectangle (Tk_Window tkwin, Drawable drawable, \ + Tk_3DBorder border, int x, int y, int width, int height, \ + int borderWidth, int relief) } declare 59 generic { - void Tk_DrawChars (Display *display, \ - Drawable drawable, GC gc, Tk_Font tkfont, \ - CONST char *source, int numChars, int x, \ - int y) + void Tk_DrawChars (Display *display, Drawable drawable, GC gc, \ + Tk_Font tkfont, CONST char *source, int numBytes, int x, int y) } declare 60 generic { - void Tk_DrawFocusHighlight (Tk_Window tkwin, \ - GC gc, int width, Drawable drawable) + void Tk_DrawFocusHighlight (Tk_Window tkwin, GC gc, int width, \ + Drawable drawable) } declare 61 generic { @@ -430,7 +427,7 @@ declare 81 generic { declare 82 generic { int Tk_GetAnchor (Tcl_Interp *interp, \ - char *string, Tk_Anchor *anchorPtr) + char *str, Tk_Anchor *anchorPtr) } declare 83 generic { @@ -440,11 +437,11 @@ declare 83 generic { declare 84 generic { char * Tk_GetBinding (Tcl_Interp *interp, \ Tk_BindingTable bindingTable, ClientData object, \ - char *eventString) + char *eventStr) } declare 85 generic { - Pixmap Tk_GetBitmap (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid string) + Pixmap Tk_GetBitmap (Tcl_Interp *interp, Tk_Window tkwin, CONST char * str) } declare 86 generic { @@ -453,7 +450,7 @@ declare 86 generic { } declare 87 generic { - int Tk_GetCapStyle (Tcl_Interp *interp, char *string, int *capPtr) + int Tk_GetCapStyle (Tcl_Interp *interp, char *str, int *capPtr) } declare 88 generic { @@ -465,12 +462,12 @@ declare 89 generic { } declare 90 generic { - Colormap Tk_GetColormap (Tcl_Interp *interp, Tk_Window tkwin, char *string) + Colormap Tk_GetColormap (Tcl_Interp *interp, Tk_Window tkwin, char *str) } declare 91 generic { Tk_Cursor Tk_GetCursor (Tcl_Interp *interp, Tk_Window tkwin, \ - Tk_Uid string) + Tk_Uid str) } declare 92 generic { @@ -482,12 +479,11 @@ declare 92 generic { declare 93 generic { Tk_Font Tk_GetFont (Tcl_Interp *interp, \ - Tk_Window tkwin, CONST char *string) + Tk_Window tkwin, CONST char *str) } declare 94 generic { - Tk_Font Tk_GetFontFromObj (Tcl_Interp *interp, \ - Tk_Window tkwin, Tcl_Obj *objPtr) + Tk_Font Tk_GetFontFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) } declare 95 generic { @@ -513,12 +509,12 @@ declare 99 generic { } declare 100 generic { - int Tk_GetJoinStyle (Tcl_Interp *interp, char *string, int *joinPtr) + int Tk_GetJoinStyle (Tcl_Interp *interp, char *str, int *joinPtr) } declare 101 generic { int Tk_GetJustify (Tcl_Interp *interp, \ - char *string, Tk_Justify *justifyPtr) + char *str, Tk_Justify *justifyPtr) } declare 102 generic { @@ -531,7 +527,7 @@ declare 103 generic { declare 104 generic { int Tk_GetPixels (Tcl_Interp *interp, \ - Tk_Window tkwin, char *string, int *intPtr) + Tk_Window tkwin, char *str, int *intPtr) } declare 105 generic { @@ -554,7 +550,7 @@ declare 108 generic { declare 109 generic { int Tk_GetScreenMM (Tcl_Interp *interp, \ - Tk_Window tkwin, char *string, double *doublePtr) + Tk_Window tkwin, char *str, double *doublePtr) } declare 110 generic { @@ -564,12 +560,12 @@ declare 110 generic { } declare 111 generic { - Tk_Uid Tk_GetUid (CONST char *string) + Tk_Uid Tk_GetUid (CONST char *str) } declare 112 generic { Visual * Tk_GetVisual (Tcl_Interp *interp, \ - Tk_Window tkwin, char *string, int *depthPtr, \ + Tk_Window tkwin, char *str, int *depthPtr, \ Colormap *colormapPtr) } @@ -632,7 +628,7 @@ declare 125 generic { declare 126 generic { int Tk_MeasureChars (Tk_Font tkfont, \ - CONST char *source, int maxChars, int maxPixels, \ + CONST char *source, int numBytes, int maxPixels, \ int flags, int *lengthPtr) } @@ -850,7 +846,7 @@ declare 175 generic { } declare 176 generic { - int Tk_TextWidth (Tk_Font font, CONST char *string, int numChars) + int Tk_TextWidth (Tk_Font font, CONST char *str, int numBytes) } declare 177 generic { @@ -860,8 +856,8 @@ declare 177 generic { declare 178 generic { void Tk_UnderlineChars (Display *display, \ Drawable drawable, GC gc, Tk_Font tkfont, \ - CONST char *source, int x, int y, int firstChar, \ - int lastChar) + CONST char *source, int x, int y, int firstByte, \ + int lastByte) } declare 179 generic { @@ -890,6 +886,152 @@ declare 184 generic { void Tk_UpdatePointer (Tk_Window tkwin, int x, int y, int state) } +# new functions for 8.1 + +declare 185 generic { + Pixmap Tk_AllocBitmapFromObj (Tcl_Interp *interp, Tk_Window tkwin, \ + Tcl_Obj *objPtr) +} + +declare 186 generic { + Tk_3DBorder Tk_Alloc3DBorderFromObj (Tcl_Interp *interp, Tk_Window tkwin, \ + Tcl_Obj *objPtr) +} + +declare 187 generic { + XColor * Tk_AllocColorFromObj (Tcl_Interp *interp, Tk_Window tkwin, \ + Tcl_Obj *objPtr) +} + +declare 188 generic { + Tk_Cursor Tk_AllocCursorFromObj (Tcl_Interp *interp, Tk_Window tkwin, \ + Tcl_Obj *objPtr) +} + +declare 189 generic { + Tk_Font Tk_AllocFontFromObj (Tcl_Interp *interp, Tk_Window tkwin, \ + Tcl_Obj *objPtr) + +} + +declare 190 generic { + Tk_OptionTable Tk_CreateOptionTable (Tcl_Interp *interp, \ + CONST Tk_OptionSpec *templatePtr) +} + +declare 191 generic { + void Tk_DeleteOptionTable (Tk_OptionTable optionTable) +} + +declare 192 generic { + void Tk_Free3DBorderFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 193 generic { + void Tk_FreeBitmapFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 194 generic { + void Tk_FreeColorFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 195 generic { + void Tk_FreeConfigOptions (char *recordPtr, Tk_OptionTable optionToken, \ + Tk_Window tkwin) + +} + +declare 196 generic { + void Tk_FreeSavedOptions (Tk_SavedOptions *savePtr) +} + +declare 197 generic { + void Tk_FreeCursorFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 198 generic { + void Tk_FreeFontFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 199 generic { + Tk_3DBorder Tk_Get3DBorderFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 200 generic { + int Tk_GetAnchorFromObj (Tcl_Interp *interp, Tcl_Obj *objPtr, \ + Tk_Anchor *anchorPtr) +} + +declare 201 generic { + Pixmap Tk_GetBitmapFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 202 generic { + XColor * Tk_GetColorFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 203 generic { + Tk_Cursor Tk_GetCursorFromObj (Tk_Window tkwin, Tcl_Obj *objPtr) +} + +declare 204 generic { + Tcl_Obj * Tk_GetOptionInfo (Tcl_Interp *interp, \ + char *recordPtr, Tk_OptionTable optionTable, \ + Tcl_Obj *namePtr, Tk_Window tkwin) +} + +declare 205 generic { + Tcl_Obj * Tk_GetOptionValue (Tcl_Interp *interp, char *recordPtr, \ + Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin) +} + +declare 206 generic { + int Tk_GetJustifyFromObj (Tcl_Interp *interp, \ + Tcl_Obj *objPtr, Tk_Justify *justifyPtr) +} + +declare 207 generic { + int Tk_GetMMFromObj (Tcl_Interp *interp, \ + Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr) +} + +declare 208 generic { + int Tk_GetPixelsFromObj (Tcl_Interp *interp, \ + Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr) +} + +declare 209 generic { + int Tk_GetReliefFromObj (Tcl_Interp *interp, \ + Tcl_Obj *objPtr, int *resultPtr) +} + +declare 210 generic { + int Tk_GetScrollInfoObj (Tcl_Interp *interp, \ + int objc, Tcl_Obj *CONST objv[], double *dblPtr, int *intPtr) +} + +declare 211 generic { + int Tk_InitOptions ( + Tcl_Interp *interp, char *recordPtr, \ + Tk_OptionTable optionToken, Tk_Window tkwin) +} + +declare 212 generic { + void Tk_MainEx (int argc, char **argv, Tcl_AppInitProc *appInitProc, \ + Tcl_Interp *interp) +} + +declare 213 generic { + void Tk_RestoreSavedOptions (Tk_SavedOptions *savePtr) +} + +declare 214 generic { + int Tk_SetOptions (Tcl_Interp *interp, char *recordPtr, \ + Tk_OptionTable optionTable, int objc, \ + Tcl_Obj *CONST objv[], Tk_Window tkwin, \ + Tk_SavedOptions *savePtr, int *maskPtr) +} + # Define the platform specific public Tk interface. These functions are # only available on the designated platform. diff --git a/generic/tk.h b/generic/tk.h index 69ca6a7..11c0433 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -6,13 +6,13 @@ * * Copyright (c) 1989-1994 The Regents of the University of California. * Copyright (c) 1994 The Australian National University. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. * Copyright (c) 1998-1999 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tk.h,v 1.20 1999/03/10 07:04:38 stanton Exp $ + * RCS: @(#) $Id: tk.h,v 1.21 1999/04/16 01:51:09 stanton Exp $ */ #ifndef _TK @@ -22,39 +22,26 @@ * When version numbers change here, you must also go into the following files * and update the version numbers: * - * README * unix/configure.in * win/makefile.bc * win/makefile.vc - * win/README - * mac/README - * library/tk.tcl (Not for patch release updates) - * - * The release level should be 0 for alpha, 1 for beta, and 2 for - * final/patch. The release serial value is the number that follows the - * "a", "b", or "p" in the patch level; for example, if the patch level - * is 4.3b2, TK_RELEASE_SERIAL is 2. It restarts at 1 whenever the - * release level is changed, except for the final release, which should - * be 0. - * + * README + * library/tk.tcl (only if major.minor changes, not patchlevel) + * mac/README (only if major.minor changes, not patchlevel) + * win/README (only if major.minor changes, not patchlevel) + * unix/README (only if major.minor changes, not patchlevel) + * You may also need to update some of these files when the numbers change * for the version of Tcl that this release of Tk is compiled against. */ #define TK_MAJOR_VERSION 8 -#define TK_MINOR_VERSION 0 -#define TK_RELEASE_LEVEL 2 -#define TK_RELEASE_SERIAL 5 +#define TK_MINOR_VERSION 1 +#define TK_RELEASE_LEVEL TCL_BETA_RELEASE +#define TK_RELEASE_SERIAL 3 -#define TK_VERSION "8.0" -#define TK_PATCH_LEVEL "8.0.5" - -/* - * A special definition used to allow this header file to be included - * in resource files. - */ - -#ifndef RESOURCE_INCLUDED +#define TK_VERSION "8.1" +#define TK_PATCH_LEVEL "8.1b3" /* * The following definitions set up the proper options for Macintosh @@ -70,6 +57,14 @@ #ifndef _TCL # include <tcl.h> #endif + +/* + * A special definition used to allow this header file to be included + * in resource files. + */ + +#ifndef RESOURCE_INCLUDED + #ifndef _XLIB_H # ifdef MAC_TCL # include <Xlib.h> @@ -82,15 +77,9 @@ # include <stddef.h> #endif -#undef TCL_STORAGE_CLASS #ifdef BUILD_tk +# undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT -#else -# ifdef USE_TK_STUBS -# define TCL_STORAGE_CLASS -# else -# define TCL_STORAGE_CLASS DLLIMPORT -# endif #endif /* @@ -112,6 +101,7 @@ typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler; typedef struct Tk_Font_ *Tk_Font; typedef struct Tk_Image__ *Tk_Image; typedef struct Tk_ImageMaster_ *Tk_ImageMaster; +typedef struct Tk_OptionTable_ *Tk_OptionTable; typedef struct Tk_TextLayout_ *Tk_TextLayout; typedef struct Tk_Window_ *Tk_Window; typedef struct Tk_3DBorder_ *Tk_3DBorder; @@ -123,54 +113,164 @@ typedef struct Tk_3DBorder_ *Tk_3DBorder; typedef char *Tk_Uid; /* - * Structure used to specify how to handle argv options. + * The enum below defines the valid types for Tk configuration options + * as implemented by Tk_InitOptions, Tk_SetOptions, etc. */ -typedef struct { - char *key; /* The key string that flags the option in the - * argv array. */ - int type; /* Indicates option type; see below. */ - char *src; /* Value to be used in setting dst; usage - * depends on type. */ - char *dst; /* Address of value to be modified; usage - * depends on type. */ - char *help; /* Documentation message describing this option. */ -} Tk_ArgvInfo; +typedef enum { + TK_OPTION_BOOLEAN, + TK_OPTION_INT, + TK_OPTION_DOUBLE, + TK_OPTION_STRING, + TK_OPTION_STRING_TABLE, + TK_OPTION_COLOR, + TK_OPTION_FONT, + TK_OPTION_BITMAP, + TK_OPTION_BORDER, + TK_OPTION_RELIEF, + TK_OPTION_CURSOR, + TK_OPTION_JUSTIFY, + TK_OPTION_ANCHOR, + TK_OPTION_SYNONYM, + TK_OPTION_PIXELS, + TK_OPTION_WINDOW, + TK_OPTION_END +} Tk_OptionType; /* - * Legal values for the type field of a Tk_ArgvInfo: see the user - * documentation for details. + * Structures of the following type are used by widgets to specify + * their configuration options. Typically each widget has a static + * array of these structures, where each element of the array describes + * a single configuration option. The array is passed to + * Tk_CreateOptionTable. */ -#define TK_ARGV_CONSTANT 15 -#define TK_ARGV_INT 16 -#define TK_ARGV_STRING 17 -#define TK_ARGV_UID 18 -#define TK_ARGV_REST 19 -#define TK_ARGV_FLOAT 20 -#define TK_ARGV_FUNC 21 -#define TK_ARGV_GENFUNC 22 -#define TK_ARGV_HELP 23 -#define TK_ARGV_CONST_OPTION 24 -#define TK_ARGV_OPTION_VALUE 25 -#define TK_ARGV_OPTION_NAME_VALUE 26 -#define TK_ARGV_END 27 +typedef struct Tk_OptionSpec { + Tk_OptionType type; /* Type of option, such as TK_OPTION_COLOR; + * see definitions above. Last option in + * table must have type TK_OPTION_END. */ + char *optionName; /* Name used to specify option in Tcl + * commands. */ + char *dbName; /* Name for option in option database. */ + char *dbClass; /* Class for option in database. */ + char *defValue; /* Default value for option if not specified + * in command line, the option database, + * or the system. */ + int objOffset; /* Where in record to store a Tcl_Obj * that + * holds the value of this option, specified + * as an offset in bytes from the start of + * the record. Use the Tk_Offset macro to + * generate values for this. -1 means don't + * store the Tcl_Obj in the record. */ + int internalOffset; /* Where in record to store the internal + * representation of the value of this option, + * such as an int or XColor *. This field + * is specified as an offset in bytes + * from the start of the record. Use the + * Tk_Offset macro to generate values for it. + * -1 means don't store the internal + * representation in the record. */ + int flags; /* Any combination of the values defined + * below. */ + ClientData clientData; /* An alternate place to put option-specific + * data. Used for the monochrome default value + * for colors, etc. */ + int typeMask; /* An arbitrary bit mask defined by the + * class manager; typically bits correspond + * to certain kinds of options such as all + * those that require a redisplay when they + * change. Tk_SetOptions returns the bit-wise + * OR of the typeMasks of all options that + * were changed. */ +} Tk_OptionSpec; /* - * Flag bits for passing to Tk_ParseArgv: + * Flag values for Tk_OptionSpec structures. These flags are shared by + * Tk_ConfigSpec structures, so be sure to coordinate any changes + * carefully. */ -#define TK_ARGV_NO_DEFAULTS 0x1 -#define TK_ARGV_NO_LEFTOVERS 0x2 -#define TK_ARGV_NO_ABBREV 0x4 -#define TK_ARGV_DONT_SKIP_FIRST_ARG 0x8 +#define TK_OPTION_NULL_OK 1 + +/* + * Macro to use to fill in "offset" fields of Tk_OptionSpecs. + * Computes number of bytes from beginning of structure to a + * given field. + */ + +#ifdef offsetof +#define Tk_Offset(type, field) ((int) offsetof(type, field)) +#else +#define Tk_Offset(type, field) ((int) ((char *) &((type *) 0)->field)) +#endif + +/* + * The following two structures are used for error handling. When + * configuration options are being modified, the old values are + * saved in a Tk_SavedOptions structure. If an error occurs, then the + * contents of the structure can be used to restore all of the old + * values. The contents of this structure are for the private use + * Tk. No-one outside Tk should ever read or write any of the fields + * of these structures. + */ + +typedef struct Tk_SavedOption { + struct TkOption *optionPtr; /* Points to information that describes + * the option. */ + Tcl_Obj *valuePtr; /* The old value of the option, in + * the form of a Tcl object; may be + * NULL if the value wasn't saved as + * an object. */ + double internalForm; /* The old value of the option, in + * some internal representation such + * as an int or (XColor *). Valid + * only if optionPtr->specPtr->objOffset + * is < 0. The space must be large + * enough to accommodate a double, a + * long, or a pointer; right now it + * looks like a double is big + * enough. Also, using a double + * guarantees that the field is + * properly aligned for storing large + * values. */ +} Tk_SavedOption; + +#ifdef TCL_MEM_DEBUG +# define TK_NUM_SAVED_OPTIONS 2 +#else +# define TK_NUM_SAVED_OPTIONS 20 +#endif + +typedef struct Tk_SavedOptions { + char *recordPtr; /* The data structure in which to + * restore configuration options. */ + Tk_Window tkwin; /* Window associated with recordPtr; + * needed to restore certain options. */ + int numItems; /* The number of valid items in + * items field. */ + Tk_SavedOption items[TK_NUM_SAVED_OPTIONS]; + /* Items used to hold old values. */ + struct Tk_SavedOptions *nextPtr; /* Points to next structure in list; + * needed if too many options changed + * to hold all the old values in a + * single structure. NULL means no + * more structures. */ +} Tk_SavedOptions; /* * Structure used to describe application-specific configuration * options: indicates procedures to call to parse an option and - * to return a text string describing an option. + * to return a text string describing an option. THESE ARE + * DEPRECATED; PLEASE USE THE NEW STRUCTURES LISTED ABOVE. + */ + +/* + * This is a temporary flag used while tkObjConfig and new widgets + * are in development. */ +#ifndef __NO_OLD_CONFIG + typedef int (Tk_OptionParseProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, char *value, char *widgRec, int offset)); @@ -224,40 +324,15 @@ typedef struct Tk_ConfigSpec { * documentation for details. */ -#define TK_CONFIG_BOOLEAN 1 -#define TK_CONFIG_INT 2 -#define TK_CONFIG_DOUBLE 3 -#define TK_CONFIG_STRING 4 -#define TK_CONFIG_UID 5 -#define TK_CONFIG_COLOR 6 -#define TK_CONFIG_FONT 7 -#define TK_CONFIG_BITMAP 8 -#define TK_CONFIG_BORDER 9 -#define TK_CONFIG_RELIEF 10 -#define TK_CONFIG_CURSOR 11 -#define TK_CONFIG_ACTIVE_CURSOR 12 -#define TK_CONFIG_JUSTIFY 13 -#define TK_CONFIG_ANCHOR 14 -#define TK_CONFIG_SYNONYM 15 -#define TK_CONFIG_CAP_STYLE 16 -#define TK_CONFIG_JOIN_STYLE 17 -#define TK_CONFIG_PIXELS 18 -#define TK_CONFIG_MM 19 -#define TK_CONFIG_WINDOW 20 -#define TK_CONFIG_CUSTOM 21 -#define TK_CONFIG_END 22 - -/* - * Macro to use to fill in "offset" fields of Tk_ConfigInfos. - * Computes number of bytes from beginning of structure to a - * given field. - */ - -#ifdef offsetof -#define Tk_Offset(type, field) ((int) offsetof(type, field)) -#else -#define Tk_Offset(type, field) ((int) ((char *) &((type *) 0)->field)) -#endif +typedef enum { + TK_CONFIG_BOOLEAN, TK_CONFIG_INT, TK_CONFIG_DOUBLE, TK_CONFIG_STRING, + TK_CONFIG_UID, TK_CONFIG_COLOR, TK_CONFIG_FONT, TK_CONFIG_BITMAP, + TK_CONFIG_BORDER, TK_CONFIG_RELIEF, TK_CONFIG_CURSOR, + TK_CONFIG_ACTIVE_CURSOR, TK_CONFIG_JUSTIFY, TK_CONFIG_ANCHOR, + TK_CONFIG_SYNONYM, TK_CONFIG_CAP_STYLE, TK_CONFIG_JOIN_STYLE, + TK_CONFIG_PIXELS, TK_CONFIG_MM, TK_CONFIG_WINDOW, TK_CONFIG_CUSTOM, + TK_CONFIG_END +} Tk_ConfigTypes; /* * Possible values for flags argument to Tk_ConfigureWidget: @@ -266,18 +341,62 @@ typedef struct Tk_ConfigSpec { #define TK_CONFIG_ARGV_ONLY 1 /* - * Possible flag values for Tk_ConfigInfo structures. Any bits at + * Possible flag values for Tk_ConfigSpec structures. Any bits at * or above TK_CONFIG_USER_BIT may be used by clients for selecting * certain entries. Before changing any values here, coordinate with - * tkConfig.c (internal-use-only flags are defined there). + * tkOldConfig.c (internal-use-only flags are defined there). */ -#define TK_CONFIG_COLOR_ONLY 1 -#define TK_CONFIG_MONO_ONLY 2 -#define TK_CONFIG_NULL_OK 4 +#define TK_CONFIG_NULL_OK 1 +#define TK_CONFIG_COLOR_ONLY 2 +#define TK_CONFIG_MONO_ONLY 4 #define TK_CONFIG_DONT_SET_DEFAULT 8 #define TK_CONFIG_OPTION_SPECIFIED 0x10 #define TK_CONFIG_USER_BIT 0x100 +#endif /* __NO_OLD_CONFIG */ + +/* + * Structure used to specify how to handle argv options. + */ + +typedef struct { + char *key; /* The key string that flags the option in the + * argv array. */ + int type; /* Indicates option type; see below. */ + char *src; /* Value to be used in setting dst; usage + * depends on type. */ + char *dst; /* Address of value to be modified; usage + * depends on type. */ + char *help; /* Documentation message describing this option. */ +} Tk_ArgvInfo; + +/* + * Legal values for the type field of a Tk_ArgvInfo: see the user + * documentation for details. + */ + +#define TK_ARGV_CONSTANT 15 +#define TK_ARGV_INT 16 +#define TK_ARGV_STRING 17 +#define TK_ARGV_UID 18 +#define TK_ARGV_REST 19 +#define TK_ARGV_FLOAT 20 +#define TK_ARGV_FUNC 21 +#define TK_ARGV_GENFUNC 22 +#define TK_ARGV_HELP 23 +#define TK_ARGV_CONST_OPTION 24 +#define TK_ARGV_OPTION_VALUE 25 +#define TK_ARGV_OPTION_NAME_VALUE 26 +#define TK_ARGV_END 27 + +/* + * Flag bits for passing to Tk_ParseArgv: + */ + +#define TK_ARGV_NO_DEFAULTS 0x1 +#define TK_ARGV_NO_LEFTOVERS 0x2 +#define TK_ARGV_NO_ABBREV 0x4 +#define TK_ARGV_DONT_SKIP_FIRST_ARG 0x8 /* * Enumerated type for describing actions to be taken in response @@ -302,12 +421,12 @@ typedef enum { * Relief values returned by Tk_GetRelief: */ -#define TK_RELIEF_RAISED 1 -#define TK_RELIEF_FLAT 2 -#define TK_RELIEF_SUNKEN 4 -#define TK_RELIEF_GROOVE 8 -#define TK_RELIEF_RIDGE 16 -#define TK_RELIEF_SOLID 32 +#define TK_RELIEF_FLAT 0 +#define TK_RELIEF_GROOVE 1 +#define TK_RELIEF_RAISED 2 +#define TK_RELIEF_RIDGE 3 +#define TK_RELIEF_SOLID 4 +#define TK_RELIEF_SUNKEN 5 /* * "Which" argument values for Tk_3DBorderGC: @@ -740,6 +859,8 @@ typedef void Tk_ItemInsertProc _ANSI_ARGS_((Tk_Canvas canvas, typedef void Tk_ItemDCharsProc _ANSI_ARGS_((Tk_Canvas canvas, Tk_Item *itemPtr, int first, int last)); +#ifndef __NO_OLD_CONFIG + typedef struct Tk_ItemType { char *name; /* The name of this type of item, such * as "line". */ @@ -793,6 +914,8 @@ typedef struct Tk_ItemType { char *reserved4; } Tk_ItemType; +#endif + /* * The following structure provides information about the selection and * the insertion cursor. It is needed by only a few items, such as @@ -811,16 +934,17 @@ typedef struct Tk_CanvasTextInfo { Tk_Item *selItemPtr; /* Pointer to selected item. NULL means * selection isn't in this canvas. * Writable by items. */ - int selectFirst; /* Index of first selected character. - * Writable by items. */ - int selectLast; /* Index of last selected character. - * Writable by items. */ + int selectFirst; /* Character index of first selected + * character. Writable by items. */ + int selectLast; /* Character index of last selected + * character. Writable by items. */ Tk_Item *anchorItemPtr; /* Item corresponding to "selectAnchor": * not necessarily selItemPtr. Read-only * to items. */ - int selectAnchor; /* Fixed end of selection (i.e. "select to" - * operation will use this as one end of the - * selection). Writable by items. */ + int selectAnchor; /* Character index of fixed end of + * selection (i.e. "select to" operation will + * use this as one end of the selection). + * Writable by items. */ Tk_3DBorder insertBorder; /* Used to draw vertical bar for insertion * cursor. Read-only to items. */ int insertWidth; /* Total width of insertion cursor. Read-only @@ -1023,11 +1147,27 @@ struct Tk_PhotoImageFormat { #define Tk_DoWhenIdle Tcl_DoWhenIdle #define Tk_Sleep Tcl_Sleep +/* Additional stuff that has moved to Tcl: */ + +#define Tk_AfterCmd Tcl_AfterCmd #define Tk_EventuallyFree Tcl_EventuallyFree #define Tk_FreeProc Tcl_FreeProc #define Tk_Preserve Tcl_Preserve #define Tk_Release Tcl_Release -#define Tk_FileeventCmd Tcl_FileEventCmd + +/* Removed Tk_Main, use macro instead */ +#define Tk_Main(argc, argv, proc) \ + Tk_MainEx(argc, argv, proc, Tcl_CreateInterp()) + +char *Tk_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, char *version, int exact)); + +#ifndef USE_TK_STUBS + +#define Tk_InitStubs(interp, version, exact) \ + Tcl_PkgRequire(interp, "Tk", version, exact) + +#endif + /* *-------------------------------------------------------------- @@ -1051,32 +1191,20 @@ typedef Tk_RestrictAction (Tk_RestrictProc) _ANSI_ARGS_(( typedef int (Tk_SelectionProc) _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); - /* - * Public functions that are not accessible via the stubs table. + *-------------------------------------------------------------- + * + * Exported procedures and variables. + * + *-------------------------------------------------------------- */ -EXTERN void Tk_Main _ANSI_ARGS_((int argc, char **argv, - Tcl_AppInitProc *appInitProc)); -EXTERN void Tk_MainEx _ANSI_ARGS_((int argc, char **argv, - Tcl_AppInitProc *appInitProc, Tcl_Interp *interp)); +#include "tkDecls.h" /* - * Stubs initialization function. This function should be invoked before - * any other Tk functions in a stubs-aware extension. Tk_InitStubs is - * implemented in the stub library, not the main Tk library. In directly - * linked code, this function turns into a call to Tcl_PkgRequire(). + * Tcl commands exported by Tk: */ -EXTERN char * Tk_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, - char *version, int exact)); - -#ifndef USE_TK_STUBS -#define Tk_InitStubs(interp, version, exact) \ - Tcl_PkgRequire(interp, "Tk", version, exact) -#endif - -#include "tkDecls.h" #endif /* RESOURCE_INCLUDED */ diff --git a/generic/tk3d.c b/generic/tk3d.c index ae049c9..cd5343a 100644 --- a/generic/tk3d.c +++ b/generic/tk3d.c @@ -10,36 +10,153 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tk3d.c,v 1.2 1998/09/14 18:23:02 stanton Exp $ + * RCS: @(#) $Id: tk3d.c,v 1.3 1999/04/16 01:51:10 stanton Exp $ */ -#include <tk3d.h> +#include "tk3d.h" /* - * Hash table to map from a border's values (color, etc.) to a - * Border structure for those values. + * The following table defines the string values for reliefs, which are + * used by Tk_GetReliefFromObj. */ -static Tcl_HashTable borderTable; -typedef struct { - Tk_Uid colorName; /* Color for border. */ - Colormap colormap; /* Colormap used for allocating border - * colors. */ - Screen *screen; /* Screen on which border will be drawn. */ -} BorderKey; - -static int initialized = 0; /* 0 means static structures haven't - * been initialized yet. */ +static char *reliefStrings[] = {"flat", "groove", "raised", "ridge", "solid", + "sunken", (char *) NULL}; /* * Forward declarations for procedures defined in this file: */ -static void BorderInit _ANSI_ARGS_((void)); +static void BorderInit _ANSI_ARGS_((TkDisplay *dispPtr)); +static void DupBorderObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, + Tcl_Obj *dupObjPtr)); +static void FreeBorderObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); static int Intersect _ANSI_ARGS_((XPoint *a1Ptr, XPoint *a2Ptr, XPoint *b1Ptr, XPoint *b2Ptr, XPoint *iPtr)); +static void InitBorderObj _ANSI_ARGS_((Tcl_Obj *objPtr)); static void ShiftLine _ANSI_ARGS_((XPoint *p1Ptr, XPoint *p2Ptr, int distance, XPoint *p3Ptr)); + +/* + * The following structure defines the implementation of the "border" Tcl + * object, used for drawing. The border object remembers the hash table entry + * associated with a border. The actual allocation and deallocation of the + * border should be done by the configuration package when the border option + * is set. + */ + +static Tcl_ObjType borderObjType = { + "border", /* name */ + FreeBorderObjProc, /* freeIntRepProc */ + DupBorderObjProc, /* dupIntRepProc */ + NULL, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +/* + *---------------------------------------------------------------------- + * + * Tk_Alloc3DBorderFromObj -- + * + * Given a Tcl_Obj *, map the value to a corresponding + * Tk_3DBorder structure based on the tkwin given. + * + * Results: + * The return value is a token for a data structure describing a + * 3-D border. This token may be passed to procedures such as + * Tk_Draw3DRectangle and Tk_Free3DBorder. If an error prevented + * the border from being created then NULL is returned and an error + * message will be left in the interp's result. + * + * Side effects: + * The border is added to an internal database with a reference + * count. For each call to this procedure, there should eventually + * be a call to Tk_FreeBorderFromObj so that the database is + * cleaned up when borders aren't in use anymore. + * + *---------------------------------------------------------------------- + */ + +Tk_3DBorder +Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr) + Tcl_Interp *interp; /* Interp for error results. */ + Tk_Window tkwin; /* Need the screen the border is used on.*/ + Tcl_Obj *objPtr; /* Object giving name of color for window + * background. */ +{ + TkBorder *borderPtr; + + if (objPtr->typePtr != &borderObjType) { + InitBorderObj(objPtr); + } + borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + + /* + * If the object currently points to a TkBorder, see if it's the + * one we want. If so, increment its reference count and return. + */ + + if (borderPtr != NULL) { + if (borderPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a border that's + * no longer in use. Clear the reference. + */ + + FreeBorderObjProc(objPtr); + borderPtr = NULL; + } else if ((Tk_Screen(tkwin) == borderPtr->screen) + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + borderPtr->resourceRefCount++; + return (Tk_3DBorder) borderPtr; + } + } + + /* + * The object didn't point to the border that we wanted. Search + * the list of borders with the same name to see if one of the + * others is the right one. + */ + + /* + * If the cached value is NULL, either the object type was not a + * color going in, or the object is a color type but had + * previously been freed. + * + * If the value is not NULL, the internal rep is the value + * of the color the last time this object was accessed. Check + * the screen and colormap of the last access, and if they + * match, we are done. + */ + + if (borderPtr != NULL) { + TkBorder *firstBorderPtr = + (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); + FreeBorderObjProc(objPtr); + for (borderPtr = firstBorderPtr ; borderPtr != NULL; + borderPtr = borderPtr->nextPtr) { + if ((Tk_Screen(tkwin) == borderPtr->screen) + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + borderPtr->resourceRefCount++; + borderPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr; + return (Tk_3DBorder) borderPtr; + } + } + } + + /* + * Still no luck. Call Tk_Get3DBorder to allocate a new border. + */ + + borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin, + Tcl_GetString(objPtr)); + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr; + if (borderPtr != NULL) { + borderPtr->objRefCount++; + } + return (Tk_3DBorder) borderPtr; +} /* *-------------------------------------------------------------- @@ -49,12 +166,11 @@ static void ShiftLine _ANSI_ARGS_((XPoint *p1Ptr, XPoint *p2Ptr, * Create a data structure for displaying a 3-D border. * * Results: - * The return value is a token for a data structure - * describing a 3-D border. This token may be passed - * to Tk_Draw3DRectangle and Tk_Free3DBorder. If an - * error prevented the border from being created then - * NULL is returned and an error message will be left - * in interp->result. + * The return value is a token for a data structure describing a + * 3-D border. This token may be passed to procedures such as + * Tk_Draw3DRectangle and Tk_Free3DBorder. If an error prevented + * the border from being created then NULL is returned and an error + * message will be left in the interp's result. * * Side effects: * Data structures, graphics contexts, etc. are allocated. @@ -69,70 +185,75 @@ Tk_Get3DBorder(interp, tkwin, colorName) Tcl_Interp *interp; /* Place to store an error message. */ Tk_Window tkwin; /* Token for window in which border will * be drawn. */ - Tk_Uid colorName; /* String giving name of color + char *colorName; /* String giving name of color * for window background. */ { - BorderKey key; Tcl_HashEntry *hashPtr; - register TkBorder *borderPtr; + TkBorder *borderPtr, *existingBorderPtr; int new; XGCValues gcValues; + XColor *bgColorPtr; + TkDisplay *dispPtr; - if (!initialized) { - BorderInit(); - } - - /* - * First, check to see if there's already a border that will work - * for this request. - */ + dispPtr = ((TkWindow *) tkwin)->dispPtr; - key.colorName = colorName; - key.colormap = Tk_Colormap(tkwin); - key.screen = Tk_Screen(tkwin); + if (!dispPtr->borderInit) { + BorderInit(dispPtr); + } - hashPtr = Tcl_CreateHashEntry(&borderTable, (char *) &key, &new); + hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &new); if (!new) { - borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); - borderPtr->refCount++; + existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); + for (borderPtr = existingBorderPtr; borderPtr != NULL; + borderPtr = borderPtr->nextPtr) { + if ((Tk_Screen(tkwin) == borderPtr->screen) + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + borderPtr->resourceRefCount++; + return (Tk_3DBorder) borderPtr; + } + } } else { - XColor *bgColorPtr; + existingBorderPtr = NULL; + } - /* - * No satisfactory border exists yet. Initialize a new one. - */ - - bgColorPtr = Tk_GetColor(interp, tkwin, colorName); - if (bgColorPtr == NULL) { + /* + * No satisfactory border exists yet. Initialize a new one. + */ + + bgColorPtr = Tk_GetColor(interp, tkwin, colorName); + if (bgColorPtr == NULL) { + if (new) { Tcl_DeleteHashEntry(hashPtr); - return NULL; } - - borderPtr = TkpGetBorder(); - borderPtr->screen = Tk_Screen(tkwin); - borderPtr->visual = Tk_Visual(tkwin); - borderPtr->depth = Tk_Depth(tkwin); - borderPtr->colormap = key.colormap; - borderPtr->refCount = 1; - borderPtr->bgColorPtr = bgColorPtr; - borderPtr->darkColorPtr = NULL; - borderPtr->lightColorPtr = NULL; - borderPtr->shadow = None; - borderPtr->bgGC = None; - borderPtr->darkGC = None; - borderPtr->lightGC = None; - borderPtr->hashPtr = hashPtr; - Tcl_SetHashValue(hashPtr, borderPtr); - - /* - * Create the information for displaying the background color, - * but delay the allocation of shadows until they are actually - * needed for drawing. - */ - - gcValues.foreground = borderPtr->bgColorPtr->pixel; - borderPtr->bgGC = Tk_GetGC(tkwin, GCForeground, &gcValues); + return NULL; } + + borderPtr = TkpGetBorder(); + borderPtr->screen = Tk_Screen(tkwin); + borderPtr->visual = Tk_Visual(tkwin); + borderPtr->depth = Tk_Depth(tkwin); + borderPtr->colormap = Tk_Colormap(tkwin); + borderPtr->resourceRefCount = 1; + borderPtr->objRefCount = 0; + borderPtr->bgColorPtr = bgColorPtr; + borderPtr->darkColorPtr = NULL; + borderPtr->lightColorPtr = NULL; + borderPtr->shadow = None; + borderPtr->bgGC = None; + borderPtr->darkGC = None; + borderPtr->lightGC = None; + borderPtr->hashPtr = hashPtr; + borderPtr->nextPtr = existingBorderPtr; + Tcl_SetHashValue(hashPtr, borderPtr); + + /* + * Create the information for displaying the background color, + * but delay the allocation of shadows until they are actually + * needed for drawing. + */ + + gcValues.foreground = borderPtr->bgColorPtr->pixel; + borderPtr->bgGC = Tk_GetGC(tkwin, GCForeground, &gcValues); return (Tk_3DBorder) borderPtr; } @@ -208,7 +329,7 @@ Tk_NameOf3DBorder(border) { TkBorder *borderPtr = (TkBorder *) border; - return ((BorderKey *) borderPtr->hashPtr->key.words)->colorName; + return borderPtr->hashPtr->key.string; } /* @@ -303,34 +424,51 @@ void Tk_Free3DBorder(border) Tk_3DBorder border; /* Token for border to be released. */ { - register TkBorder *borderPtr = (TkBorder *) border; + TkBorder *borderPtr = (TkBorder *) border; Display *display = DisplayOfScreen(borderPtr->screen); + TkBorder *prevPtr; - borderPtr->refCount--; - if (borderPtr->refCount == 0) { - TkpFreeBorder(borderPtr); - if (borderPtr->bgColorPtr != NULL) { - Tk_FreeColor(borderPtr->bgColorPtr); - } - if (borderPtr->darkColorPtr != NULL) { - Tk_FreeColor(borderPtr->darkColorPtr); - } - if (borderPtr->lightColorPtr != NULL) { - Tk_FreeColor(borderPtr->lightColorPtr); - } - if (borderPtr->shadow != None) { - Tk_FreeBitmap(display, borderPtr->shadow); - } - if (borderPtr->bgGC != None) { - Tk_FreeGC(display, borderPtr->bgGC); - } - if (borderPtr->darkGC != None) { - Tk_FreeGC(display, borderPtr->darkGC); + borderPtr->resourceRefCount--; + if (borderPtr->resourceRefCount > 0) { + return; + } + + prevPtr = (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); + TkpFreeBorder(borderPtr); + if (borderPtr->bgColorPtr != NULL) { + Tk_FreeColor(borderPtr->bgColorPtr); + } + if (borderPtr->darkColorPtr != NULL) { + Tk_FreeColor(borderPtr->darkColorPtr); + } + if (borderPtr->lightColorPtr != NULL) { + Tk_FreeColor(borderPtr->lightColorPtr); + } + if (borderPtr->shadow != None) { + Tk_FreeBitmap(display, borderPtr->shadow); + } + if (borderPtr->bgGC != None) { + Tk_FreeGC(display, borderPtr->bgGC); + } + if (borderPtr->darkGC != None) { + Tk_FreeGC(display, borderPtr->darkGC); + } + if (borderPtr->lightGC != None) { + Tk_FreeGC(display, borderPtr->lightGC); + } + if (prevPtr == borderPtr) { + if (borderPtr->nextPtr == NULL) { + Tcl_DeleteHashEntry(borderPtr->hashPtr); + } else { + Tcl_SetHashValue(borderPtr->hashPtr, borderPtr->nextPtr); } - if (borderPtr->lightGC != None) { - Tk_FreeGC(display, borderPtr->lightGC); + } else { + while (prevPtr->nextPtr != borderPtr) { + prevPtr = prevPtr->nextPtr; } - Tcl_DeleteHashEntry(borderPtr->hashPtr); + prevPtr->nextPtr = borderPtr->nextPtr; + } + if (borderPtr->objRefCount == 0) { ckfree((char *) borderPtr); } } @@ -338,6 +476,105 @@ Tk_Free3DBorder(border) /* *---------------------------------------------------------------------- * + * Tk_Free3DBorderFromObj -- + * + * This procedure is called to release a border allocated by + * Tk_Alloc3DBorderFromObj. It does not throw away the Tcl_Obj *; + * it only gets rid of the hash table entry for this border + * and clears the cached value that is normally stored in the object. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with the border represented by + * objPtr is decremented, and the border's resources are released + * to X if there are no remaining uses for it. + * + *---------------------------------------------------------------------- + */ + +void +Tk_Free3DBorderFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window this border lives in. Needed + * for the screen and colormap values. */ + Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ +{ + Tk_Free3DBorder(Tk_Get3DBorderFromObj(tkwin, objPtr)); +} + +/* + *--------------------------------------------------------------------------- + * + * FreeBorderObjProc -- + * + * This proc is called to release an object reference to a border. + * Called when the object's internal rep is released or when + * the cached borderPtr needs to be changed. + * + * Results: + * None. + * + * Side effects: + * The object reference count is decremented. When both it + * and the hash ref count go to zero, the border's resources + * are released. + * + *--------------------------------------------------------------------------- + */ + +static void +FreeBorderObjProc(objPtr) + Tcl_Obj *objPtr; /* The object we are releasing. */ +{ + TkBorder *borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + + if (borderPtr != NULL) { + borderPtr->objRefCount--; + if ((borderPtr->objRefCount == 0) + && (borderPtr->resourceRefCount == 0)) { + ckfree((char *) borderPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; + } +} + +/* + *--------------------------------------------------------------------------- + * + * DupBorderObjProc -- + * + * When a cached border object is duplicated, this is called to + * update the internal reps. + * + * Results: + * None. + * + * Side effects: + * The border's objRefCount is incremented and the internal rep + * of the copy is set to point to it. + * + *--------------------------------------------------------------------------- + */ + +static void +DupBorderObjProc(srcObjPtr, dupObjPtr) + Tcl_Obj *srcObjPtr; /* The object we are copying from. */ + Tcl_Obj *dupObjPtr; /* The object we are copying to. */ +{ + TkBorder *borderPtr = (TkBorder *) srcObjPtr->internalRep.twoPtrValue.ptr1; + + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr; + + if (borderPtr != NULL) { + borderPtr->objRefCount++; + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_SetBackgroundFromBorder -- * * Change the background of a window to one appropriate for a given @@ -365,6 +602,35 @@ Tk_SetBackgroundFromBorder(tkwin, border) /* *---------------------------------------------------------------------- * + * Tk_GetReliefFromObj -- + * + * Return an integer value based on the value of the objPtr. + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * The object gets converted by Tcl_GetIndexFromObj. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetReliefFromObj(interp, objPtr, resultPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *objPtr; /* The object we are trying to get the + * value from. */ + int *resultPtr; /* Where to place the answer. */ +{ + return Tcl_GetIndexFromObj(interp, objPtr, reliefStrings, "relief", 0, + resultPtr); +} + +/* + *---------------------------------------------------------------------- + * * Tk_GetRelief -- * * Parse a relief description and return the corresponding @@ -407,8 +673,11 @@ Tk_GetRelief(interp, name, reliefPtr) } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)) { *reliefPtr = TK_RELIEF_SUNKEN; } else { - sprintf(interp->result, "bad relief type \"%.50s\": must be %s", + char buf[200]; + + sprintf(buf, "bad relief type \"%.50s\": must be %s", name, "flat, groove, raised, ridge, solid, or sunken"); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -782,10 +1051,11 @@ Tk_Fill3DPolygon(tkwin, drawable, border, pointPtr, numPoints, */ static void -BorderInit() +BorderInit(dispPtr) + TkDisplay * dispPtr; /* Used to access thread-specific data. */ { - initialized = 1; - Tcl_InitHashTable(&borderTable, sizeof(BorderKey)/sizeof(int)); + dispPtr->borderInit = 1; + Tcl_InitHashTable(&dispPtr->borderTable, TCL_STRING_KEYS); } /* @@ -947,3 +1217,170 @@ Intersect(a1Ptr, a2Ptr, b1Ptr, b2Ptr, iPtr) } return 0; } + +/* + *---------------------------------------------------------------------- + * + * Tk_Get3DBorderFromObj -- + * + * Returns the border referred to by a Tcl object. The border must + * already have been allocated via a call to Tk_Alloc3DBorderFromObj + * or Tk_Get3DBorder. + * + * Results: + * Returns the Tk_3DBorder that matches the tkwin and the string rep + * of the name of the border given in objPtr. + * + * Side effects: + * If the object is not already a border, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +Tk_3DBorder +Tk_Get3DBorderFromObj(tkwin, objPtr) + Tk_Window tkwin; + Tcl_Obj *objPtr; /* The object whose string value selects + * a border. */ +{ + TkBorder *borderPtr = NULL; + Tcl_HashEntry *hashPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + if (objPtr->typePtr != &borderObjType) { + InitBorderObj(objPtr); + } + + borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; + if (borderPtr != NULL) { + if ((borderPtr->resourceRefCount > 0) + && (Tk_Screen(tkwin) == borderPtr->screen) + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + /* + * The object already points to the right border structure. + * Just return it. + */ + + return (Tk_3DBorder) borderPtr; + } + hashPtr = borderPtr->hashPtr; + FreeBorderObjProc(objPtr); + } else { + hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, + Tcl_GetString(objPtr)); + if (hashPtr == NULL) { + goto error; + } + } + + /* + * At this point we've got a hash table entry, off of which hang + * one or more TkBorder structures. See if any of them will work. + */ + + for (borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); + (borderPtr != NULL); borderPtr = borderPtr->nextPtr) { + if ((Tk_Screen(tkwin) == borderPtr->screen) + && (Tk_Colormap(tkwin) == borderPtr->colormap)) { + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) borderPtr; + borderPtr->objRefCount++; + return (Tk_3DBorder) borderPtr; + } + } + + error: + panic("Tk_Get3DBorderFromObj called with non-existent border!"); + /* + * The following code isn't reached; it's just there to please compilers. + */ + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * InitBorderObj -- + * + * Attempt to generate a border internal form for the Tcl object + * "objPtr". + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * If no error occurs, a blank internal format for a border value + * is intialized. The final form cannot be done without a Tk_Window. + * + *---------------------------------------------------------------------- + */ + +static void +InitBorderObj(objPtr) + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetString(objPtr); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &borderObjType; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TkDebugBorder -- + * + * This procedure returns debugging information about a border. + * + * Results: + * The return value is a list with one sublist for each TkBorder + * corresponding to "name". Each sublist has two elements that + * contain the resourceRefCount and objRefCount fields from the + * TkBorder structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkDebugBorder(tkwin, name) + Tk_Window tkwin; /* The window in which the border will be + * used (not currently used). */ + char *name; /* Name of the desired color. */ +{ + TkBorder *borderPtr; + Tcl_HashEntry *hashPtr; + Tcl_Obj *resultPtr, *objPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + resultPtr = Tcl_NewObj(); + hashPtr = Tcl_FindHashEntry(&dispPtr->borderTable, name); + if (hashPtr != NULL) { + borderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); + if (borderPtr == NULL) { + panic("TkDebugBorder found empty hash table entry"); + } + for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) { + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(borderPtr->resourceRefCount)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(borderPtr->objRefCount)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return resultPtr; +} diff --git a/generic/tk3d.h b/generic/tk3d.h index 1ec63d0..03ce97e 100644 --- a/generic/tk3d.h +++ b/generic/tk3d.h @@ -4,12 +4,12 @@ * Declarations of types and functions shared by the 3d border * module. * - * Copyright (c) 1996 by Sun Microsystems, Inc. + * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tk3d.h,v 1.4 1998/09/14 18:23:03 stanton Exp $ + * RCS: @(#) $Id: tk3d.h,v 1.5 1999/04/16 01:51:10 stanton Exp $ */ #ifndef _TK3D @@ -23,13 +23,13 @@ #endif /* - * One of the following data structures is allocated for - * each 3-D border currently in use. Structures of this - * type are indexed by borderTable, so that a single - * structure can be shared for several uses. + * One of the following data structures is allocated for each 3-D border + * currently in use. Structures of this type are indexed by + * borderTable, so that a single structure can be shared for several + * uses. */ -typedef struct { +typedef struct TkBorder { Screen *screen; /* Screen on which the border will be used. */ Visual *visual; /* Visual for all windows and pixmaps using * the border. */ @@ -37,8 +37,18 @@ typedef struct { * the border will be used. */ Colormap colormap; /* Colormap out of which pixels are * allocated. */ - int refCount; /* Number of different users of - * this border. */ + int resourceRefCount; /* Number of active uses of this color (each + * active use corresponds to a call to + * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder). + * If this count is 0, then this structure + * is no longer valid and it isn't present + * in borderTable: it is being kept around + * only because there are objects referring + * to it. The structure is freed when + * resourceRefCount and objRefCount are + * both 0. */ + int objRefCount; /* The number of Tcl objects that reference + * this structure. */ XColor *bgColorPtr; /* Background color (intensity * between lightColorPtr and * darkColorPtr). */ @@ -63,6 +73,11 @@ typedef struct { * haven't been allocated yet. */ Tcl_HashEntry *hashPtr; /* Entry in borderTable (needed in * order to delete structure). */ + struct TkBorder *nextPtr; /* Points to the next TkBorder structure with + * the same color name. Borders with the + * same name but different screens or + * colormaps are chained together off a + * single entry in borderTable. */ } TkBorder; diff --git a/generic/tkArgv.c b/generic/tkArgv.c index 8d5d661..7f35368 100644 --- a/generic/tkArgv.c +++ b/generic/tkArgv.c @@ -5,12 +5,12 @@ * argv-argc parsing. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkArgv.c,v 1.2 1998/09/14 18:23:03 stanton Exp $ + * RCS: @(#) $Id: tkArgv.c,v 1.3 1999/04/16 01:51:10 stanton Exp $ */ #include "tkPort.h" @@ -45,7 +45,7 @@ static void PrintUsage _ANSI_ARGS_((Tcl_Interp *interp, * * Results: * The return value is a standard Tcl return value. If an - * error occurs then an error message is left in interp->result. + * error occurs then an error message is left in the interp's result. * Under normal conditions, both *argcPtr and *argv are modified * to return the arguments that couldn't be processed here (they * didn't match the option table, or followed an TK_ARGV_REST @@ -291,10 +291,14 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) srcIndex += 2; argc -= 2; break; - default: - sprintf(interp->result, "bad argument type %d in Tk_ArgvInfo", + default: { + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "bad argument type %d in Tk_ArgvInfo", infoPtr->type); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; + } } } @@ -328,7 +332,7 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) * Generate a help string describing command-line options. * * Results: - * Interp->result will be modified to hold a help string + * The interp's result will be modified to hold a help string * describing all the options in argTable, plus all those * in the default table unless TK_ARGV_NO_DEFAULTS is * specified in flags. @@ -353,7 +357,7 @@ PrintUsage(interp, argTable, flags) int width, i, numSpaces; #define NUM_SPACES 20 static char spaces[] = " "; - char tmp[30]; + char tmp[TCL_DOUBLE_SPACE]; /* * First, compute the width of the widest option key, so that we diff --git a/generic/tkBind.c b/generic/tkBind.c index 72bcd2e..e0daec8 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -5,13 +5,13 @@ * with X events or sequences of X events. * * Copyright (c) 1989-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkBind.c,v 1.5 1999/03/10 07:04:38 stanton Exp $ + * RCS: @(#) $Id: tkBind.c,v 1.6 1999/04/16 01:51:10 stanton Exp $ */ #include "tkPort.h" @@ -344,6 +344,8 @@ typedef struct BindInfo { PendingBinding *pendingList;/* The list of pending C bindings, kept in * case a C or Tcl binding causes the target * window to be deleted. */ + int deleted; /* 1 the application has been deleted but + * the structure has been preserved. */ } BindInfo; /* @@ -378,6 +380,7 @@ static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */ */ static int initialized = 0; +TCL_DECLARE_MUTEX(bindMutex) /* * A hash table is kept to map from the string names of event @@ -578,6 +581,20 @@ static int flagArray[TK_LASTEVENT] = { }; /* + * The following table is used to map between the location where an + * generated event should be queued and the string used to specify the + * location. + */ + +static TkStateMap queuePosition[] = { + {-1, "now"}, + {TCL_QUEUE_HEAD, "head"}, + {TCL_QUEUE_MARK, "mark"}, + {TCL_QUEUE_TAIL, "tail"}, + {-2, NULL} +}; + +/* * The following tables are used as a two-way map between X's internal * numeric values for fields in an XEvent and the strings used in Tcl. The * tables are used both when constructing an XEvent from user input and @@ -651,7 +668,8 @@ static int GetVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, static Tk_Uid GetVirtualEventUid _ANSI_ARGS_((Tcl_Interp *interp, char *virtString)); static int HandleEventGenerate _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window main, int argc, char **argv)); + Tk_Window main, int objc, + Tcl_Obj *CONST objv[])); static void InitKeymapInfo _ANSI_ARGS_((TkDisplay *dispPtr)); static void InitVirtualEventTable _ANSI_ARGS_(( VirtualEventTable *vetPtr)); @@ -659,9 +677,14 @@ static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr, BindingTable *bindPtr, PatSeq *psPtr, PatSeq *bestPtr, ClientData *objectPtr, PatSeq **sourcePtrPtr)); +static int NameToWindow _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window main, Tcl_Obj *objPtr, + Tk_Window *tkwinPtr)); static int ParseEventDescription _ANSI_ARGS_((Tcl_Interp *interp, char **eventStringPtr, Pattern *patPtr, unsigned long *eventMaskPtr)); +static void SetKeycodeAndState _ANSI_ARGS_((Tk_Window tkwin, + KeySym keySym, XEvent *eventPtr)); /* * The following define is used as a short circuit for the callback @@ -709,37 +732,41 @@ TkBindInit(mainPtr) */ if (!initialized) { - Tcl_HashEntry *hPtr; - ModInfo *modPtr; - EventInfo *eiPtr; - int dummy; + Tcl_MutexLock(&bindMutex); + if (!initialized) { + Tcl_HashEntry *hPtr; + ModInfo *modPtr; + EventInfo *eiPtr; + int dummy; #ifdef REDO_KEYSYM_LOOKUP - KeySymInfo *kPtr; - - Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); - Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); - for (kPtr = keyArray; kPtr->name != NULL; kPtr++) { - hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); - Tcl_SetHashValue(hPtr, kPtr->value); - hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, - &dummy); - Tcl_SetHashValue(hPtr, kPtr->name); - } + KeySymInfo *kPtr; + + Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); + for (kPtr = keyArray; kPtr->name != NULL; kPtr++) { + hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); + Tcl_SetHashValue(hPtr, kPtr->value); + hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, + &dummy); + Tcl_SetHashValue(hPtr, kPtr->name); + } #endif /* REDO_KEYSYM_LOOKUP */ - Tcl_InitHashTable(&modTable, TCL_STRING_KEYS); - for (modPtr = modArray; modPtr->name != NULL; modPtr++) { - hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &dummy); - Tcl_SetHashValue(hPtr, modPtr); - } + Tcl_InitHashTable(&modTable, TCL_STRING_KEYS); + for (modPtr = modArray; modPtr->name != NULL; modPtr++) { + hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &dummy); + Tcl_SetHashValue(hPtr, modPtr); + } - Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS); - for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { - hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); - Tcl_SetHashValue(hPtr, eiPtr); + Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS); + for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { + hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); + Tcl_SetHashValue(hPtr, eiPtr); + } + initialized = 1; } - initialized = 1; + Tcl_MutexUnlock(&bindMutex); } mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp); @@ -750,6 +777,7 @@ TkBindInit(mainPtr) bindInfoPtr->screenInfo.curScreenIndex = -1; bindInfoPtr->screenInfo.bindingDepth = 0; bindInfoPtr->pendingList = NULL; + bindInfoPtr->deleted = 0; mainPtr->bindInfo = (TkBindInfo) bindInfoPtr; TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable); @@ -783,6 +811,8 @@ TkBindFree(mainPtr) bindInfoPtr = (BindInfo *) mainPtr->bindInfo; DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable); + bindInfoPtr->deleted = 1; + Tcl_EventuallyFree((ClientData) bindInfoPtr, Tcl_Free); mainPtr->bindInfo = NULL; } @@ -897,7 +927,7 @@ Tk_DeleteBindingTable(bindingTable) * Results: * The return value is 0 if an error occurred while setting * up the binding. In this case, an error message will be - * left in interp->result. If all went well then the return + * left in the interp's result. If all went well then the return * value is a mask of the event types that must be made * available to Tk_BindEvent in order to properly detect when * this binding triggers. This value can be used to determine @@ -1002,7 +1032,7 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) * Results: * The return value is 0 if an error occurred while setting * up the binding. In this case, an error message will be - * left in interp->result. If all went well then the return + * left in the interp's result. If all went well then the return * value is a mask of the event types that must be made * available to Tk_BindEvent in order to properly detect when * this binding triggers. This value can be used to determine @@ -1086,7 +1116,7 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, * * Results: * The result is a standard Tcl return value. If an error - * occurs then interp->result will contain an error message. + * occurs then the interp's result will contain an error message. * * Side effects: * The binding given by object and eventString is removed @@ -1181,7 +1211,7 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) * given by bindingTable. If there is no binding for * eventString, or if eventString is improperly formed, * then NULL is returned and an error message is left in - * interp->result. The return value is semi-static: it + * the interp's result. The return value is semi-static: it * will persist until the binding is changed or deleted. * * Side effects: @@ -1224,7 +1254,7 @@ Tk_GetBinding(interp, bindingTable, object, eventString) * associated with a given object. * * Results: - * There is no return value. Interp->result is modified to + * There is no return value. The interp's result is modified to * hold a Tcl list with one entry for each binding associated * with object in bindingTable. Each entry in the list * contains the event string associated with one binding. @@ -1388,9 +1418,9 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) { BindingTable *bindPtr; TkDisplay *dispPtr; + ScreenInfo *screenPtr; BindInfo *bindInfoPtr; TkDisplay *oldDispPtr; - ScreenInfo *screenPtr; XEvent *ringPtr; PatSeq *vMatchDetailList, *vMatchNoDetailList; int flags, oldScreen, i, deferModal; @@ -1621,12 +1651,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) unsigned int oldSize, newSize; oldSize = sizeof(staticPending) - - sizeof(staticPending.matchArray) - + matchSpace * sizeof(PatSeq*); + - sizeof(staticPending.matchArray) + + matchSpace * sizeof(PatSeq*); matchSpace *= 2; newSize = sizeof(staticPending) - - sizeof(staticPending.matchArray) - + matchSpace * sizeof(PatSeq*); + - sizeof(staticPending.matchArray) + + matchSpace * sizeof(PatSeq*); new = (PendingBinding *) ckalloc(newSize); memcpy((VOID *) new, (VOID *) pendingPtr, oldSize); if (pendingPtr != &staticPending) { @@ -1657,7 +1687,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) * * There are two tricks here: * 1. Bindings can be invoked from in the middle of Tcl commands, - * where interp->result is significant (for example, a widget + * where the interp's result is significant (for example, a widget * might be deleted because of an error in creating it, so the * result contains an error message that is eventually going to * be returned by the creating command). To preserve the result, @@ -1688,6 +1718,13 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } if (matchCount > 0) { + /* + * Remember the list of pending C binding callbacks, so we can mark + * them as deleted and not call them if the act of evaluating a C + * or Tcl binding deletes a C binding callback or even the whole + * window. + */ + pendingPtr->nextPtr = bindInfoPtr->pendingList; pendingPtr->tkwin = tkwin; pendingPtr->deleted = 0; @@ -1707,10 +1744,20 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) end = p + Tcl_DStringLength(&scripts); i = 0; + /* + * Be carefule when dereferencing screenPtr or bindInfoPtr. If we + * evaluate something that destroys ".", bindInfoPtr would have been + * freed, but we can tell that by first checking to see if + * winPtr->mainPtr == NULL. + */ + + Tcl_Preserve((ClientData) bindInfoPtr); while (p < end) { int code; - screenPtr->bindingDepth++; + if (!bindInfoPtr->deleted) { + screenPtr->bindingDepth++; + } Tcl_AllowExceptions(interp); if (*p == '\0') { @@ -1736,7 +1783,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) p += strlen(p); } p++; - screenPtr->bindingDepth--; + + if (!bindInfoPtr->deleted) { + screenPtr->bindingDepth--; + } if (code != TCL_OK) { if (code == TCL_CONTINUE) { /* @@ -1766,8 +1816,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } } - if ((screenPtr->bindingDepth != 0) && - ((oldDispPtr != screenPtr->curDispPtr) + if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0) + && ((oldDispPtr != screenPtr->curDispPtr) || (oldScreen != screenPtr->curScreenIndex))) { /* @@ -1784,19 +1834,27 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) Tcl_DStringFree(&scripts); if (matchCount > 0) { - PendingBinding **curPtrPtr; + if (!bindInfoPtr->deleted) { + /* + * Delete the pending list from the list of pending scripts + * for this window. + */ + + PendingBinding **curPtrPtr; - for (curPtrPtr = &bindInfoPtr->pendingList; ; ) { - if (*curPtrPtr == pendingPtr) { - *curPtrPtr = pendingPtr->nextPtr; - break; + for (curPtrPtr = &bindInfoPtr->pendingList; ; ) { + if (*curPtrPtr == pendingPtr) { + *curPtrPtr = pendingPtr->nextPtr; + break; + } + curPtrPtr = &(*curPtrPtr)->nextPtr; } - curPtrPtr = &(*curPtrPtr)->nextPtr; } if (pendingPtr != &staticPending) { ckfree((char *) pendingPtr); } } + Tcl_Release((ClientData) bindInfoPtr); } /* @@ -2171,7 +2229,8 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) bestPtr = matchPtr; bestSourcePtr = sourcePtr; - nextSequence: continue; + nextSequence: + continue; } *sourcePtrPtr = bestSourcePtr; @@ -2215,8 +2274,11 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) int number, flags, length; #define NUM_SIZE 40 char *string; + Tcl_DString buf; char numStorage[NUM_SIZE+1]; + Tcl_DStringInit(&buf); + if (eventPtr->type < TK_LASTEVENT) { flags = flagArray[eventPtr->type]; } else { @@ -2250,8 +2312,10 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) number = eventPtr->xany.serial; goto doNumber; case 'a': - TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); - string = numStorage; + if (flags & CONFIG) { + TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); + string = numStorage; + } goto doString; case 'b': number = eventPtr->xbutton.button; @@ -2365,37 +2429,8 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) goto doNumber; case 'A': if (flags & KEY) { - int numChars; - - /* - * If we're using input methods and this is a keypress - * event, invoke XmbTkFindStateString. Otherwise just use - * the older XTkFindStateString. - */ - -#ifdef TK_USE_INPUT_METHODS - Status status; - if ((winPtr->inputContext != NULL) - && (eventPtr->type == KeyPress)) { - numChars = XmbLookupString(winPtr->inputContext, - &eventPtr->xkey, numStorage, NUM_SIZE, - (KeySym *) NULL, &status); - if ((status != XLookupChars) - && (status != XLookupBoth)) { - numChars = 0; - } - } else { - numChars = XLookupString(&eventPtr->xkey, numStorage, - NUM_SIZE, (KeySym *) NULL, - (XComposeStatus *) NULL); - } -#else /* TK_USE_INPUT_METHODS */ - numChars = XLookupString(&eventPtr->xkey, numStorage, - NUM_SIZE, (KeySym *) NULL, - (XComposeStatus *) NULL); -#endif /* TK_USE_INPUT_METHODS */ - numStorage[numChars] = '\0'; - string = numStorage; + Tcl_DStringFree(&buf); + string = TkpGetString(winPtr, eventPtr, &buf); } goto doString; case 'B': @@ -2496,6 +2531,7 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) Tcl_DStringSetLength(dsPtr, length + spaceNeeded); before += 2; } + Tcl_DStringFree(&buf); } /* @@ -2528,7 +2564,7 @@ ChangeScreen(interp, dispName, screenIndex) { Tcl_DString cmd; int code; - char screen[30]; + char screen[TCL_INTEGER_SPACE]; Tcl_DStringInit(&cmd); Tcl_DStringAppend(&cmd, "tkScreenChanged ", 16); @@ -2562,87 +2598,96 @@ ChangeScreen(interp, dispName, screenIndex) */ int -Tk_EventCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_EventObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { - int i; - size_t length; - char *option; + int index; Tk_Window tkwin; VirtualEventTable *vetPtr; TkBindInfo bindInfo; - - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg1?\"", (char *) NULL); - return TCL_ERROR; - } - - option = argv[1]; - length = strlen(option); - if (length == 0) { - goto badopt; - } + static char *optionStrings[] = { + "add", "delete", "generate", "info", + NULL + }; + enum options { + EVENT_ADD, EVENT_DELETE, EVENT_GENERATE, EVENT_INFO + }; tkwin = (Tk_Window) clientData; bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo; vetPtr = &((BindInfo *) bindInfo)->virtualEventTable; - if (strncmp(option, "add", length) == 0) { - if (argc < 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " add virtual sequence ?sequence ...?\"", (char *) NULL); - return TCL_ERROR; - } - for (i = 3; i < argc; i++) { - if (CreateVirtualEvent(interp, vetPtr, argv[2], argv[i]) - != TCL_OK) { + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + + switch ((enum options) index) { + case EVENT_ADD: { + int i; + char *name, *event; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual sequence ?sequence ...?"); return TCL_ERROR; } + name = Tcl_GetStringFromObj(objv[2], NULL); + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { + return TCL_ERROR; + } + } + break; } - } else if (strncmp(option, "delete", length) == 0) { - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " delete virtual ?sequence sequence ...?\"", - (char *) NULL); - return TCL_ERROR; - } - if (argc == 3) { - return DeleteVirtualEvent(interp, vetPtr, argv[2], NULL); - } - for (i = 3; i < argc; i++) { - if (DeleteVirtualEvent(interp, vetPtr, argv[2], argv[i]) - != TCL_OK) { + case EVENT_DELETE: { + int i; + char *name, *event; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual ?sequence sequence ...?"); return TCL_ERROR; } + name = Tcl_GetStringFromObj(objv[2], NULL); + if (objc == 3) { + return DeleteVirtualEvent(interp, vetPtr, name, NULL); + } + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { + return TCL_ERROR; + } + } + break; } - } else if (strncmp(option, "generate", length) == 0) { - if (argc < 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " generate window event ?options?\"", (char *) NULL); - return TCL_ERROR; + case EVENT_GENERATE: { + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); + return TCL_ERROR; + } + return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); } - return HandleEventGenerate(interp, tkwin, argc - 2, argv + 2); - } else if (strncmp(option, "info", length) == 0) { - if (argc == 2) { - GetAllVirtualEvents(interp, vetPtr); - return TCL_OK; - } else if (argc == 3) { - return GetVirtualEvent(interp, vetPtr, argv[2]); - } else { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " info ?virtual?\"", (char *) NULL); - return TCL_ERROR; + case EVENT_INFO: { + if (objc == 2) { + GetAllVirtualEvents(interp, vetPtr); + return TCL_OK; + } else if (objc == 3) { + return GetVirtualEvent(interp, vetPtr, + Tcl_GetStringFromObj(objv[2], NULL)); + } else { + Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); + return TCL_ERROR; + } } - } else { - badopt: - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": should be add, delete, generate, info", (char *) NULL); - return TCL_ERROR; } return TCL_OK; } @@ -2729,8 +2774,8 @@ DeleteVirtualEventTable(vetPtr) * Results: * The return value is TCL_ERROR if an error occured while * creating the virtual binding. In this case, an error message - * will be left in interp->result. If all went well then the return - * value is TCL_OK. + * will be left in the interp's result. If all went well then the + * return value is TCL_OK. * * Side effects: * The virtual event may cause future calls to Tk_BindEvent to @@ -2835,7 +2880,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) * * Results: * The result is a standard Tcl return value. If an error - * occurs then interp->result will contain an error message. + * occurs then the interp's result will contain an error message. * It is not an error to attempt to delete a virtual event that * does not exist or a definition that does not exist. * @@ -2887,7 +2932,10 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString, 0, 0, &eventMask); if (eventPSPtr == NULL) { - return (interp->result[0] != '\0') ? TCL_ERROR : TCL_OK; + char *string; + + string = Tcl_GetStringResult(interp); + return (string[0] != '\0') ? TCL_ERROR : TCL_OK; } } @@ -2989,12 +3037,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) * given virtual event. * * Results: - * The return value is TCL_OK and interp->result is filled with the + * The return value is TCL_OK and the interp's result is filled with the * string representation of the physical events associated with the * virtual event; if there are no physical events for the given virtual - * event, interp->result is filled with and empty string. If the + * event, the interp's result is filled with and empty string. If the * virtual event string is improperly formed, then TCL_ERROR is - * returned and an error message is left in interp->result. + * returned and an error message is left in the interp's result. * * Side effects: * None. @@ -3046,7 +3094,7 @@ GetVirtualEvent(interp, vetPtr, virtString) * event defined. * * Results: - * There is no return value. Interp->result is modified to + * There is no return value. The interp's result is modified to * hold a Tcl list with one entry for each virtual event in * nameTable. * @@ -3115,56 +3163,72 @@ GetAllVirtualEvents(interp, vetPtr) *--------------------------------------------------------------------------- */ static int -HandleEventGenerate(interp, mainwin, argc, argv) - Tcl_Interp *interp; /* Interp for error messages and name lookup. */ - Tk_Window mainwin; /* Main window associated with interp. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +HandleEventGenerate(interp, mainWin, objc, objv) + Tcl_Interp *interp; /* Interp for errors return and name lookup. */ + Tk_Window mainWin; /* Main window associated with interp. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { + XEvent event; + char *name, *p; + int count, flags, synch, i, number; + Tcl_QueuePosition pos; Pattern pat; - Tk_Window tkwin; - char *p; + Tk_Window tkwin, tkwin2; + TkWindow *mainPtr; unsigned long eventMask; - int count, i, state, flags, synch; - Tcl_QueuePosition pos; - XEvent event; + static char *fieldStrings[] = { + "-when", "-above", "-borderwidth", "-button", + "-count", "-delta", "-detail", "-focus", + "-height", + "-keycode", "-keysym", "-mode", "-override", + "-place", "-root", "-rootx", "-rooty", + "-sendevent", "-serial", "-state", "-subwindow", + "-time", "-width", "-window", "-x", + "-y", NULL + }; + enum field { + EVENT_WHEN, EVENT_ABOVE, EVENT_BORDER, EVENT_BUTTON, + EVENT_COUNT, EVENT_DELTA, EVENT_DETAIL, EVENT_FOCUS, + EVENT_HEIGHT, + EVENT_KEYCODE, EVENT_KEYSYM, EVENT_MODE, EVENT_OVERRIDE, + EVENT_PLACE, EVENT_ROOT, EVENT_ROOTX, EVENT_ROOTY, + EVENT_SEND, EVENT_SERIAL, EVENT_STATE, EVENT_SUBWINDOW, + EVENT_TIME, EVENT_WIDTH, EVENT_WINDOW, EVENT_X, + EVENT_Y + }; + + if (NameToWindow(interp, mainWin, objv[0], &tkwin) != TCL_OK) { + return TCL_ERROR; + } - if (argv[0][0] == '.') { - tkwin = Tk_NameToWindow(interp, argv[0], mainwin); - if (tkwin == NULL) { - return TCL_ERROR; - } - } else { - if (TkpScanWindowId(NULL, argv[0], &i) != TCL_OK) { - Tcl_AppendResult(interp, "bad window name/identifier \"", - argv[0], "\"", (char *) NULL); - return TCL_ERROR; - } - tkwin = Tk_IdToWindow(Tk_Display(mainwin), (Window) i); - if ((tkwin == NULL) || (((TkWindow *) mainwin)->mainPtr - != ((TkWindow *) tkwin)->mainPtr)) { - Tcl_AppendResult(interp, "window id \"", argv[0], - "\" doesn't exist in this application", (char *) NULL); - return TCL_ERROR; - } + mainPtr = (TkWindow *) mainWin; + if ((tkwin == NULL) + || (mainPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) { + char *name; + + name = Tcl_GetStringFromObj(objv[0], NULL); + Tcl_AppendResult(interp, "window id \"", name, + "\" doesn't exist in this application", (char *) NULL); + return TCL_ERROR; } - p = argv[1]; + name = Tcl_GetStringFromObj(objv[1], NULL); + + p = name; + eventMask = 0; count = ParseEventDescription(interp, &p, &pat, &eventMask); if (count == 0) { return TCL_ERROR; } if (count != 1) { - interp->result = "Double or Triple modifier not allowed"; + Tcl_SetResult(interp, "Double or Triple modifier not allowed", + TCL_STATIC); return TCL_ERROR; } if (*p != '\0') { - interp->result = "only one event specification allowed"; - return TCL_ERROR; - } - if (argc & 1) { - Tcl_AppendResult(interp, "value for \"", argv[argc - 1], - "\" missing", (char *) NULL); + Tcl_SetResult(interp, "only one event specification allowed", + TCL_STATIC); return TCL_ERROR; } @@ -3179,34 +3243,7 @@ HandleEventGenerate(interp, mainwin, argc, argv) if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { event.xkey.state = pat.needMods; if ((flags & KEY) && (event.xany.type != MouseWheelEvent)) { - /* - * When mapping from a keysym to a keycode, need information about - * the modifier state that should be used so that when they call - * XKeycodeToKeysym taking into account the xkey.state, they will - * get back the original keysym. - */ - - if (pat.detail.keySym == NoSymbol) { - event.xkey.keycode = 0; - } else { - event.xkey.keycode = XKeysymToKeycode(event.xany.display, - pat.detail.keySym); - } - if (event.xkey.keycode != 0) { - for (state = 0; state < 4; state++) { - if (XKeycodeToKeysym(event.xany.display, - event.xkey.keycode, state) == pat.detail.keySym) { - if (state & 1) { - event.xkey.state |= ShiftMask; - } - if (state & 2) { - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - event.xkey.state |= dispPtr->modeModMask; - } - break; - } - } - } + SetKeycodeAndState(tkwin, pat.detail.keySym, &event); } else if (flags & BUTTON) { event.xbutton.button = pat.detail.button; } else if (flags & VIRTUAL) { @@ -3224,375 +3261,407 @@ HandleEventGenerate(interp, mainwin, argc, argv) synch = 1; pos = TCL_QUEUE_TAIL; - for (i = 2; i < argc; i += 2) { - char *field, *value; - Tk_Window tkwin2; - int number; - KeySym keysym; + for (i = 2; i < objc; i += 2) { + Tcl_Obj *optionPtr, *valuePtr; + int index; - field = argv[i]; - value = argv[i+1]; - - if (strcmp(field, "-when") == 0) { - if (strcmp(value, "now") == 0) { - synch = 1; - } else if (strcmp(value, "head") == 0) { - pos = TCL_QUEUE_HEAD; - synch = 0; - } else if (strcmp(value, "mark") == 0) { - pos = TCL_QUEUE_MARK; - synch = 0; - } else if (strcmp(value, "tail") == 0) { - pos = TCL_QUEUE_TAIL; + optionPtr = objv[i]; + valuePtr = objv[i + 1]; + + if (Tcl_GetIndexFromObj(interp, optionPtr, fieldStrings, "option", + TCL_EXACT, &index) != TCL_OK) { + return TCL_ERROR; + } + if (objc & 1) { + /* + * This test occurs after Tcl_GetIndexFromObj() so that + * "event generate <Button> -xyz" will return the error message + * that "-xyz" is a bad option, rather than that the value + * for "-xyz" is missing. + */ + + Tcl_AppendResult(interp, "value for \"", + Tcl_GetStringFromObj(optionPtr, NULL), "\" missing", + (char *) NULL); + return TCL_ERROR; + } + + switch ((enum field) index) { + case EVENT_WHEN: { + pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, + queuePosition, valuePtr); + if ((int) pos < -1) { + return TCL_ERROR; + } synch = 0; - } else { - Tcl_AppendResult(interp, "bad position \"", value, - "\": should be now, head, mark, tail", (char *) NULL); - return TCL_ERROR; + if ((int) pos == -1) { + synch = 1; + } + break; } - } else if (strcmp(field, "-above") == 0) { - if (value[0] == '.') { - tkwin2 = Tk_NameToWindow(interp, value, mainwin); - if (tkwin2 == NULL) { + case EVENT_ABOVE: { + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { return TCL_ERROR; } - number = Tk_WindowId(tkwin2); - } else if (TkpScanWindowId(interp, value, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & CONFIG) { - event.xconfigure.above = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-borderwidth") == 0) { - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.border_width = number; - } else { - goto badopt; + if (flags & CONFIG) { + event.xconfigure.above = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-button") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_BORDER: { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.border_width = number; + } else { + goto badopt; + } + break; } - if (flags & BUTTON) { - event.xbutton.button = number; - } else { - goto badopt; + case EVENT_BUTTON: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & BUTTON) { + event.xbutton.button = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-count") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_COUNT: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.count = number; + } else { + goto badopt; + } + break; } - if (flags & EXPOSE) { - event.xexpose.count = number; - } else { - goto badopt; + case EVENT_DELTA: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-delta") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_DETAIL: { + number = TkFindStateNumObj(interp, optionPtr, notifyDetail, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & FOCUS) { + event.xfocus.detail = number; + } else if (flags & CROSSING) { + event.xcrossing.detail = number; + } else { + goto badopt; + } + break; } - if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; + case EVENT_FOCUS: { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & CROSSING) { + event.xcrossing.focus = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-detail") == 0) { - number = TkFindStateNum(interp, field, notifyDetail, value); - if (number < 0) { - return TCL_ERROR; + case EVENT_HEIGHT: { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.height = number; + } else if (flags & CONFIG) { + event.xconfigure.height = number; + } else { + goto badopt; + } + break; } - if (flags & FOCUS) { - event.xfocus.detail = number; - } else if (flags & CROSSING) { - event.xcrossing.detail = number; - } else { - goto badopt; + case EVENT_KEYCODE: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-focus") == 0) { - if (Tcl_GetBoolean(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_KEYSYM: { + KeySym keysym; + char *value; + + value = Tcl_GetStringFromObj(valuePtr, NULL); + keysym = TkStringToKeysym(value); + if (keysym == NoSymbol) { + Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", + (char *) NULL); + return TCL_ERROR; + } + + SetKeycodeAndState(tkwin, keysym, &event); + if (event.xkey.keycode == 0) { + Tcl_AppendResult(interp, "no keycode for keysym \"", value, + "\"", (char *) NULL); + return TCL_ERROR; + } + if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { + goto badopt; + } + break; } - if (flags & CROSSING) { - event.xcrossing.focus = number; - } else { - goto badopt; + case EVENT_MODE: { + number = TkFindStateNumObj(interp, optionPtr, notifyMode, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & CROSSING) { + event.xcrossing.mode = number; + } else if (flags & FOCUS) { + event.xfocus.mode = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-height") == 0) { - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_OVERRIDE: { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & CREATE) { + event.xcreatewindow.override_redirect = number; + } else if (flags & MAP) { + event.xmap.override_redirect = number; + } else if (flags & REPARENT) { + event.xreparent.override_redirect = number; + } else if (flags & CONFIG) { + event.xconfigure.override_redirect = number; + } else { + goto badopt; + } + break; } - if (flags & EXPOSE) { - event.xexpose.height = number; - } else if (flags & CONFIG) { - event.xconfigure.height = number; - } else { - goto badopt; + case EVENT_PLACE: { + number = TkFindStateNumObj(interp, optionPtr, circPlace, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & CIRC) { + event.xcirculate.place = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-keycode") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_ROOT: { + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.root = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; } - if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; + case EVENT_ROOTX: { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x_root = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-keysym") == 0) { - keysym = TkStringToKeysym(value); - if (keysym == NoSymbol) { - Tcl_AppendResult(interp, "unknown keysym \"", value, - "\"", (char *) NULL); - return TCL_ERROR; + case EVENT_ROOTY: { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y_root = number; + } else { + goto badopt; + } + break; } - /* - * When mapping from a keysym to a keycode, need information about - * the modifier state that should be used so that when they call - * XKeycodeToKeysym taking into account the xkey.state, they will - * get back the original keysym. - */ + case EVENT_SEND: { + CONST char *value; - number = XKeysymToKeycode(event.xany.display, keysym); - if (number == 0) { - Tcl_AppendResult(interp, "no keycode for keysym \"", value, - "\"", (char *) NULL); - return TCL_ERROR; - } - for (state = 0; state < 4; state++) { - if (XKeycodeToKeysym(event.xany.display, (unsigned) number, - state) == keysym) { - if (state & 1) { - event.xkey.state |= ShiftMask; + value = Tcl_GetStringFromObj(valuePtr, NULL); + if (isdigit(UCHAR(value[0]))) { + /* + * Allow arbitrary integer values for the field; they + * are needed by a few of the tests in the Tk test suite. + */ + + if (Tcl_GetIntFromObj(interp, valuePtr, &number) + != TCL_OK) { + return TCL_ERROR; } - if (state & 2) { - TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - event.xkey.state |= dispPtr->modeModMask; + } else { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) + != TCL_OK) { + return TCL_ERROR; } - break; } - } - if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-mode") == 0) { - number = TkFindStateNum(interp, field, notifyMode, value); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CROSSING) { - event.xcrossing.mode = number; - } else if (flags & FOCUS) { - event.xfocus.mode = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-override") == 0) { - if (Tcl_GetBoolean(interp, value, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CREATE) { - event.xcreatewindow.override_redirect = number; - } else if (flags & MAP) { - event.xmap.override_redirect = number; - } else if (flags & REPARENT) { - event.xreparent.override_redirect = number; - } else if (flags & CONFIG) { - event.xconfigure.override_redirect = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-place") == 0) { - number = TkFindStateNum(interp, field, circPlace, value); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CIRC) { - event.xcirculate.place = number; - } else { - goto badopt; + event.xany.send_event = number; + break; } - } else if (strcmp(field, "-root") == 0) { - if (value[0] == '.') { - tkwin2 = Tk_NameToWindow(interp, value, mainwin); - if (tkwin2 == NULL) { + case EVENT_SERIAL: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - number = Tk_WindowId(tkwin2); - } else if (TkpScanWindowId(interp, value, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.root = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-rootx") == 0) { - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x_root = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-rooty") == 0) { - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; + event.xany.serial = number; + break; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y_root = number; - } else { - goto badopt; + case EVENT_STATE: { + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) + != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + event.xkey.state = number; + } else { + event.xcrossing.state = number; + } + } else if (flags & VISIBILITY) { + number = TkFindStateNumObj(interp, optionPtr, visNotify, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + event.xvisibility.state = number; + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-sendevent") == 0) { - if (isdigit(UCHAR(value[0]))) { - /* - * Allow arbitrary integer values for the field; they - * are needed by a few of the tests in the Tk test suite. - */ - - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { + case EVENT_SUBWINDOW: { + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { return TCL_ERROR; } - } else { - if (Tcl_GetBoolean(interp, value, &number) != TCL_OK) { - return TCL_ERROR; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.subwindow = Tk_WindowId(tkwin2); + } else { + goto badopt; } + break; } - event.xany.send_event = number; - } else if (strcmp(field, "-serial") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; - } - event.xany.serial = number; - } else if (strcmp(field, "-state") == 0) { - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { + case EVENT_TIME: { + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - event.xkey.state = number; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.time = (Time) number; + } else if (flags & PROP) { + event.xproperty.time = (Time) number; } else { - event.xcrossing.state = number; + goto badopt; } - } else if (flags & VISIBILITY) { - number = TkFindStateNum(interp, field, visNotify, value); - if (number < 0) { + break; + } + case EVENT_WIDTH: { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) + != TCL_OK) { return TCL_ERROR; } - event.xvisibility.state = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-subwindow") == 0) { - if (value[0] == '.') { - tkwin2 = Tk_NameToWindow(interp, value, mainwin); - if (tkwin2 == NULL) { - return TCL_ERROR; + if (flags & EXPOSE) { + event.xexpose.width = number; + } else if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.width = number; + } else { + goto badopt; } - number = Tk_WindowId(tkwin2); - } else if (TkpScanWindowId(interp, value, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.subwindow = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-time") == 0) { - if (Tcl_GetInt(interp, value, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.time = (Time) number; - } else if (flags & PROP) { - event.xproperty.time = (Time) number; - } else { - goto badopt; - } - } else if (strcmp(field, "-width") == 0) { - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & EXPOSE) { - event.xexpose.width = number; - } else if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.width = number; - } else { - goto badopt; + break; } - } else if (strcmp(field, "-window") == 0) { - if (value[0] == '.') { - tkwin2 = Tk_NameToWindow(interp, value, mainwin); - if (tkwin2 == NULL) { + case EVENT_WINDOW: { + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { return TCL_ERROR; } - number = Tk_WindowId(tkwin2); - } else if (TkpScanWindowId(interp, value, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|DESTROY|UNMAP|MAP|REPARENT|CONFIG - |GRAVITY|CIRC)) { - event.xcreatewindow.window = number; - } else { - goto badopt; - } - } else if (strcmp(field, "-x") == 0) { - int rootX, rootY; - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; - } - Tk_GetRootCoords(tkwin, &rootX, &rootY); - rootX += number; - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x = number; - event.xkey.x_root = rootX; - } else if (flags & EXPOSE) { - event.xexpose.x = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.x = number; - } else if (flags & REPARENT) { - event.xreparent.x = number; - } else { - goto badopt; + if (flags & (CREATE|DESTROY|UNMAP|MAP|REPARENT|CONFIG + |GRAVITY|CIRC)) { + event.xcreatewindow.window = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; } - } else if (strcmp(field, "-y") == 0) { - int rootX, rootY; - if (Tk_GetPixels(interp, tkwin, value, &number) != TCL_OK) { - return TCL_ERROR; + case EVENT_X: { + int rootX, rootY; + + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) + != TCL_OK) { + return TCL_ERROR; + } + Tk_GetRootCoords(tkwin, &rootX, &rootY); + rootX += number; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x = number; + event.xkey.x_root = rootX; + } else if (flags & EXPOSE) { + event.xexpose.x = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.x = number; + } else if (flags & REPARENT) { + event.xreparent.x = number; + } else { + goto badopt; + } + break; } - Tk_GetRootCoords(tkwin, &rootX, &rootY); - rootY += number; - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y = number; - event.xkey.y_root = rootY; - } else if (flags & EXPOSE) { - event.xexpose.y = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.y = number; - } else if (flags & REPARENT) { - event.xreparent.y = number; - } else { - goto badopt; + case EVENT_Y: { + int rootX, rootY; + + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) + != TCL_OK) { + return TCL_ERROR; + } + Tk_GetRootCoords(tkwin, &rootX, &rootY); + rootY += number; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y = number; + event.xkey.y_root = rootY; + } else if (flags & EXPOSE) { + event.xexpose.y = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.y = number; + } else if (flags & REPARENT) { + event.xreparent.y = number; + } else { + goto badopt; + } + break; } - } else { - badopt: - Tcl_AppendResult(interp, "bad option to ", argv[1], - " event: \"", field, "\"", (char *) NULL); - return TCL_ERROR; } + continue; + + badopt: + Tcl_AppendResult(interp, name, " event doesn't accept \"", + Tcl_GetStringFromObj(optionPtr, NULL), "\" option", NULL); + return TCL_ERROR; } - if (synch != 0) { Tk_HandleEvent(&event); } else { @@ -3600,6 +3669,79 @@ HandleEventGenerate(interp, mainwin, argc, argv) } Tcl_ResetResult(interp); return TCL_OK; + +} +static int +NameToWindow(interp, mainWin, objPtr, tkwinPtr) + Tcl_Interp *interp; /* Interp for error return and name lookup. */ + Tk_Window mainWin; /* Main window of application. */ + Tcl_Obj *objPtr; /* Contains name or id string of window. */ + Tk_Window *tkwinPtr; /* Filled with token for window. */ +{ + char *name; + Tk_Window tkwin; + int id; + + name = Tcl_GetStringFromObj(objPtr, NULL); + if (name[0] == '.') { + tkwin = Tk_NameToWindow(interp, name, mainWin); + if (tkwin == NULL) { + return TCL_ERROR; + } + *tkwinPtr = tkwin; + } else { + if (TkpScanWindowId(NULL, name, &id) != TCL_OK) { + Tcl_AppendResult(interp, "bad window name/identifier \"", + name, "\"", (char *) NULL); + return TCL_ERROR; + } + *tkwinPtr = Tk_IdToWindow(Tk_Display(mainWin), (Window) id); + } + return TCL_OK; +} + +/* + * When mapping from a keysym to a keycode, need + * information about the modifier state that should be used + * so that when they call XKeycodeToKeysym taking into + * account the xkey.state, they will get back the original + * keysym. + */ + +static void +SetKeycodeAndState(tkwin, keySym, eventPtr) + Tk_Window tkwin; + KeySym keySym; + XEvent *eventPtr; +{ + Display *display; + int state; + KeyCode keycode; + + display = Tk_Display(tkwin); + + if (keySym == NoSymbol) { + keycode = 0; + } else { + keycode = XKeysymToKeycode(display, keySym); + } + if (keycode != 0) { + for (state = 0; state < 4; state++) { + if (XKeycodeToKeysym(display, keycode, state) == keySym) { + if (state & 1) { + eventPtr->xkey.state |= ShiftMask; + } + if (state & 2) { + TkDisplay *dispPtr; + + dispPtr = ((TkWindow *) tkwin)->dispPtr; + eventPtr->xkey.state |= dispPtr->modeModMask; + } + break; + } + } + } + eventPtr->xkey.keycode = keycode; } /* @@ -3613,7 +3755,7 @@ HandleEventGenerate(interp, mainwin, argc, argv) * Results: * The return value is NULL if the virtual event string was * not in the proper format. In this case, an error message - * will be left in interp->result. Otherwise the return + * will be left in the interp's result. Otherwise the return * value is a Tk_Uid that represents the virtual event. * * Side effects: @@ -3659,7 +3801,7 @@ GetVirtualEventUid(interp, virtString) * in patternTable that corresponds to eventString. If an error * was found while parsing eventString, or if "create" is 0 and * no pattern sequence previously existed, then NULL is returned - * and interp->result contains a message describing the problem. + * and the interp's result contains a message describing the problem. * If no pattern sequence previously existed for eventString, then * a new one is created with a NULL command field. In a successful * return, *maskPtr is filled in with a mask of the event types @@ -3735,8 +3877,9 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (eventMask & VirtualEventMask) { if (allowVirtual == 0) { - interp->result = - "virtual event not allowed in definition of another virtual event"; + Tcl_SetResult(interp, + "virtual event not allowed in definition of another virtual event", + TCL_STATIC); return NULL; } virtualFound = 1; @@ -3767,11 +3910,12 @@ FindSequence(interp, patternTablePtr, object, eventString, create, */ if (numPats == 0) { - interp->result = "no events specified in binding"; + Tcl_SetResult(interp, "no events specified in binding", TCL_STATIC); return NULL; } if ((numPats > 1) && (virtualFound != 0)) { - interp->result = "virtual events may not be composed"; + Tcl_SetResult(interp, "virtual events may not be composed", + TCL_STATIC); return NULL; } @@ -3797,6 +3941,14 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (new) { Tcl_DeleteHashEntry(hPtr); } + /* + * No binding exists for the sequence, so return an empty error. + * This is a special error that the caller will check for in order + * to silently ignore this case. This is a hack that maintains + * backward compatibility for Tk_GetBinding but the various "bind" + * commands silently ignore missing bindings. + */ + return NULL; } psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq) @@ -3886,8 +4038,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, if (isprint(UCHAR(*p))) { patPtr->detail.keySym = *p; } else { - sprintf(interp->result, - "bad ASCII character 0x%x", (unsigned char) *p); + char buf[64]; + + sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return 0; } } @@ -3927,11 +4081,13 @@ ParseEventDescription(interp, eventStringPtr, patPtr, char *field = p + 1; p = strchr(field, '>'); if (p == field) { - interp->result = "virtual event \"<<>>\" is badly formed"; + Tcl_SetResult(interp, "virtual event \"<<>>\" is badly formed", + TCL_STATIC); return 0; } if ((p == NULL) || (p[1] != '>')) { - interp->result = "missing \">\" in virtual binding"; + Tcl_SetResult(interp, "missing \">\" in virtual binding", + TCL_STATIC); return 0; } *p = '\0'; @@ -4018,7 +4174,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } } } else if (eventFlags == 0) { - interp->result = "no event type or button # or keysym"; + Tcl_SetResult(interp, "no event type or button # or keysym", + TCL_STATIC); return 0; } @@ -4029,11 +4186,13 @@ ParseEventDescription(interp, eventStringPtr, patPtr, while (*p != '\0') { p++; if (*p == '>') { - interp->result = "extra characters after detail in binding"; + Tcl_SetResult(interp, + "extra characters after detail in binding", + TCL_STATIC); return 0; } } - interp->result = "missing \">\" in binding"; + Tcl_SetResult(interp, "missing \">\" in binding", TCL_STATIC); return 0; } p++; @@ -4108,7 +4267,7 @@ GetPatternString(psPtr, dsPtr) Tcl_DString *dsPtr; { Pattern *patPtr; - char c, buffer[10]; + char c, buffer[TCL_INTEGER_SPACE]; int patsLeft, needMods; ModInfo *modPtr; EventInfo *eiPtr; @@ -4529,7 +4688,7 @@ TkKeysymToString(keysym) * * Results: * Returns the result of evaluating script, including both a standard - * Tcl completion code and a string in interp->result. + * Tcl completion code and a string in the interp's result. * * Side effects: * None. diff --git a/generic/tkBitmap.c b/generic/tkBitmap.c index e7a14b9..6facc97 100644 --- a/generic/tkBitmap.c +++ b/generic/tkBitmap.c @@ -6,12 +6,12 @@ * also avoids interactions with the X server. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkBitmap.c,v 1.6 1998/09/14 18:23:03 stanton Exp $ + * RCS: @(#) $Id: tkBitmap.c,v 1.7 1999/04/16 01:51:10 stanton Exp $ */ #include "tkPort.h" @@ -51,69 +51,180 @@ * "nameTable". */ -typedef struct { +typedef struct TkBitmap { Pixmap bitmap; /* X identifier for bitmap. None means this * bitmap was created by Tk_DefineBitmap * and it isn't currently in use. */ int width, height; /* Dimensions of bitmap. */ Display *display; /* Display for which bitmap is valid. */ - int refCount; /* Number of active uses of bitmap. */ - Tcl_HashEntry *hashPtr; /* Entry in nameTable for this structure + int resourceRefCount; /* Number of active uses of this bitmap (each + * active use corresponds to a call to + * Tk_AllocBitmapFromObj or Tk_GetBitmap). + * If this count is 0, then this TkBitmap + * structure is no longer valid and it isn't + * present in nameTable: it is being kept + * around only because there are objects + * referring to it. The structure is freed + * when resourceRefCount and objRefCount + * are both 0. */ + int objRefCount; /* Number of Tcl_Obj's that reference + * this structure. */ + Tcl_HashEntry *nameHashPtr; /* Entry in nameTable for this structure + * (needed when deleting). */ + Tcl_HashEntry *idHashPtr; /* Entry in idTable for this structure * (needed when deleting). */ + struct TkBitmap *nextPtr; /* Points to the next TkBitmap structure with + * the same name. All bitmaps with the + * same name (but different displays) are + * chained together off a single entry in + * nameTable. */ } TkBitmap; -/* - * Hash table to map from a textual description of a bitmap to the - * TkBitmap record for the bitmap, and key structure used in that - * hash table: +/* + * Used in bitmapDataTable, stored in the TkDisplay structure, to map + * between in-core data about a bitmap to its TkBitmap structure. */ -static Tcl_HashTable nameTable; typedef struct { - Tk_Uid name; /* Textual name for desired bitmap. */ - Screen *screen; /* Screen on which bitmap will be used. */ -} NameKey; + char *source; /* Bitmap bits. */ + int width, height; /* Dimensions of bitmap. */ +} DataKey; + +typedef struct ThreadSpecificData { + int initialized; /* 0 means table below needs initializing. */ + Tcl_HashTable predefBitmapTable; + /* Hash table created by Tk_DefineBitmap + * to map from a name to a collection + * of in-core data about a bitmap. The + * table is indexed by the address of the + * data for the bitmap, and the entries + * contain pointers to TkPredefBitmap + * structures. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* - * Hash table that maps from <display + bitmap id> to the TkBitmap structure - * for the bitmap. This table is used by Tk_FreeBitmap. + * Forward declarations for procedures defined in this file: */ -static Tcl_HashTable idTable; -typedef struct { - Display *display; /* Display for which bitmap was allocated. */ - Pixmap pixmap; /* X identifier for pixmap. */ -} IdKey; +static void BitmapInit _ANSI_ARGS_((TkDisplay *dispPtr)); +static void DupBitmapObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, + Tcl_Obj *dupObjPtr)); +static void FreeBitmap _ANSI_ARGS_((TkBitmap *bitmapPtr)); +static void FreeBitmapObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); +static TkBitmap * GetBitmap _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, CONST char *name)); +static TkBitmap * GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj *objPtr)); +static void InitBitmapObj _ANSI_ARGS_((Tcl_Obj *objPtr)); /* - * Hash table create by Tk_DefineBitmap to map from a name to a - * collection of in-core data about a bitmap. The table is - * indexed by the address of the data for the bitmap, and the entries - * contain pointers to TkPredefBitmap structures. + * The following structure defines the implementation of the "bitmap" Tcl + * object, which maps a string bitmap name to a TkBitmap object. The + * ptr1 field of the Tcl_Obj points to a TkBitmap object. */ -Tcl_HashTable tkPredefBitmapTable; - +static Tcl_ObjType bitmapObjType = { + "bitmap", /* name */ + FreeBitmapObjProc, /* freeIntRepProc */ + DupBitmapObjProc, /* dupIntRepProc */ + NULL, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + /* - * Hash table used by Tk_GetBitmapFromData to map from a collection - * of in-core data about a bitmap to a Tk_Uid giving an automatically- - * generated name for the bitmap: + *---------------------------------------------------------------------- + * + * Tk_AllocBitmapFromObj -- + * + * Given a Tcl_Obj *, map the value to a corresponding + * Pixmap structure based on the tkwin given. + * + * Results: + * The return value is the X identifer for the desired bitmap + * (i.e. a Pixmap with a single plane), unless string couldn't be + * parsed correctly. In this case, None is returned and an error + * message is left in the interp's result. The caller should never + * modify the bitmap that is returned, and should eventually call + * Tk_FreeBitmapFromObj when the bitmap is no longer needed. + * + * Side effects: + * The bitmap is added to an internal database with a reference count. + * For each call to this procedure, there should eventually be a call + * to Tk_FreeBitmapFromObj, so that the database can be cleaned up + * when bitmaps aren't needed anymore. + * + *---------------------------------------------------------------------- */ -static Tcl_HashTable dataTable; -typedef struct { - char *source; /* Bitmap bits. */ - int width, height; /* Dimensions of bitmap. */ -} DataKey; +Pixmap +Tk_AllocBitmapFromObj(interp, tkwin, objPtr) + Tcl_Interp *interp; /* Interp for error results. This may + * be NULL. */ + Tk_Window tkwin; /* Need the screen the bitmap is used on.*/ + Tcl_Obj *objPtr; /* Object describing bitmap; see manual + * entry for legal syntax of string value. */ +{ + TkBitmap *bitmapPtr; -static int initialized = 0; /* 0 means static structures haven't been - * initialized yet. */ + if (objPtr->typePtr != &bitmapObjType) { + InitBitmapObj(objPtr); + } + bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; -/* - * Forward declarations for procedures defined in this file: - */ + /* + * If the object currently points to a TkBitmap, see if it's the + * one we want. If so, increment its reference count and return. + */ + + if (bitmapPtr != NULL) { + if (bitmapPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a TkBitmap that's + * no longer in use. Clear the reference. + */ + + FreeBitmapObjProc(objPtr); + bitmapPtr = NULL; + } else if (Tk_Display(tkwin) == bitmapPtr->display) { + bitmapPtr->resourceRefCount++; + return bitmapPtr->bitmap; + } + } + + /* + * The object didn't point to the TkBitmap that we wanted. Search + * the list of TkBitmaps with the same name to see if one of the + * others is the right one. + */ + + if (bitmapPtr != NULL) { + TkBitmap *firstBitmapPtr = + (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr); + FreeBitmapObjProc(objPtr); + for (bitmapPtr = firstBitmapPtr; bitmapPtr != NULL; + bitmapPtr = bitmapPtr->nextPtr) { + if (Tk_Display(tkwin) == bitmapPtr->display) { + bitmapPtr->resourceRefCount++; + bitmapPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr; + return bitmapPtr->bitmap; + } + } + } + + /* + * Still no luck. Call GetBitmap to allocate a new TkBitmap object. + */ -static void BitmapInit _ANSI_ARGS_((void)); + bitmapPtr = GetBitmap(interp, tkwin, Tcl_GetString(objPtr)); + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr; + if (bitmapPtr == NULL) { + return None; + } + bitmapPtr->objRefCount++; + return bitmapPtr->bitmap; +} /* *---------------------------------------------------------------------- @@ -127,7 +238,7 @@ static void BitmapInit _ANSI_ARGS_((void)); * The return value is the X identifer for the desired bitmap * (i.e. a Pixmap with a single plane), unless string couldn't be * parsed correctly. In this case, None is returned and an error - * message is left in interp->result. The caller should never + * message is left in the interp's result. The caller should never * modify the bitmap that is returned, and should eventually call * Tk_FreeBitmap when the bitmap is no longer needed. * @@ -145,30 +256,78 @@ Tk_GetBitmap(interp, tkwin, string) Tcl_Interp *interp; /* Interpreter to use for error reporting, * this may be NULL. */ Tk_Window tkwin; /* Window in which bitmap will be used. */ - Tk_Uid string; /* Description of bitmap. See manual entry + CONST char *string; /* Description of bitmap. See manual entry * for details on legal syntax. */ { - NameKey nameKey; - IdKey idKey; - Tcl_HashEntry *nameHashPtr, *idHashPtr, *predefHashPtr; - register TkBitmap *bitmapPtr; + TkBitmap *bitmapPtr = GetBitmap(interp, tkwin, string); + if (bitmapPtr == NULL) { + return None; + } + return bitmapPtr->bitmap; +} + +/* + *---------------------------------------------------------------------- + * + * GetBitmap -- + * + * Given a string describing a bitmap, locate (or create if necessary) + * a bitmap that fits the description. This routine returns the + * internal data structure for the bitmap. This avoids extra + * hash table lookups in Tk_AllocBitmapFromObj. + * + * Results: + * The return value is the X identifer for the desired bitmap + * (i.e. a Pixmap with a single plane), unless string couldn't be + * parsed correctly. In this case, None is returned and an error + * message is left in the interp's result. The caller should never + * modify the bitmap that is returned, and should eventually call + * Tk_FreeBitmap when the bitmap is no longer needed. + * + * Side effects: + * The bitmap is added to an internal database with a reference count. + * For each call to this procedure, there should eventually be a call + * to Tk_FreeBitmap or Tk_FreeBitmapFromObj, so that the database can + * be cleaned up when bitmaps aren't needed anymore. + * + *---------------------------------------------------------------------- + */ + +static TkBitmap * +GetBitmap(interp, tkwin, string) + Tcl_Interp *interp; /* Interpreter to use for error reporting, + * this may be NULL. */ + Tk_Window tkwin; /* Window in which bitmap will be used. */ + CONST char *string; /* Description of bitmap. See manual entry + * for details on legal syntax. */ +{ + Tcl_HashEntry *nameHashPtr, *predefHashPtr; + TkBitmap *bitmapPtr, *existingBitmapPtr; TkPredefBitmap *predefPtr; int new; Pixmap bitmap; int width, height; int dummy2; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (!initialized) { - BitmapInit(); + if (!dispPtr->bitmapInit) { + BitmapInit(dispPtr); } - nameKey.name = string; - nameKey.screen = Tk_Screen(tkwin); - nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &nameKey, &new); + nameHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapNameTable, string, &new); if (!new) { - bitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); - bitmapPtr->refCount++; - return bitmapPtr->bitmap; + existingBitmapPtr = (TkBitmap *) Tcl_GetHashValue(nameHashPtr); + for (bitmapPtr = existingBitmapPtr; bitmapPtr != NULL; + bitmapPtr = bitmapPtr->nextPtr) { + if (Tk_Display(tkwin) == bitmapPtr->display) { + bitmapPtr->resourceRefCount++; + return bitmapPtr; + } + } + } else { + existingBitmapPtr = NULL; } /* @@ -179,7 +338,7 @@ Tk_GetBitmap(interp, tkwin, string) * defined by a call to Tk_DefineBitmap. */ - if (*string == '@') { + if (*string == '@') { /* INTL: ISO char */ Tcl_DString buffer; int result; @@ -188,13 +347,19 @@ Tk_GetBitmap(interp, tkwin, string) " safe interpreter", (char *) NULL); goto error; } - - string = Tcl_TranslateFileName(interp, string + 1, &buffer); + + /* + * Note that we need to cast away the CONST from the string because + * Tcl_TranslateFileName is non const, even though it doesn't modify + * the string. + */ + + string = Tcl_TranslateFileName(interp, (char *) string + 1, &buffer); if (string == NULL) { goto error; } result = TkReadBitmapFile(Tk_Display(tkwin), - RootWindowOfScreen(nameKey.screen), string, + RootWindowOfScreen(Tk_Screen(tkwin)), string, (unsigned int *) &width, (unsigned int *) &height, &bitmap, &dummy2, &dummy2); if (result != BitmapSuccess) { @@ -207,7 +372,8 @@ Tk_GetBitmap(interp, tkwin, string) } Tcl_DStringFree(&buffer); } else { - predefHashPtr = Tcl_FindHashEntry(&tkPredefBitmapTable, string); + predefHashPtr = Tcl_FindHashEntry(&tsdPtr->predefBitmapTable, + string); if (predefHashPtr == NULL) { /* * The following platform specific call allows the user to @@ -236,7 +402,8 @@ Tk_GetBitmap(interp, tkwin, string) } } else { bitmap = XCreateBitmapFromData(Tk_Display(tkwin), - RootWindowOfScreen(nameKey.screen), predefPtr->source, + RootWindowOfScreen(Tk_Screen(tkwin)), + predefPtr->source, (unsigned) width, (unsigned) height); } } @@ -251,22 +418,24 @@ Tk_GetBitmap(interp, tkwin, string) bitmapPtr->width = width; bitmapPtr->height = height; bitmapPtr->display = Tk_Display(tkwin); - bitmapPtr->refCount = 1; - bitmapPtr->hashPtr = nameHashPtr; - idKey.display = bitmapPtr->display; - idKey.pixmap = bitmap; - idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey, - &new); + bitmapPtr->resourceRefCount = 1; + bitmapPtr->objRefCount = 0; + bitmapPtr->nameHashPtr = nameHashPtr; + bitmapPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapIdTable, + (char *) bitmap, &new); if (!new) { panic("bitmap already registered in Tk_GetBitmap"); } + bitmapPtr->nextPtr = existingBitmapPtr; Tcl_SetHashValue(nameHashPtr, bitmapPtr); - Tcl_SetHashValue(idHashPtr, bitmapPtr); - return bitmapPtr->bitmap; + Tcl_SetHashValue(bitmapPtr->idHashPtr, bitmapPtr); + return bitmapPtr; error: - Tcl_DeleteHashEntry(nameHashPtr); - return None; + if (new) { + Tcl_DeleteHashEntry(nameHashPtr); + } + return NULL; } /* @@ -280,7 +449,7 @@ Tk_GetBitmap(interp, tkwin, string) * * Results: * A standard Tcl result. If an error occurs then TCL_ERROR is - * returned and a message is left in interp->result. + * returned and a message is left in the interp's result. * * Side effects: * "Name" is entered into the bitmap table and may be used from @@ -292,7 +461,7 @@ Tk_GetBitmap(interp, tkwin, string) int Tk_DefineBitmap(interp, name, source, width, height) Tcl_Interp *interp; /* Interpreter to use for error reporting. */ - Tk_Uid name; /* Name to use for bitmap. Must not already + CONST char *name; /* Name to use for bitmap. Must not already * be defined as a bitmap. */ char *source; /* Address of bits for bitmap. */ int width; /* Width of bitmap. */ @@ -301,12 +470,23 @@ Tk_DefineBitmap(interp, name, source, width, height) int new; Tcl_HashEntry *predefHashPtr; TkPredefBitmap *predefPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + /* + * Initialize the Bitmap module if not initialized already for this + * thread. Since the current TkDisplay structure cannot be + * introspected from here, pass a NULL pointer to BitmapInit, + * which will know to initialize only the data in the + * ThreadSpecificData structure for the current thread. + */ - if (!initialized) { - BitmapInit(); + if (!tsdPtr->initialized) { + BitmapInit((TkDisplay *) NULL); } - predefHashPtr = Tcl_CreateHashEntry(&tkPredefBitmapTable, name, &new); + predefHashPtr = Tcl_CreateHashEntry(&tsdPtr->predefBitmapTable, + name, &new); if (!new) { Tcl_AppendResult(interp, "bitmap \"", name, "\" is already defined", (char *) NULL); @@ -338,29 +518,27 @@ Tk_DefineBitmap(interp, name, source, width, height) *-------------------------------------------------------------- */ -Tk_Uid +char * Tk_NameOfBitmap(display, bitmap) Display *display; /* Display for which bitmap was * allocated. */ Pixmap bitmap; /* Bitmap whose name is wanted. */ { - IdKey idKey; Tcl_HashEntry *idHashPtr; TkBitmap *bitmapPtr; + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { + if (dispPtr == NULL || !dispPtr->bitmapInit) { unknown: panic("Tk_NameOfBitmap received unknown bitmap argument"); } - idKey.display = display; - idKey.pixmap = bitmap; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); if (idHashPtr == NULL) { goto unknown; } bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); - return ((NameKey *) bitmapPtr->hashPtr->key.words)->name; + return bitmapPtr->nameHashPtr->key.string; } /* @@ -390,18 +568,16 @@ Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr) int *widthPtr; /* Store bitmap width here. */ int *heightPtr; /* Store bitmap height here. */ { - IdKey idKey; Tcl_HashEntry *idHashPtr; TkBitmap *bitmapPtr; + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { + if (!dispPtr->bitmapInit) { unknownBitmap: panic("Tk_SizeOfBitmap received unknown bitmap argument"); } - idKey.display = display; - idKey.pixmap = bitmap; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); if (idHashPtr == NULL) { goto unknownBitmap; } @@ -413,6 +589,56 @@ Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr) /* *---------------------------------------------------------------------- * + * FreeBitmap -- + * + * This procedure does all the work of releasing a bitmap allocated by + * Tk_GetBitmap or TkGetBitmapFromData. It is invoked by both + * Tk_FreeBitmap and Tk_FreeBitmapFromObj + * + * Results: + * None. + * + * Side effects: + * The reference count associated with bitmap is decremented, and + * it is officially deallocated if no-one is using it anymore. + * + *---------------------------------------------------------------------- + */ + +static void +FreeBitmap(bitmapPtr) + TkBitmap *bitmapPtr; /* Bitmap to be released. */ +{ + TkBitmap *prevPtr; + + bitmapPtr->resourceRefCount--; + if (bitmapPtr->resourceRefCount > 0) { + return; + } + + Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap); + Tcl_DeleteHashEntry(bitmapPtr->idHashPtr); + prevPtr = (TkBitmap *) Tcl_GetHashValue(bitmapPtr->nameHashPtr); + if (prevPtr == bitmapPtr) { + if (bitmapPtr->nextPtr == NULL) { + Tcl_DeleteHashEntry(bitmapPtr->nameHashPtr); + } else { + Tcl_SetHashValue(bitmapPtr->nameHashPtr, bitmapPtr->nextPtr); + } + } else { + while (prevPtr->nextPtr != bitmapPtr) { + prevPtr = prevPtr->nextPtr; + } + prevPtr->nextPtr = bitmapPtr->nextPtr; + } + if (bitmapPtr->objRefCount == 0) { + ckfree((char *) bitmapPtr); + } +} + +/* + *---------------------------------------------------------------------- + * * Tk_FreeBitmap -- * * This procedure is called to release a bitmap allocated by @@ -435,26 +661,115 @@ Tk_FreeBitmap(display, bitmap) Pixmap bitmap; /* Bitmap to be released. */ { Tcl_HashEntry *idHashPtr; - register TkBitmap *bitmapPtr; - IdKey idKey; + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { + if (!dispPtr->bitmapInit) { panic("Tk_FreeBitmap called before Tk_GetBitmap"); } - idKey.display = display; - idKey.pixmap = bitmap; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap); if (idHashPtr == NULL) { panic("Tk_FreeBitmap received unknown bitmap argument"); } - bitmapPtr = (TkBitmap *) Tcl_GetHashValue(idHashPtr); - bitmapPtr->refCount--; - if (bitmapPtr->refCount == 0) { - Tk_FreePixmap(bitmapPtr->display, bitmapPtr->bitmap); - Tcl_DeleteHashEntry(idHashPtr); - Tcl_DeleteHashEntry(bitmapPtr->hashPtr); - ckfree((char *) bitmapPtr); + FreeBitmap((TkBitmap *) Tcl_GetHashValue(idHashPtr)); +} + +/* + *---------------------------------------------------------------------- + * + * Tk_FreeBitmapFromObj -- + * + * This procedure is called to release a bitmap allocated by + * Tk_AllocBitmapFromObj. It does not throw away the Tcl_Obj *; + * it only gets rid of the hash table entry for this bitmap + * and clears the cached value that is normally stored in the object. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with the bitmap represented by + * objPtr is decremented, and the bitmap is released to X if there are + * no remaining uses for it. + * + *---------------------------------------------------------------------- + */ + +void +Tk_FreeBitmapFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window this bitmap lives in. Needed + * for the display value. */ + Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ +{ + FreeBitmap(GetBitmapFromObj(tkwin, objPtr)); +} + +/* + *--------------------------------------------------------------------------- + * + * FreeBitmapObjProc -- + * + * This proc is called to release an object reference to a bitmap. + * Called when the object's internal rep is released or when + * the cached bitmapPtr needs to be changed. + * + * Results: + * None. + * + * Side effects: + * The object reference count is decremented. When both it + * and the hash ref count go to zero, the color's resources + * are released. + * + *--------------------------------------------------------------------------- + */ + +static void +FreeBitmapObjProc(objPtr) + Tcl_Obj *objPtr; /* The object we are releasing. */ +{ + TkBitmap *bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; + + if (bitmapPtr != NULL) { + bitmapPtr->objRefCount--; + if ((bitmapPtr->objRefCount == 0) + && (bitmapPtr->resourceRefCount == 0)) { + ckfree((char *) bitmapPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; + } +} + +/* + *--------------------------------------------------------------------------- + * + * DupBitmapObjProc -- + * + * When a cached bitmap object is duplicated, this is called to + * update the internal reps. + * + * Results: + * None. + * + * Side effects: + * The color's objRefCount is incremented and the internal rep + * of the copy is set to point to it. + * + *--------------------------------------------------------------------------- + */ + +static void +DupBitmapObjProc(srcObjPtr, dupObjPtr) + Tcl_Obj *srcObjPtr; /* The object we are copying from. */ + Tcl_Obj *dupObjPtr; /* The object we are copying to. */ +{ + TkBitmap *bitmapPtr = (TkBitmap *) srcObjPtr->internalRep.twoPtrValue.ptr1; + + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr; + + if (bitmapPtr != NULL) { + bitmapPtr->objRefCount++; } } @@ -471,7 +786,7 @@ Tk_FreeBitmap(display, bitmap) * The return value is the X identifer for the desired bitmap * (a one-plane Pixmap), unless it couldn't be created properly. * In this case, None is returned and an error message is left in - * interp->result. The caller should never modify the bitmap that + * the interp's result. The caller should never modify the bitmap that * is returned, and should eventually call Tk_FreeBitmap when the * bitmap is no longer needed. * @@ -494,25 +809,24 @@ Tk_GetBitmapFromData(interp, tkwin, source, width, height) { DataKey nameKey; Tcl_HashEntry *dataHashPtr; - Tk_Uid name; int new; - char string[20]; - static int autoNumber = 0; + char string[16 + TCL_INTEGER_SPACE]; + char *name; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - BitmapInit(); - } + BitmapInit(dispPtr); nameKey.source = source; nameKey.width = width; nameKey.height = height; - dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &nameKey, &new); + dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable, + (char *) &nameKey, &new); if (!new) { - name = (Tk_Uid) Tcl_GetHashValue(dataHashPtr); + name = (char *) Tcl_GetHashValue(dataHashPtr); } else { - autoNumber++; - sprintf(string, "_tk%d", autoNumber); - name = Tk_GetUid(string); + dispPtr->bitmapAutoNumber++; + sprintf(string, "_tk%d", dispPtr->bitmapAutoNumber); + name = string; Tcl_SetHashValue(dataHashPtr, name); if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) { Tcl_DeleteHashEntry(dataHashPtr); @@ -525,63 +839,226 @@ Tk_GetBitmapFromData(interp, tkwin, source, width, height) /* *---------------------------------------------------------------------- * - * BitmapInit -- + * Tk_GetBitmapFromObj -- + * + * Returns the bitmap referred to by a Tcl object. The bitmap must + * already have been allocated via a call to Tk_AllocBitmapFromObj + * or Tk_GetBitmap. + * + * Results: + * Returns the Pixmap that matches the tkwin and the string rep + * of objPtr. * - * Initialize the structures used for bitmap management. + * Side effects: + * If the object is not already a bitmap, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +Pixmap +Tk_GetBitmapFromObj(tkwin, objPtr) + Tk_Window tkwin; + Tcl_Obj *objPtr; /* The object from which to get pixels. */ +{ + TkBitmap *bitmapPtr = GetBitmapFromObj(tkwin, objPtr); + return bitmapPtr->bitmap; +} + +/* + *---------------------------------------------------------------------- + * + * GetBitmapFromObj -- + * + * Returns the bitmap referred to by a Tcl object. The bitmap must + * already have been allocated via a call to Tk_AllocBitmapFromObj + * or Tk_GetBitmap. + * + * Results: + * Returns the TkBitmap * that matches the tkwin and the string rep + * of objPtr. + * + * Side effects: + * If the object is not already a bitmap, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +static TkBitmap * +GetBitmapFromObj(tkwin, objPtr) + Tk_Window tkwin; /* Window in which the bitmap will be used. */ + Tcl_Obj *objPtr; /* The object that describes the desired + * bitmap. */ +{ + TkBitmap *bitmapPtr; + Tcl_HashEntry *hashPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + if (objPtr->typePtr != &bitmapObjType) { + InitBitmapObj(objPtr); + } + + bitmapPtr = (TkBitmap *) objPtr->internalRep.twoPtrValue.ptr1; + if (bitmapPtr != NULL) { + if ((bitmapPtr->resourceRefCount > 0) + && (Tk_Display(tkwin) == bitmapPtr->display)) { + return bitmapPtr; + } + hashPtr = bitmapPtr->nameHashPtr; + FreeBitmapObjProc(objPtr); + } else { + hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, + Tcl_GetString(objPtr)); + if (hashPtr == NULL) { + goto error; + } + } + + /* + * At this point we've got a hash table entry, off of which hang + * one or more TkBitmap structures. See if any of them will work. + */ + + for (bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr); + bitmapPtr != NULL; bitmapPtr = bitmapPtr->nextPtr) { + if (Tk_Display(tkwin) == bitmapPtr->display) { + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) bitmapPtr; + bitmapPtr->objRefCount++; + return bitmapPtr; + } + } + + error: + panic("GetBitmapFromObj called with non-existent bitmap!"); + /* + * The following code isn't reached; it's just there to please compilers. + */ + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * InitBitmapObj -- + * + * Bookeeping procedure to change an objPtr to a bitmap type. * * Results: * None. * * Side effects: + * The old internal rep of the object is freed. The internal + * rep is cleared. The final form of the object is set + * by either Tk_AllocBitmapFromObj or GetBitmapFromObj. + * + *---------------------------------------------------------------------- + */ + +static void +InitBitmapObj(objPtr) + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetString(objPtr); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &bitmapObjType; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; +} + +/* + *---------------------------------------------------------------------- + * + * BitmapInit -- + * Initializes hash tables used by this module. Initializes + * tables stored in TkDisplay structure if a TkDisplay pointer + * is passed in. Iinitializes the thread-local data + * in the current thread's ThreadSpecificData structure. + * + * Results: + * None. + * + * Side effects: * Read the code. * *---------------------------------------------------------------------- */ static void -BitmapInit() +BitmapInit(dispPtr) + TkDisplay *dispPtr; /* TkDisplay structure encapsulating + * thread-specific data used by this + * module, or NULL if unavailable. */ { Tcl_Interp *dummy; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + /* + * First initialize the data in the ThreadSpecificData strucuture, + * if needed. + */ - dummy = Tcl_CreateInterp(); - initialized = 1; - Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); - Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int)); - Tcl_InitHashTable(&tkPredefBitmapTable, TCL_ONE_WORD_KEYS); + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + dummy = Tcl_CreateInterp(); + Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS); + + Tk_DefineBitmap(dummy, "error", (char *) error_bits, + error_width, error_height); + Tk_DefineBitmap(dummy, "gray75", (char *) gray75_bits, + gray75_width, gray75_height); + Tk_DefineBitmap(dummy, "gray50", (char *) gray50_bits, + gray50_width, gray50_height); + Tk_DefineBitmap(dummy, "gray25", (char *) gray25_bits, + gray25_width, gray25_height); + Tk_DefineBitmap(dummy, "gray12", (char *) gray12_bits, + gray12_width, gray12_height); + Tk_DefineBitmap(dummy, "hourglass", (char *) hourglass_bits, + hourglass_width, hourglass_height); + Tk_DefineBitmap(dummy, "info", (char *) info_bits, + info_width, info_height); + Tk_DefineBitmap(dummy, "questhead", (char *) questhead_bits, + questhead_width, questhead_height); + Tk_DefineBitmap(dummy, "question", (char *) question_bits, + question_width, question_height); + Tk_DefineBitmap(dummy, "warning", (char *) warning_bits, + warning_width, warning_height); + + TkpDefineNativeBitmaps(); + Tcl_DeleteInterp(dummy); + } /* - * The call below is tricky: can't use sizeof(IdKey) because it - * gets padded with extra unpredictable bytes on some 64-bit - * machines. + * Was a valid TkDisplay pointer passed? If so, initialize the + * Bitmap module tables in that structure. */ - Tcl_InitHashTable(&idTable, (sizeof(Display *) + sizeof(Pixmap)) - /sizeof(int)); - - Tk_DefineBitmap(dummy, Tk_GetUid("error"), (char *) error_bits, - error_width, error_height); - Tk_DefineBitmap(dummy, Tk_GetUid("gray75"), (char *) gray75_bits, - gray75_width, gray75_height); - Tk_DefineBitmap(dummy, Tk_GetUid("gray50"), (char *) gray50_bits, - gray50_width, gray50_height); - Tk_DefineBitmap(dummy, Tk_GetUid("gray25"), (char *) gray25_bits, - gray25_width, gray25_height); - Tk_DefineBitmap(dummy, Tk_GetUid("gray12"), (char *) gray12_bits, - gray12_width, gray12_height); - Tk_DefineBitmap(dummy, Tk_GetUid("hourglass"), (char *) hourglass_bits, - hourglass_width, hourglass_height); - Tk_DefineBitmap(dummy, Tk_GetUid("info"), (char *) info_bits, - info_width, info_height); - Tk_DefineBitmap(dummy, Tk_GetUid("questhead"), (char *) questhead_bits, - questhead_width, questhead_height); - Tk_DefineBitmap(dummy, Tk_GetUid("question"), (char *) question_bits, - question_width, question_height); - Tk_DefineBitmap(dummy, Tk_GetUid("warning"), (char *) warning_bits, - warning_width, warning_height); - - TkpDefineNativeBitmaps(); - - Tcl_DeleteInterp(dummy); + if (dispPtr != NULL) { + dispPtr->bitmapInit = 1; + Tcl_InitHashTable(&dispPtr->bitmapNameTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&dispPtr->bitmapDataTable, sizeof(DataKey) + /sizeof(int)); + + /* + * The call below is tricky: can't use sizeof(IdKey) because it + * gets padded with extra unpredictable bytes on some 64-bit + * machines. + */ + + /* + * The comment above doesn't make sense... + */ + Tcl_InitHashTable(&dispPtr->bitmapIdTable, TCL_ONE_WORD_KEYS); + } } /* @@ -627,4 +1104,82 @@ TkReadBitmapFile(display, d, filename, width_return, height_return, ckfree(data); return BitmapSuccess; + } + +/* + *---------------------------------------------------------------------- + * + * TkDebugBitmap -- + * + * This procedure returns debugging information about a bitmap. + * + * Results: + * The return value is a list with one sublist for each TkBitmap + * corresponding to "name". Each sublist has two elements that + * contain the resourceRefCount and objRefCount fields from the + * TkBitmap structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkDebugBitmap(tkwin, name) + Tk_Window tkwin; /* The window in which the bitmap will be + * used (not currently used). */ + char *name; /* Name of the desired color. */ +{ + TkBitmap *bitmapPtr; + Tcl_HashEntry *hashPtr; + Tcl_Obj *resultPtr, *objPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + resultPtr = Tcl_NewObj(); + hashPtr = Tcl_FindHashEntry(&dispPtr->bitmapNameTable, name); + if (hashPtr != NULL) { + bitmapPtr = (TkBitmap *) Tcl_GetHashValue(hashPtr); + if (bitmapPtr == NULL) { + panic("TkDebugBitmap found empty hash table entry"); + } + for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) { + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(bitmapPtr->resourceRefCount)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(bitmapPtr->objRefCount)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return resultPtr; +} + + +/* + *---------------------------------------------------------------------- + * + * TkGetBitmapPredefTable -- + * This procedure is used by tkMacBitmap.c to access the thread- + * specific predefBitmap table that maps from the names of + * the predefined bitmaps to data associated with those + * bitmaps. It is required because the table is allocated in + * thread-local storage and is not visible outside this file. + + * Results: + * Returns a pointer to the predefined bitmap hash table for + * the current thread. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +Tcl_HashTable * +TkGetBitmapPredefTable() +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + return &tsdPtr->predefBitmapTable; } diff --git a/generic/tkButton.c b/generic/tkButton.c index aea1e58..dce66f9 100644 --- a/generic/tkButton.c +++ b/generic/tkButton.c @@ -3,199 +3,448 @@ * * This module implements a collection of button-like * widgets for the Tk toolkit. The widgets implemented - * include labels, buttons, check buttons, and radio - * buttons. + * include labels, buttons, checkbuttons, and radiobuttons. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkButton.c,v 1.2 1998/09/14 18:23:04 stanton Exp $ + * RCS: @(#) $Id: tkButton.c,v 1.3 1999/04/16 01:51:10 stanton Exp $ */ #include "tkButton.h" #include "default.h" /* - * Class names for buttons, indexed by one of the type values above. + * Class names for buttons, indexed by one of the type values defined + * in tkButton.h. */ static char *classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"}; /* - * The class procedure table for the button widget. + * The following table defines the legal values for the -default option. + * It is used together with the "enum defaultValue" declaration in tkButton.h. */ -static int configFlags[] = {LABEL_MASK, BUTTON_MASK, - CHECK_BUTTON_MASK, RADIO_BUTTON_MASK}; +static char *defaultStrings[] = { + "active", "disabled", "normal", (char *) NULL +}; + +/* + * The following table defines the legal values for the -state option. + * It is used together with the "enum state" declaration in tkButton.h. + */ + +static char *stateStrings[] = { + "active", "disabled", "normal", (char *) NULL +}; /* - * Information used for parsing configuration specs: + * Information used for parsing configuration options. There is a + * separate table for each of the four widget classes. */ -Tk_ConfigSpec tkpButtonConfigSpecs[] = { - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_BUTTON_ACTIVE_BG_COLOR, Tk_Offset(TkButton, activeBorder), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK - |TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_BUTTON_ACTIVE_BG_MONO, Tk_Offset(TkButton, activeBorder), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK - |TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_BUTTON_ACTIVE_FG_COLOR, Tk_Offset(TkButton, activeFg), - BUTTON_MASK|TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_CHKRAD_ACTIVE_FG_COLOR, Tk_Offset(TkButton, activeFg), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_BUTTON_ACTIVE_FG_MONO, Tk_Offset(TkButton, activeFg), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK - |TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", - DEF_BUTTON_ANCHOR, Tk_Offset(TkButton, anchor), ALL_MASK}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_BUTTON_BG_COLOR, Tk_Offset(TkButton, normalBorder), - ALL_MASK | TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_BUTTON_BG_MONO, Tk_Offset(TkButton, normalBorder), - ALL_MASK | TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, ALL_MASK}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, ALL_MASK}, - {TK_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", - DEF_BUTTON_BITMAP, Tk_Offset(TkButton, bitmap), - ALL_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidth), ALL_MASK}, - {TK_CONFIG_STRING, "-command", "command", "Command", - DEF_BUTTON_COMMAND, Tk_Offset(TkButton, command), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_BUTTON_CURSOR, Tk_Offset(TkButton, cursor), - ALL_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_UID, "-default", "default", "Default", - DEF_BUTTON_DEFAULT, Tk_Offset(TkButton, defaultState), BUTTON_MASK}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", +static Tk_OptionSpec labelOptionSpecs[] = { + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), + 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", + DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidthPtr), + Tk_Offset(TkButton, borderWidth), 0, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0}, + {TK_OPTION_STRING, "-height", "height", "Height", + DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0}, + {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkButton, highlightBorder), 0, + (ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_LABEL_HIGHLIGHT_WIDTH, + Tk_Offset(TkButton, highlightWidthPtr), + Tk_Offset(TkButton, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-image", "image", "Image", + DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0}, + {TK_OPTION_PIXELS, "-padx", "padX", "Pad", + DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padXPtr), + Tk_Offset(TkButton, padX), 0, 0, 0}, + {TK_OPTION_PIXELS, "-pady", "padY", "Pad", + DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr), + Tk_Offset(TkButton, padY), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-text", "text", "Text", + DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-underline", "underline", "Underline", + DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0}, + {TK_OPTION_STRING, "-width", "width", "Width", + DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr), + Tk_Offset(TkButton, wrapLength), 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, 0, 0, 0} +}; + +static Tk_OptionSpec buttonOptionSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", + DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), + 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", + DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), + TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), + 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", + DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidthPtr), + Tk_Offset(TkButton, borderWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-command", "command", "Command", + DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-default", "default", "Default", + DEF_BUTTON_DEFAULT, -1, Tk_Offset(TkButton, defaultState), + 0, (ClientData) defaultStrings, 0}, + {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", + "DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR, + -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, + (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0}, + {TK_OPTION_STRING, "-height", "height", "Height", + DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0}, + {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkButton, highlightBorder), 0, + (ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH, + Tk_Offset(TkButton, highlightWidthPtr), + Tk_Offset(TkButton, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-image", "image", "Image", + DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0}, + {TK_OPTION_PIXELS, "-padx", "padX", "Pad", + DEF_BUTTON_PADX, Tk_Offset(TkButton, padXPtr), + Tk_Offset(TkButton, padX), 0, 0, 0}, + {TK_OPTION_PIXELS, "-pady", "padY", "Pad", + DEF_BUTTON_PADY, Tk_Offset(TkButton, padYPtr), + Tk_Offset(TkButton, padY), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-text", "text", "Text", + DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-underline", "underline", "Underline", + DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0}, + {TK_OPTION_STRING, "-width", "width", "Width", + DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr), + Tk_Offset(TkButton, wrapLength), 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} +}; + +static Tk_OptionSpec checkbuttonOptionSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", + DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), + 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", + DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), + TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), + 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", + DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidthPtr), + Tk_Offset(TkButton, borderWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-command", "command", "Command", + DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR, - Tk_Offset(TkButton, disabledFg), BUTTON_MASK|CHECK_BUTTON_MASK - |RADIO_BUTTON_MASK|TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", - "DisabledForeground", DEF_BUTTON_DISABLED_FG_MONO, - Tk_Offset(TkButton, disabledFg), BUTTON_MASK|CHECK_BUTTON_MASK - |RADIO_BUTTON_MASK|TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, ALL_MASK}, - {TK_CONFIG_FONT, "-font", "font", "Font", - DEF_BUTTON_FONT, Tk_Offset(TkButton, tkfont), - ALL_MASK}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_BUTTON_FG, Tk_Offset(TkButton, normalFg), LABEL_MASK|BUTTON_MASK}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_CHKRAD_FG, Tk_Offset(TkButton, normalFg), CHECK_BUTTON_MASK - |RADIO_BUTTON_MASK}, - {TK_CONFIG_STRING, "-height", "height", "Height", - DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightString), ALL_MASK}, - {TK_CONFIG_BORDER, "-highlightbackground", "highlightBackground", - "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG, - Tk_Offset(TkButton, highlightBorder), ALL_MASK}, - {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_BUTTON_HIGHLIGHT, Tk_Offset(TkButton, highlightColorPtr), - ALL_MASK}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", - DEF_LABEL_HIGHLIGHT_WIDTH, Tk_Offset(TkButton, highlightWidth), - LABEL_MASK}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", - DEF_BUTTON_HIGHLIGHT_WIDTH, Tk_Offset(TkButton, highlightWidth), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_STRING, "-image", "image", "Image", - DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imageString), - ALL_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", - DEF_BUTTON_INDICATOR, Tk_Offset(TkButton, indicatorOn), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", - DEF_BUTTON_JUSTIFY, Tk_Offset(TkButton, justify), ALL_MASK}, - {TK_CONFIG_STRING, "-offvalue", "offValue", "Value", - DEF_BUTTON_OFF_VALUE, Tk_Offset(TkButton, offValue), - CHECK_BUTTON_MASK}, - {TK_CONFIG_STRING, "-onvalue", "onValue", "Value", - DEF_BUTTON_ON_VALUE, Tk_Offset(TkButton, onValue), - CHECK_BUTTON_MASK}, - {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", - DEF_BUTTON_PADX, Tk_Offset(TkButton, padX), BUTTON_MASK}, - {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", - DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padX), - LABEL_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", - DEF_BUTTON_PADY, Tk_Offset(TkButton, padY), BUTTON_MASK}, - {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", - DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padY), - LABEL_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_BUTTON_RELIEF, Tk_Offset(TkButton, relief), BUTTON_MASK}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_LABCHKRAD_RELIEF, Tk_Offset(TkButton, relief), - LABEL_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_BORDER, "-selectcolor", "selectColor", "Background", - DEF_BUTTON_SELECT_COLOR, Tk_Offset(TkButton, selectBorder), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_COLOR_ONLY - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_BORDER, "-selectcolor", "selectColor", "Background", - DEF_BUTTON_SELECT_MONO, Tk_Offset(TkButton, selectBorder), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_MONO_ONLY - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-selectimage", "selectImage", "SelectImage", - DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImageString), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_UID, "-state", "state", "State", - DEF_BUTTON_STATE, Tk_Offset(TkButton, state), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocus), - LABEL_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocus), - BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-text", "text", "Text", - DEF_BUTTON_TEXT, Tk_Offset(TkButton, text), ALL_MASK}, - {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", - DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarName), - ALL_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_INT, "-underline", "underline", "Underline", - DEF_BUTTON_UNDERLINE, Tk_Offset(TkButton, underline), ALL_MASK}, - {TK_CONFIG_STRING, "-value", "value", "Value", - DEF_BUTTON_VALUE, Tk_Offset(TkButton, onValue), - RADIO_BUTTON_MASK}, - {TK_CONFIG_STRING, "-variable", "variable", "Variable", - DEF_RADIOBUTTON_VARIABLE, Tk_Offset(TkButton, selVarName), - RADIO_BUTTON_MASK}, - {TK_CONFIG_STRING, "-variable", "variable", "Variable", - DEF_CHECKBUTTON_VARIABLE, Tk_Offset(TkButton, selVarName), - CHECK_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-width", "width", "Width", - DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthString), ALL_MASK}, - {TK_CONFIG_PIXELS, "-wraplength", "wrapLength", "WrapLength", - DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLength), ALL_MASK}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} + -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, + (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0}, + {TK_OPTION_STRING, "-height", "height", "Height", + DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0}, + {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkButton, highlightBorder), 0, + (ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH, + Tk_Offset(TkButton, highlightWidthPtr), + Tk_Offset(TkButton, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-image", "image", "Image", + DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", + DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn), 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0}, + {TK_OPTION_STRING, "-offvalue", "offValue", "Value", + DEF_BUTTON_OFF_VALUE, Tk_Offset(TkButton, offValuePtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-onvalue", "onValue", "Value", + DEF_BUTTON_ON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-padx", "padX", "Pad", + DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padXPtr), + Tk_Offset(TkButton, padX), 0, 0, 0}, + {TK_OPTION_PIXELS, "-pady", "padY", "Pad", + DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr), + Tk_Offset(TkButton, padY), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, + {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background", + DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder), + TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0}, + {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage", + DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-text", "text", "Text", + DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-underline", "underline", "Underline", + DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0}, + {TK_OPTION_STRING, "-variable", "variable", "Variable", + DEF_CHECKBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-width", "width", "Width", + DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr), + Tk_Offset(TkButton, wrapLength), 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} +}; + +static Tk_OptionSpec radiobuttonOptionSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", + DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder), + 0, (ClientData) DEF_BUTTON_ACTIVE_BG_MONO, 0}, + {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", + DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg), + TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_ACTIVE_FG_MONO, 0}, + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder), + 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", + DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_BUTTON_BORDER_WIDTH, Tk_Offset(TkButton, borderWidthPtr), + Tk_Offset(TkButton, borderWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-command", "command", "Command", + DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", + "DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR, + -1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK, + (ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0}, + {TK_OPTION_STRING, "-height", "height", "Height", + DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0}, + {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkButton, highlightBorder), 0, + (ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_BUTTON_HIGHLIGHT_WIDTH, + Tk_Offset(TkButton, highlightWidthPtr), + Tk_Offset(TkButton, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-image", "image", "Image", + DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", + DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn), + 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0}, + {TK_OPTION_PIXELS, "-padx", "padX", "Pad", + DEF_LABCHKRAD_PADX, Tk_Offset(TkButton, padXPtr), + Tk_Offset(TkButton, padX), 0, 0, 0}, + {TK_OPTION_PIXELS, "-pady", "padY", "Pad", + DEF_LABCHKRAD_PADY, Tk_Offset(TkButton, padYPtr), + Tk_Offset(TkButton, padY), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0}, + {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background", + DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder), + TK_OPTION_NULL_OK, (ClientData) DEF_BUTTON_SELECT_MONO, 0}, + {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage", + DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-text", "text", "Text", + DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-underline", "underline", "Underline", + DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0}, + {TK_OPTION_STRING, "-value", "value", "Value", + DEF_BUTTON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0}, + {TK_OPTION_STRING, "-variable", "variable", "Variable", + DEF_RADIOBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1, + 0, 0, 0}, + {TK_OPTION_STRING, "-width", "width", "Width", + DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr), + Tk_Offset(TkButton, wrapLength), 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} }; /* - * String to print out in error messages, identifying options for - * widget commands for different types of labels or buttons: + * The following table maps from one of the type values defined in + * tkButton.h, such as TYPE_LABEL, to the option template for that + * class of widgets. */ -static char *optionStrings[] = { - "cget or configure", - "cget, configure, flash, or invoke", - "cget, configure, deselect, flash, invoke, select, or toggle", - "cget, configure, deselect, flash, invoke, or select" +static Tk_OptionSpec *optionSpecs[] = { + labelOptionSpecs, + buttonOptionSpecs, + checkbuttonOptionSpecs, + radiobuttonOptionSpecs +}; + +/* + * The following tables define the widget commands supported by + * each of the classes, and map the indexes into the string tables + * into a single enumerated type used to dispatch the widget command. + */ + +static char *commandNames[][8] = { + {"cget", "configure", (char *) NULL}, + {"cget", "configure", "flash", "invoke", (char *) NULL}, + {"cget", "configure", "deselect", "flash", "invoke", "select", + "toggle", (char *) NULL}, + {"cget", "configure", "deselect", "flash", "invoke", "select", + (char *) NULL} +}; +enum command { + COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH, + COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE +}; +static enum command map[][8] = { + {COMMAND_CGET, COMMAND_CONFIGURE}, + {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_FLASH, COMMAND_INVOKE}, + {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH, + COMMAND_INVOKE, COMMAND_SELECT, COMMAND_TOGGLE}, + {COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DESELECT, COMMAND_FLASH, + COMMAND_INVOKE, COMMAND_SELECT} }; /* @@ -205,8 +454,8 @@ static char *optionStrings[] = { static void ButtonCmdDeletedProc _ANSI_ARGS_(( ClientData clientData)); static int ButtonCreate _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv, - int type)); + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[], int type)); static void ButtonEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static void ButtonImageProc _ANSI_ARGS_((ClientData clientData, @@ -221,13 +470,13 @@ static char * ButtonTextVarProc _ANSI_ARGS_((ClientData clientData, static char * ButtonVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); -static int ButtonWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +static int ButtonWidgetObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static int ConfigureButton _ANSI_ARGS_((Tcl_Interp *interp, - TkButton *butPtr, int argc, char **argv, - int flags)); + TkButton *butPtr, int objc, + Tcl_Obj *CONST objv[])); static void DestroyButton _ANSI_ARGS_((TkButton *butPtr)); - /* *-------------------------------------------------------------- @@ -249,47 +498,43 @@ static void DestroyButton _ANSI_ARGS_((TkButton *butPtr)); */ int -Tk_ButtonCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_ButtonObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - return ButtonCreate(clientData, interp, argc, argv, TYPE_BUTTON); + return ButtonCreate(clientData, interp, objc, objv, TYPE_BUTTON); } int -Tk_CheckbuttonCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_CheckbuttonObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - return ButtonCreate(clientData, interp, argc, argv, TYPE_CHECK_BUTTON); + return ButtonCreate(clientData, interp, objc, objv, TYPE_CHECK_BUTTON); } int -Tk_LabelCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_LabelObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - return ButtonCreate(clientData, interp, argc, argv, TYPE_LABEL); + return ButtonCreate(clientData, interp, objc, objv, TYPE_LABEL); } int -Tk_RadiobuttonCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_RadiobuttonObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - return ButtonCreate(clientData, interp, argc, argv, TYPE_RADIO_BUTTON); + return ButtonCreate(clientData, interp, objc, objv, TYPE_RADIO_BUTTON); } /* @@ -311,23 +556,42 @@ Tk_RadiobuttonCmd(clientData, interp, argc, argv) */ static int -ButtonCreate(clientData, interp, argc, argv, type) - ClientData clientData; /* Main window associated with - * interpreter. */ +ButtonCreate(clientData, interp, objc, objv, type) + ClientData clientData; /* Option table for this widget class, or + * NULL if not created yet. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ int type; /* Type of button to create: TYPE_LABEL, * TYPE_BUTTON, TYPE_CHECK_BUTTON, or * TYPE_RADIO_BUTTON. */ { - register TkButton *butPtr; - Tk_Window tkwin = (Tk_Window) clientData; - Tk_Window new; + TkButton *butPtr; + Tk_OptionTable optionTable; + Tk_Window tkwin; + + optionTable = (Tk_OptionTable) clientData; + if (optionTable == NULL) { + Tcl_CmdInfo info; + char *name; + + /* + * We haven't created the option table for this widget class + * yet. Do it now and save the table as the clientData for + * the command, so we'll have access to it in future + * invocations of the command. + */ - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + TkpButtonSetDefaults(optionSpecs[type]); + optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); + name = Tcl_GetString(objv[0]); + Tcl_GetCommandInfo(interp, name, &info); + info.objClientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, name, &info); + } + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } @@ -335,39 +599,43 @@ ButtonCreate(clientData, interp, argc, argv, type) * Create the new window. */ - new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); - if (new == NULL) { + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetString(objv[1]), (char *) NULL); + if (tkwin == NULL) { return TCL_ERROR; } - Tk_SetClass(new, classNames[type]); - butPtr = TkpCreateButton(new); + Tk_SetClass(tkwin, classNames[type]); + butPtr = TkpCreateButton(tkwin); - TkSetClassProcs(new, &tkpButtonProcs, (ClientData) butPtr); + TkSetClassProcs(tkwin, &tkpButtonProcs, (ClientData) butPtr); /* * Initialize the data structure for the button. */ - butPtr->tkwin = new; - butPtr->display = Tk_Display(new); - butPtr->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(butPtr->tkwin), - ButtonWidgetCmd, (ClientData) butPtr, ButtonCmdDeletedProc); + butPtr->tkwin = tkwin; + butPtr->display = Tk_Display(tkwin); butPtr->interp = interp; + butPtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), + ButtonWidgetObjCmd, (ClientData) butPtr, ButtonCmdDeletedProc); butPtr->type = type; - butPtr->text = NULL; + butPtr->optionTable = optionTable; + butPtr->textPtr = NULL; butPtr->underline = -1; - butPtr->textVarName = NULL; + butPtr->textVarNamePtr = NULL; butPtr->bitmap = None; - butPtr->imageString = NULL; + butPtr->imagePtr = NULL; butPtr->image = NULL; - butPtr->selectImageString = NULL; + butPtr->selectImagePtr = NULL; butPtr->selectImage = NULL; - butPtr->state = tkNormalUid; + butPtr->state = STATE_NORMAL; butPtr->normalBorder = NULL; butPtr->activeBorder = NULL; + butPtr->borderWidthPtr = NULL; butPtr->borderWidth = 0; butPtr->relief = TK_RELIEF_FLAT; + butPtr->highlightWidthPtr = NULL; butPtr->highlightWidth = 0; butPtr->highlightBorder = NULL; butPtr->highlightColorPtr = NULL; @@ -378,43 +646,53 @@ ButtonCreate(clientData, interp, argc, argv, type) butPtr->disabledFg = NULL; butPtr->normalTextGC = None; butPtr->activeTextGC = None; - butPtr->gray = None; butPtr->disabledGC = None; + butPtr->gray = None; butPtr->copyGC = None; - butPtr->widthString = NULL; - butPtr->heightString = NULL; + butPtr->widthPtr = NULL; butPtr->width = 0; + butPtr->heightPtr = NULL; butPtr->height = 0; + butPtr->wrapLengthPtr = NULL; butPtr->wrapLength = 0; + butPtr->padXPtr = NULL; butPtr->padX = 0; + butPtr->padYPtr = NULL; butPtr->padY = 0; butPtr->anchor = TK_ANCHOR_CENTER; butPtr->justify = TK_JUSTIFY_CENTER; - butPtr->textLayout = NULL; butPtr->indicatorOn = 0; butPtr->selectBorder = NULL; + butPtr->textWidth = 0; + butPtr->textHeight = 0; + butPtr->textLayout = NULL; butPtr->indicatorSpace = 0; butPtr->indicatorDiameter = 0; - butPtr->defaultState = tkDisabledUid; - butPtr->selVarName = NULL; - butPtr->onValue = NULL; - butPtr->offValue = NULL; + butPtr->defaultState = DEFAULT_DISABLED; + butPtr->selVarNamePtr = NULL; + butPtr->onValuePtr = NULL; + butPtr->offValuePtr = NULL; butPtr->cursor = None; - butPtr->command = NULL; - butPtr->takeFocus = NULL; + butPtr->takeFocusPtr = NULL; + butPtr->commandPtr = NULL; butPtr->flags = 0; Tk_CreateEventHandler(butPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, ButtonEventProc, (ClientData) butPtr); - if (ConfigureButton(interp, butPtr, argc - 2, argv + 2, - configFlags[type]) != TCL_OK) { + if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin) + != TCL_OK) { + Tk_DestroyWindow(butPtr->tkwin); + return TCL_ERROR; + } + if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) { Tk_DestroyWindow(butPtr->tkwin); return TCL_ERROR; } - interp->result = Tk_PathName(butPtr->tkwin); + Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(butPtr->tkwin), + -1); return TCL_OK; } @@ -437,147 +715,155 @@ ButtonCreate(clientData, interp, argc, argv, type) */ static int -ButtonWidgetCmd(clientData, interp, argc, argv) +ButtonWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about button widget. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - register TkButton *butPtr = (TkButton *) clientData; - int result = TCL_OK; - size_t length; - int c; - - if (argc < 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s option ?arg arg ...?\"", - argv[0]); + TkButton *butPtr = (TkButton *) clientData; + int index; + int result; + Tcl_Obj *objPtr; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } + result = Tcl_GetIndexFromObj(interp, objv[1], commandNames[butPtr->type], + "option", 0, &index); + if (result != TCL_OK) { + return result; + } Tcl_Preserve((ClientData) butPtr); - c = argv[1][0]; - length = strlen(argv[1]); - - if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - goto error; - } - result = Tk_ConfigureValue(interp, butPtr->tkwin, tkpButtonConfigSpecs, - (char *) butPtr, argv[2], configFlags[butPtr->type]); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, butPtr->tkwin, - tkpButtonConfigSpecs, (char *) butPtr, (char *) NULL, - configFlags[butPtr->type]); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, butPtr->tkwin, - tkpButtonConfigSpecs, (char *) butPtr, argv[2], - configFlags[butPtr->type]); - } else { - result = ConfigureButton(interp, butPtr, argc-2, argv+2, - configFlags[butPtr->type] | TK_CONFIG_ARGV_ONLY); - } - } else if ((c == 'd') && (strncmp(argv[1], "deselect", length) == 0) - && (butPtr->type >= TYPE_CHECK_BUTTON)) { - if (argc > 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s deselect\"", - argv[0]); - goto error; - } - if (butPtr->type == TYPE_CHECK_BUTTON) { - if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->offValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + + switch (map[butPtr->type][index]) { + case COMMAND_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); + goto error; } - } else if (butPtr->flags & SELECTED) { - if (Tcl_SetVar(interp, butPtr->selVarName, "", - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; - }; - } - } else if ((c == 'f') && (strncmp(argv[1], "flash", length) == 0) - && (butPtr->type != TYPE_LABEL)) { - int i; - - if (argc > 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s flash\"", - argv[0]); - goto error; - } - if (butPtr->state != tkDisabledUid) { - for (i = 0; i < 4; i++) { - butPtr->state = (butPtr->state == tkNormalUid) - ? tkActiveUid : tkNormalUid; - Tk_SetBackgroundFromBorder(butPtr->tkwin, - (butPtr->state == tkActiveUid) ? butPtr->activeBorder - : butPtr->normalBorder); - TkpDisplayButton((ClientData) butPtr); - - /* - * Special note: must cancel any existing idle handler - * for TkpDisplayButton; it's no longer needed, and TkpDisplayButton - * cleared the REDRAW_PENDING flag. - */ - - Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); - XFlush(butPtr->display); - Tcl_Sleep(50); + objPtr = Tk_GetOptionValue(interp, (char *) butPtr, + butPtr->optionTable, objv[2], butPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); } + break; } - } else if ((c == 'i') && (strncmp(argv[1], "invoke", length) == 0) - && (butPtr->type > TYPE_LABEL)) { - if (argc > 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s invoke\"", - argv[0]); - goto error; + + case COMMAND_CONFIGURE: { + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) butPtr, + butPtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + butPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + } else { + result = ConfigureButton(interp, butPtr, objc-2, objv+2); + } + break; } - if (butPtr->state != tkDisabledUid) { - result = TkInvokeButton(butPtr); + + case COMMAND_DESELECT: { + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "deselect"); + goto error; + } + if (butPtr->type == TYPE_CHECK_BUTTON) { + if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL, + butPtr->offValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + goto error; + } + } else if (butPtr->flags & SELECTED) { + if (Tcl_ObjSetVar2(interp, + butPtr->selVarNamePtr, NULL, Tcl_NewObj(), + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + goto error; + } + } + break; } - } else if ((c == 's') && (strncmp(argv[1], "select", length) == 0) - && (butPtr->type >= TYPE_CHECK_BUTTON)) { - if (argc > 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s select\"", - argv[0]); - goto error; + + case COMMAND_FLASH: { + int i; + + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "flash"); + goto error; + } + if (butPtr->state != STATE_DISABLED) { + for (i = 0; i < 4; i++) { + if (butPtr->state == STATE_NORMAL) { + butPtr->state = STATE_ACTIVE; + Tk_SetBackgroundFromBorder(butPtr->tkwin, + butPtr->activeBorder); + } else { + butPtr->state = STATE_NORMAL; + Tk_SetBackgroundFromBorder(butPtr->tkwin, + butPtr->normalBorder); + } + TkpDisplayButton((ClientData) butPtr); + + /* + * Special note: must cancel any existing idle handler + * for TkpDisplayButton; it's no longer needed, and + * TkpDisplayButton cleared the REDRAW_PENDING flag. + */ + + Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); + XFlush(butPtr->display); + Tcl_Sleep(50); + } + } + break; } - if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->onValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + + case COMMAND_INVOKE: { + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "invoke"); + goto error; + } + if (butPtr->state != STATE_DISABLED) { + result = TkInvokeButton(butPtr); + } + break; } - } else if ((c == 't') && (strncmp(argv[1], "toggle", length) == 0) - && (length >= 2) && (butPtr->type == TYPE_CHECK_BUTTON)) { - if (argc > 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s toggle\"", - argv[0]); - goto error; + + case COMMAND_SELECT: { + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "select"); + goto error; + } + if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL, + butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + goto error; + } + break; } - if (butPtr->flags & SELECTED) { - if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->offValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + + case COMMAND_TOGGLE: { + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "toggle"); + goto error; } - } else { - if (Tcl_SetVar(interp, butPtr->selVarName, butPtr->onValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + if (Tcl_ObjSetVar2(interp, butPtr->selVarNamePtr, NULL, + (butPtr->flags & SELECTED) ? butPtr->offValuePtr + : butPtr->onValuePtr, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + goto error; } + break; } - } else { - sprintf(interp->result, - "bad option \"%.50s\": must be %s", argv[1], - optionStrings[butPtr->type]); - goto error; } Tcl_Release((ClientData) butPtr); return result; @@ -592,15 +878,14 @@ ButtonWidgetCmd(clientData, interp, argc, argv) * * DestroyButton -- * - * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release - * to clean up the internal structure of a button at a safe time - * (when no-one is using it anymore). + * This procedure is invoked by ButtonEventProc to free all the + * resources of a button and clean up its state. * * Results: * None. * * Side effects: - * Everything associated with the widget is freed up. + * Everything associated with the widget is freed. * *---------------------------------------------------------------------- */ @@ -609,14 +894,22 @@ static void DestroyButton(butPtr) TkButton *butPtr; /* Info about button widget. */ { + TkpDestroyButton(butPtr); + + butPtr->flags |= BUTTON_DELETED; + if (butPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); + } + /* * Free up all the stuff that requires special handling, then * let Tk_FreeOptions handle all the standard option-related * stuff. */ - if (butPtr->textVarName != NULL) { - Tcl_UntraceVar(butPtr->interp, butPtr->textVarName, + Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd); + if (butPtr->textVarNamePtr != NULL) { + Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->textVarNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, (ClientData) butPtr); } @@ -632,24 +925,27 @@ DestroyButton(butPtr) if (butPtr->activeTextGC != None) { Tk_FreeGC(butPtr->display, butPtr->activeTextGC); } - if (butPtr->gray != None) { - Tk_FreeBitmap(butPtr->display, butPtr->gray); - } if (butPtr->disabledGC != None) { Tk_FreeGC(butPtr->display, butPtr->disabledGC); } + if (butPtr->gray != None) { + Tk_FreeBitmap(butPtr->display, butPtr->gray); + } if (butPtr->copyGC != None) { Tk_FreeGC(butPtr->display, butPtr->copyGC); } - if (butPtr->selVarName != NULL) { - Tcl_UntraceVar(butPtr->interp, butPtr->selVarName, + if (butPtr->textLayout != NULL) { + Tk_FreeTextLayout(butPtr->textLayout); + } + if (butPtr->selVarNamePtr != NULL) { + Tcl_UntraceVar(butPtr->interp, Tcl_GetString(butPtr->selVarNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonVarProc, (ClientData) butPtr); } - Tk_FreeTextLayout(butPtr->textLayout); - Tk_FreeOptions(tkpButtonConfigSpecs, (char *) butPtr, butPtr->display, - configFlags[butPtr->type]); - Tcl_EventuallyFree((ClientData)butPtr, TCL_DYNAMIC); + Tk_FreeConfigOptions((char *) butPtr, butPtr->optionTable, + butPtr->tkwin); + butPtr->tkwin = NULL; + Tcl_EventuallyFree((ClientData) butPtr, TCL_DYNAMIC); } /* @@ -657,13 +953,12 @@ DestroyButton(butPtr) * * ConfigureButton -- * - * This procedure is called to process an argv/argc list, plus - * the Tk option database, in order to configure (or - * reconfigure) a button widget. + * This procedure is called to process an objc/objv list to set + * configuration options for a button widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then an error message is left in interp's result. * * Side effects: * Configuration information, such as text string, colors, font, @@ -674,199 +969,244 @@ DestroyButton(butPtr) */ static int -ConfigureButton(interp, butPtr, argc, argv, flags) +ConfigureButton(interp, butPtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ register TkButton *butPtr; /* Information about widget; may or may * not already have values for some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Flags to pass to Tk_ConfigureWidget. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { + Tk_SavedOptions savedOptions; + Tcl_Obj *errorResult = NULL; + int error; Tk_Image image; /* * Eliminate any existing trace on variables monitored by the button. */ - if (butPtr->textVarName != NULL) { - Tcl_UntraceVar(interp, butPtr->textVarName, + if (butPtr->textVarNamePtr != NULL) { + Tcl_UntraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, (ClientData) butPtr); } - if (butPtr->selVarName != NULL) { - Tcl_UntraceVar(interp, butPtr->selVarName, + if (butPtr->selVarNamePtr != NULL) { + Tcl_UntraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonVarProc, (ClientData) butPtr); } - - - if (Tk_ConfigureWidget(interp, butPtr->tkwin, tkpButtonConfigSpecs, - argc, argv, (char *) butPtr, flags) != TCL_OK) { - return TCL_ERROR; - } - /* - * A few options need special processing, such as setting the - * background from a 3-D border, or filling in complicated - * defaults that couldn't be specified to Tk_ConfigureWidget. + * The following loop is potentially executed twice. During the + * first pass configuration options get set to their new values. + * If there is an error in this pass, we execute a second pass + * to restore all the options to their previous values. */ - if ((butPtr->state == tkActiveUid) && !Tk_StrictMotif(butPtr->tkwin)) { - Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->activeBorder); - } else { - Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->normalBorder); - if ((butPtr->state != tkNormalUid) && (butPtr->state != tkActiveUid) - && (butPtr->state != tkDisabledUid)) { - Tcl_AppendResult(interp, "bad state value \"", butPtr->state, - "\": must be normal, active, or disabled", (char *) NULL); - butPtr->state = tkNormalUid; - return TCL_ERROR; - } - } + for (error = 0; error <= 1; error++) { + if (!error) { + /* + * First pass: set options to new values. + */ - if ((butPtr->defaultState != tkActiveUid) - && (butPtr->defaultState != tkDisabledUid) - && (butPtr->defaultState != tkNormalUid)) { - Tcl_AppendResult(interp, "bad -default value \"", butPtr->defaultState, - "\": must be normal, active, or disabled", (char *) NULL); - butPtr->defaultState = tkDisabledUid; - return TCL_ERROR; - } + if (Tk_SetOptions(interp, (char *) butPtr, + butPtr->optionTable, objc, objv, + butPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) { + continue; + } + } else { + /* + * Second pass: restore options to old values. + */ - if (butPtr->highlightWidth < 0) { - butPtr->highlightWidth = 0; - } + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); + } - if (butPtr->padX < 0) { - butPtr->padX = 0; - } - if (butPtr->padY < 0) { - butPtr->padY = 0; - } + /* + * A few options need special processing, such as setting the + * background from a 3-D border, or filling in complicated + * defaults that couldn't be specified to Tk_SetOptions. + */ - if (butPtr->type >= TYPE_CHECK_BUTTON) { - char *value; + if ((butPtr->state == STATE_ACTIVE) + && !Tk_StrictMotif(butPtr->tkwin)) { + Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->activeBorder); + } else { + Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->normalBorder); + } + if (butPtr->borderWidth < 0) { + butPtr->borderWidth = 0; + } + if (butPtr->highlightWidth < 0) { + butPtr->highlightWidth = 0; + } + if (butPtr->padX < 0) { + butPtr->padX = 0; + } + if (butPtr->padY < 0) { + butPtr->padY = 0; + } - if (butPtr->selVarName == NULL) { - butPtr->selVarName = (char *) ckalloc((unsigned) - (strlen(Tk_Name(butPtr->tkwin)) + 1)); - strcpy(butPtr->selVarName, Tk_Name(butPtr->tkwin)); + if (butPtr->type >= TYPE_CHECK_BUTTON) { + Tcl_Obj *valuePtr, *namePtr; + + if (butPtr->selVarNamePtr == NULL) { + butPtr->selVarNamePtr = Tcl_NewStringObj( + Tk_Name(butPtr->tkwin), -1); + Tcl_IncrRefCount(butPtr->selVarNamePtr); + } + namePtr = butPtr->selVarNamePtr; + + /* + * Select the button if the associated variable has the + * appropriate value, initialize the variable if it doesn't + * exist, then set a trace on the variable to monitor future + * changes to its value. + */ + + valuePtr = Tcl_ObjGetVar2(interp, namePtr, NULL, TCL_GLOBAL_ONLY); + butPtr->flags &= ~SELECTED; + if (valuePtr != NULL) { + if (strcmp(Tcl_GetString(valuePtr), + Tcl_GetString(butPtr->onValuePtr)) == 0) { + butPtr->flags |= SELECTED; + } + } else { + if (Tcl_ObjSetVar2(interp, namePtr, NULL, + (butPtr->type == TYPE_CHECK_BUTTON) + ? butPtr->offValuePtr : Tcl_NewObj(), + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + continue; + } + } } /* - * Select the button if the associated variable has the - * appropriate value, initialize the variable if it doesn't - * exist, then set a trace on the variable to monitor future - * changes to its value. + * Get the images for the widget, if there are any. Allocate the + * new images before freeing the old ones, so that the reference + * counts don't go to zero and cause image data to be discarded. */ - - value = Tcl_GetVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY); - butPtr->flags &= ~SELECTED; - if (value != NULL) { - if (strcmp(value, butPtr->onValue) == 0) { - butPtr->flags |= SELECTED; + + if (butPtr->imagePtr != NULL) { + image = Tk_GetImage(butPtr->interp, butPtr->tkwin, + Tcl_GetString(butPtr->imagePtr), ButtonImageProc, + (ClientData) butPtr); + if (image == NULL) { + continue; } } else { - if (Tcl_SetVar(interp, butPtr->selVarName, - (butPtr->type == TYPE_CHECK_BUTTON) ? butPtr->offValue : "", - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; + image = NULL; + } + if (butPtr->image != NULL) { + Tk_FreeImage(butPtr->image); + } + butPtr->image = image; + if (butPtr->selectImagePtr != NULL) { + image = Tk_GetImage(butPtr->interp, butPtr->tkwin, + Tcl_GetString(butPtr->selectImagePtr), + ButtonSelectImageProc, (ClientData) butPtr); + if (image == NULL) { + continue; } + } else { + image = NULL; } - Tcl_TraceVar(interp, butPtr->selVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ButtonVarProc, (ClientData) butPtr); - } - - /* - * Get the images for the widget, if there are any. Allocate the - * new images before freeing the old ones, so that the reference - * counts don't go to zero and cause image data to be discarded. - */ - - if (butPtr->imageString != NULL) { - image = Tk_GetImage(butPtr->interp, butPtr->tkwin, - butPtr->imageString, ButtonImageProc, (ClientData) butPtr); - if (image == NULL) { - return TCL_ERROR; + if (butPtr->selectImage != NULL) { + Tk_FreeImage(butPtr->selectImage); } - } else { - image = NULL; - } - if (butPtr->image != NULL) { - Tk_FreeImage(butPtr->image); - } - butPtr->image = image; - if (butPtr->selectImageString != NULL) { - image = Tk_GetImage(butPtr->interp, butPtr->tkwin, - butPtr->selectImageString, ButtonSelectImageProc, - (ClientData) butPtr); - if (image == NULL) { - return TCL_ERROR; + butPtr->selectImage = image; + + if ((butPtr->imagePtr == NULL) && (butPtr->bitmap == None) + && (butPtr->textVarNamePtr != NULL)) { + /* + * The button must display the value of a variable: set up a trace + * on the variable's value, create the variable if it doesn't + * exist, and fetch its current value. + */ + + Tcl_Obj *valuePtr, *namePtr; + + namePtr = butPtr->textVarNamePtr; + valuePtr = Tcl_ObjGetVar2(interp, namePtr, NULL, TCL_GLOBAL_ONLY); + if (valuePtr == NULL) { + if (Tcl_ObjSetVar2(interp, namePtr, NULL, butPtr->textPtr, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { + continue; + } + } else { + if (butPtr->textPtr != NULL) { + Tcl_DecrRefCount(butPtr->textPtr); + } + butPtr->textPtr = valuePtr; + Tcl_IncrRefCount(butPtr->textPtr); + } } - } else { - image = NULL; - } - if (butPtr->selectImage != NULL) { - Tk_FreeImage(butPtr->selectImage); - } - butPtr->selectImage = image; - - if ((butPtr->image == NULL) && (butPtr->bitmap == None) - && (butPtr->textVarName != NULL)) { - /* - * The button must display the value of a variable: set up a trace - * on the variable's value, create the variable if it doesn't - * exist, and fetch its current value. - */ - - char *value; - - value = Tcl_GetVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY); - if (value == NULL) { - if (Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; + + if ((butPtr->bitmap != None) || (butPtr->imagePtr != NULL)) { + /* + * The button must display the contents of an image or + * bitmap. + */ + + if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->widthPtr, + &butPtr->width) != TCL_OK) { + widthError: + Tcl_AddErrorInfo(interp, "\n (processing -width option)"); + continue; + } + if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->heightPtr, + &butPtr->height) != TCL_OK) { + heightError: + Tcl_AddErrorInfo(interp, "\n (processing -height option)"); + continue; } } else { - if (butPtr->text != NULL) { - ckfree(butPtr->text); + /* + * The button displays an ordinary text string. + */ + + if (Tcl_GetIntFromObj(interp, butPtr->widthPtr, &butPtr->width) + != TCL_OK) { + goto widthError; + } + if (Tcl_GetIntFromObj(interp, butPtr->heightPtr, &butPtr->height) + != TCL_OK) { + goto heightError; } - butPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); - strcpy(butPtr->text, value); } - Tcl_TraceVar(interp, butPtr->textVarName, + break; + } + if (!error) { + Tk_FreeSavedOptions(&savedOptions); + } + + /* + * Reestablish the variable traces, if they're needed. + */ + + if (butPtr->textVarNamePtr != NULL) { + Tcl_TraceVar(interp, Tcl_GetString(butPtr->textVarNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, (ClientData) butPtr); } - - if ((butPtr->bitmap != None) || (butPtr->image != NULL)) { - if (Tk_GetPixels(interp, butPtr->tkwin, butPtr->widthString, - &butPtr->width) != TCL_OK) { - widthError: - Tcl_AddErrorInfo(interp, "\n (processing -width option)"); - return TCL_ERROR; - } - if (Tk_GetPixels(interp, butPtr->tkwin, butPtr->heightString, - &butPtr->height) != TCL_OK) { - heightError: - Tcl_AddErrorInfo(interp, "\n (processing -height option)"); - return TCL_ERROR; - } - } else { - if (Tcl_GetInt(interp, butPtr->widthString, &butPtr->width) - != TCL_OK) { - goto widthError; - } - if (Tcl_GetInt(interp, butPtr->heightString, &butPtr->height) - != TCL_OK) { - goto heightError; - } + if (butPtr->selVarNamePtr != NULL) { + Tcl_TraceVar(interp, Tcl_GetString(butPtr->selVarNamePtr), + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, (ClientData) butPtr); } TkButtonWorldChanged((ClientData) butPtr); - return TCL_OK; + if (error) { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); + return TCL_ERROR; + } else { + return TCL_OK; + } } /* @@ -921,7 +1261,6 @@ TkButtonWorldChanged(instanceData) butPtr->normalTextGC = newGC; if (butPtr->activeFg != NULL) { - gcValues.font = Tk_FontId(butPtr->tkfont); gcValues.foreground = butPtr->activeFg->pixel; gcValues.background = Tk_3DBorderColor(butPtr->activeBorder)->pixel; mask = GCForeground | GCBackground | GCFont; @@ -933,17 +1272,15 @@ TkButtonWorldChanged(instanceData) } if (butPtr->type != TYPE_LABEL) { - gcValues.font = Tk_FontId(butPtr->tkfont); gcValues.background = Tk_3DBorderColor(butPtr->normalBorder)->pixel; - if ((butPtr->disabledFg != NULL) && (butPtr->imageString == NULL)) { + if ((butPtr->disabledFg != NULL) && (butPtr->imagePtr == NULL)) { gcValues.foreground = butPtr->disabledFg->pixel; mask = GCForeground | GCBackground | GCFont; } else { gcValues.foreground = gcValues.background; mask = GCForeground; if (butPtr->gray == None) { - butPtr->gray = Tk_GetBitmap(NULL, butPtr->tkwin, - Tk_GetUid("gray50")); + butPtr->gray = Tk_GetBitmap(NULL, butPtr->tkwin, "gray50"); } if (butPtr->gray != None) { gcValues.fill_style = FillStippled; @@ -1008,14 +1345,6 @@ ButtonEventProc(clientData, eventPtr) goto redraw; } else if (eventPtr->type == DestroyNotify) { - TkpDestroyButton(butPtr); - if (butPtr->tkwin != NULL) { - butPtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(butPtr->interp, butPtr->widgetCmd); - } - if (butPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayButton, (ClientData) butPtr); - } DestroyButton(butPtr); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { @@ -1064,18 +1393,16 @@ ButtonCmdDeletedProc(clientData) ClientData clientData; /* Pointer to widget record for widget. */ { TkButton *butPtr = (TkButton *) clientData; - Tk_Window tkwin = butPtr->tkwin; /* * This procedure could be invoked either because the window was - * destroyed and the command was then deleted (in which case tkwin - * is NULL) or because the command was deleted, and then this procedure - * destroys the widget. + * destroyed and the command was then deleted or because the command + * was deleted, and then this procedure destroys the widget. The + * BUTTON_DELETED flag distinguishes these cases. */ - if (tkwin != NULL) { - butPtr->tkwin = NULL; - Tk_DestroyWindow(tkwin); + if (!(butPtr->flags & BUTTON_DELETED)) { + Tk_DestroyWindow(butPtr->tkwin); } } @@ -1091,7 +1418,7 @@ ButtonCmdDeletedProc(clientData) * * Results: * A standard Tcl return value. Information is also left in - * interp->result. + * the interp's result. * * Side effects: * Depends on the button and its associated command. @@ -1101,28 +1428,34 @@ ButtonCmdDeletedProc(clientData) int TkInvokeButton(butPtr) - register TkButton *butPtr; /* Information about button. */ + TkButton *butPtr; /* Information about button. */ { + Tcl_Obj *namePtr = butPtr->selVarNamePtr; + if (butPtr->type == TYPE_CHECK_BUTTON) { if (butPtr->flags & SELECTED) { - if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->offValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + if (Tcl_ObjSetVar2(butPtr->interp, namePtr, NULL, + butPtr->offValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { return TCL_ERROR; } } else { - if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->onValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + if (Tcl_ObjSetVar2(butPtr->interp, namePtr, NULL, + butPtr->onValuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { return TCL_ERROR; } } } else if (butPtr->type == TYPE_RADIO_BUTTON) { - if (Tcl_SetVar(butPtr->interp, butPtr->selVarName, butPtr->onValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + if (Tcl_ObjSetVar2(butPtr->interp, namePtr, NULL, butPtr->onValuePtr, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) { return TCL_ERROR; } } - if ((butPtr->type != TYPE_LABEL) && (butPtr->command != NULL)) { - return TkCopyAndGlobalEval(butPtr->interp, butPtr->command); + if ((butPtr->type != TYPE_LABEL) && (butPtr->commandPtr != NULL)) { + return Tcl_EvalObjEx(butPtr->interp, butPtr->commandPtr, + TCL_EVAL_GLOBAL); } return TCL_OK; } @@ -1156,7 +1489,10 @@ ButtonVarProc(clientData, interp, name1, name2, flags) int flags; /* Information about what happened. */ { register TkButton *butPtr = (TkButton *) clientData; - char *value; + char *name, *value; + Tcl_Obj *valuePtr; + + name = Tcl_GetString(butPtr->selVarNamePtr); /* * If the variable is being unset, then just re-establish the @@ -1166,7 +1502,7 @@ ButtonVarProc(clientData, interp, name1, name2, flags) if (flags & TCL_TRACE_UNSETS) { butPtr->flags &= ~SELECTED; if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_TraceVar(interp, butPtr->selVarName, + Tcl_TraceVar(interp, name, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonVarProc, clientData); } @@ -1178,11 +1514,13 @@ ButtonVarProc(clientData, interp, name1, name2, flags) * the button. */ - value = Tcl_GetVar(interp, butPtr->selVarName, TCL_GLOBAL_ONLY); - if (value == NULL) { + valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY); + if (valuePtr == NULL) { value = ""; + } else { + value = Tcl_GetString(valuePtr); } - if (strcmp(value, butPtr->onValue) == 0) { + if (strcmp(value, Tcl_GetString(butPtr->onValuePtr)) == 0) { if (butPtr->flags & SELECTED) { return (char *) NULL; } @@ -1229,8 +1567,11 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags) char *name2; /* Not used. */ int flags; /* Information about what happened. */ { - register TkButton *butPtr = (TkButton *) clientData; - char *value; + TkButton *butPtr = (TkButton *) clientData; + char *name; + Tcl_Obj *valuePtr; + + name = Tcl_GetString(butPtr->textVarNamePtr); /* * If the variable is unset, then immediately recreate it unless @@ -1239,24 +1580,22 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags) if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, + Tcl_SetVar2Ex(interp, name, NULL, butPtr->textPtr, TCL_GLOBAL_ONLY); - Tcl_TraceVar(interp, butPtr->textVarName, + Tcl_TraceVar(interp, name, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, clientData); } return (char *) NULL; } - value = Tcl_GetVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY); - if (value == NULL) { - value = ""; - } - if (butPtr->text != NULL) { - ckfree(butPtr->text); + valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY); + if (valuePtr == NULL) { + valuePtr = Tcl_NewObj(); } - butPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); - strcpy(butPtr->text, value); + Tcl_DecrRefCount(butPtr->textPtr); + butPtr->textPtr = valuePtr; + Tcl_IncrRefCount(butPtr->textPtr); TkpComputeButtonGeometry(butPtr); if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) @@ -1273,7 +1612,7 @@ ButtonTextVarProc(clientData, interp, name1, name2, flags) * ButtonImageProc -- * * This procedure is invoked by the image code whenever the manager - * for an image does something that affects the size of contents + * for an image does something that affects the size or contents * of an image displayed in a button. * * Results: @@ -1311,7 +1650,7 @@ ButtonImageProc(clientData, x, y, width, height, imgWidth, imgHeight) * ButtonSelectImageProc -- * * This procedure is invoked by the image code whenever the manager - * for an image does something that affects the size of contents + * for an image does something that affects the size or contents * of the image displayed in a button when it is selected. * * Results: diff --git a/generic/tkButton.h b/generic/tkButton.h index a873dbe..ae24bae 100644 --- a/generic/tkButton.h +++ b/generic/tkButton.h @@ -4,12 +4,12 @@ * Declarations of types and functions used to implement * button-like widgets. * - * Copyright (c) 1996 by Sun Microsystems, Inc. + * Copyright (c) 1996-1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkButton.h,v 1.4 1998/09/14 18:23:04 stanton Exp $ + * RCS: @(#) $Id: tkButton.h,v 1.5 1999/04/16 01:51:11 stanton Exp $ */ #ifndef _TKBUTTON @@ -25,6 +25,22 @@ #endif /* + * Legal values for the "state" field of TkButton records. + */ + +enum state { + STATE_ACTIVE, STATE_DISABLED, STATE_NORMAL +}; + +/* + * Legal values for the "defaultState" field of TkButton records. + */ + +enum defaultState { + DEFAULT_ACTIVE, DEFAULT_DISABLED, DEFAULT_NORMAL +}; + +/* * A data structure of the following type is kept for each * widget managed by this file: */ @@ -36,69 +52,88 @@ typedef struct { * free up resources after tkwin is gone. */ Tcl_Interp *interp; /* Interpreter associated with button. */ Tcl_Command widgetCmd; /* Token for button's widget command. */ - int type; /* Type of widget: restricts operations - * that may be performed on widget. See - * below for possible values. */ + int type; /* Type of widget, such as TYPE_LABEL: + * restricts operations that may be performed + * on widget. See below for legal values. */ + Tk_OptionTable optionTable; /* Table that defines configuration options + * available for this widget. */ /* * Information about what's in the button. */ - char *text; /* Text to display in button (malloc'ed) - * or NULL. */ - int underline; /* Index of character to underline. < 0 means + Tcl_Obj *textPtr; /* Value of -text option: specifies text to + * display in button. */ + int underline; /* Value of -underline option: specifies + * index of character to underline. < 0 means * don't underline anything. */ - char *textVarName; /* Name of variable (malloc'ed) or NULL. - * If non-NULL, button displays the contents - * of this variable. */ - Pixmap bitmap; /* Bitmap to display or None. If not None - * then text and textVar are ignored. */ - char *imageString; /* Name of image to display (malloc'ed), or - * NULL. If non-NULL, bitmap, text, and - * textVarName are ignored. */ - Tk_Image image; /* Image to display in window, or NULL if - * none. */ - char *selectImageString; /* Name of image to display when selected - * (malloc'ed), or NULL. */ - Tk_Image selectImage; /* Image to display in window when selected, - * or NULL if none. Ignored if image is + Tcl_Obj *textVarNamePtr; /* Value of -textvariable option: specifies + * name of variable or NULL. If non-NULL, + * button displays the contents of this + * variable. */ + Pixmap bitmap; /* Value of -bitmap option. If not None, + * specifies bitmap to display and text and + * textVar are ignored. */ + Tcl_Obj *imagePtr; /* Value of -image option: specifies image + * to display in window, or NULL if none. + * If non-NULL, bitmap, text, and textVarName + * are ignored.*/ + Tk_Image image; /* Derived from imagePtr by calling + * Tk_GetImage, or NULL if imagePtr is NULL. */ + Tcl_Obj *selectImagePtr; /* Value of -selectimage option: specifies + * image to display in window when selected, + * or NULL if none. Ignored if imagePtr is * NULL. */ + Tk_Image selectImage; /* Derived from selectImagePtr by calling + * Tk_GetImage, or NULL if selectImagePtr + * is NULL. */ /* * Information used when displaying widget: */ - Tk_Uid state; /* State of button for display purposes: - * normal, active, or disabled. */ - Tk_3DBorder normalBorder; /* Structure used to draw 3-D - * border and background when window - * isn't active. NULL means no such - * border exists. */ - Tk_3DBorder activeBorder; /* Structure used to draw 3-D - * border and background when window - * is active. NULL means no such - * border exists. */ - int borderWidth; /* Width of border. */ - int relief; /* 3-d effect: TK_RELIEF_RAISED, etc. */ - int highlightWidth; /* Width in pixels of highlight to draw - * around widget when it has the focus. + enum state state; /* Value of -state option: specifies + * state of button for display purposes.*/ + Tk_3DBorder normalBorder; /* Value of -background option: specifies + * color for background (and border) when + * window isn't active. */ + Tk_3DBorder activeBorder; /* Value of -activebackground option: + * this is the color used to draw 3-D border + * and background when widget is active. */ + Tcl_Obj *borderWidthPtr; /* Value of -borderWidth option: specifies + * width of border in pixels. */ + int borderWidth; /* Integer value corresponding to + * borderWidthPtr. Always >= 0. */ + int relief; /* Value of -relief option: specifies 3-d + * effect for border, such as + * TK_RELIEF_RAISED. */ + Tcl_Obj *highlightWidthPtr; /* Value of -highlightthickness option: + * specifies width in pixels of highlight to + * draw around widget when it has the focus. * <= 0 means don't draw a highlight. */ - Tk_3DBorder highlightBorder; - /* Structure used to draw 3-D default ring - * and focus highlight area when highlight - * is off. */ - XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ - + int highlightWidth; /* Integer value corresponding to + * highlightWidthPtr. Always >= 0. */ + Tk_3DBorder highlightBorder;/* Value of -highlightbackground option: + * specifies background with which to draw 3-D + * default ring and focus highlight area when + * highlight is off. */ + XColor *highlightColorPtr; /* Value of -highlightcolor option: + * specifies color for drawing traversal + * highlight. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. * Indicates how much interior stuff must * be offset from outside edges to leave * room for borders. */ - Tk_Font tkfont; /* Information about text font, or NULL. */ - XColor *normalFg; /* Foreground color in normal mode. */ - XColor *activeFg; /* Foreground color in active mode. NULL - * means use normalFg instead. */ - XColor *disabledFg; /* Foreground color when disabled. NULL + Tk_Font tkfont; /* Value of -font option: specifies font + * to use for display text. */ + XColor *normalFg; /* Value of -font option: specifies foreground + * color in normal mode. */ + XColor *activeFg; /* Value of -activeforeground option: + * foreground color in active mode. NULL + * means use -foreground instead. */ + XColor *disabledFg; /* Value of -disabledforeground option: + * foreground color when disabled. NULL * means use normalFg with a 50% stipple * instead. */ GC normalTextGC; /* GC for drawing text in normal mode. Also @@ -106,36 +141,47 @@ typedef struct { * screen. */ GC activeTextGC; /* GC for drawing text in active mode (NULL * means use normalTextGC). */ - Pixmap gray; /* Pixmap for displaying disabled text if - * disabledFg is NULL. */ GC disabledGC; /* Used to produce disabled effect. If * disabledFg isn't NULL, this GC is used to * draw button text or icon. Otherwise * text or icon is drawn with normalGC and * this GC is used to stipple background * across it. For labels this is None. */ + Pixmap gray; /* Pixmap for displaying disabled text if + * disabledFg is NULL. */ GC copyGC; /* Used for copying information from an * off-screen pixmap to the screen. */ - char *widthString; /* Value of -width option. Malloc'ed. */ - char *heightString; /* Value of -height option. Malloc'ed. */ - int width, height; /* If > 0, these specify dimensions to request - * for window, in characters for text and in - * pixels for bitmaps. In this case the actual - * size of the text string or bitmap is - * ignored in computing desired window size. */ - int wrapLength; /* Line length (in pixels) at which to wrap + Tcl_Obj *widthPtr; /* Value of -width option. */ + int width; /* Integer value corresponding to widthPtr. */ + Tcl_Obj *heightPtr; /* Value of -height option. */ + int height; /* Integer value corresponding to heightPtr. */ + Tcl_Obj *wrapLengthPtr; /* Value of -wraplength option: specifies + * line length (in pixels) at which to wrap * onto next line. <= 0 means don't wrap * except at newlines. */ - int padX, padY; /* Extra space around text (pixels to leave - * on each side). Ignored for bitmaps and + int wrapLength; /* Integer value corresponding to + * wrapLengthPtr. */ + Tcl_Obj *padXPtr; /* Value of -padx option: specifies how many + * pixels of extra space to leave on left and + * right of text. Ignored for bitmaps and * images. */ - Tk_Anchor anchor; /* Where text/bitmap should be displayed - * inside button region. */ - Tk_Justify justify; /* Justification to use for multi-line text. */ - int indicatorOn; /* True means draw indicator, false means - * don't draw it. */ - Tk_3DBorder selectBorder; /* For drawing indicator background, or perhaps - * widget background, when selected. */ + int padX; /* Integer value corresponding to padXPtr. */ + Tcl_Obj *padYPtr; /* Value of -padx option: specifies how many + * pixels of extra space to leave above and + * below text. Ignored for bitmaps and + * images. */ + int padY; /* Integer value corresponding to padYPtr. */ + Tk_Anchor anchor; /* Value of -anchor option: specifies where + * text/bitmap should be displayed inside + * button region. */ + Tk_Justify justify; /* Value of -justify option: specifies how + * to align lines of multi-line text. */ + int indicatorOn; /* Value of -indicatoron option: 1 means + * draw indicator in checkbuttons and + * radiobuttons, 0 means don't draw it. */ + Tk_3DBorder selectBorder; /* Value of -selectcolor option: specifies + * color for drawing indicator background, or + * perhaps widget background, when selected. */ int textWidth; /* Width needed to display text as requested, * in pixels. */ int textHeight; /* Height needed to display text as requested, @@ -144,36 +190,42 @@ typedef struct { int indicatorSpace; /* Horizontal space (in pixels) allocated for * display of indicator. */ int indicatorDiameter; /* Diameter of indicator, in pixels. */ - Tk_Uid defaultState; /* State of default ring: normal, active, or - * disabled. */ - + enum defaultState defaultState; + /* Value of -default option, such as + * DEFAULT_NORMAL: specifies state + * of default ring for buttons (normal, + * active, or disabled). NULL for other + * classes. */ + /* * For check and radio buttons, the fields below are used * to manage the variable indicating the button's state. */ - char *selVarName; /* Name of variable used to control selected - * state of button. Malloc'ed (if - * not NULL). */ - char *onValue; /* Value to store in variable when - * this button is selected. Malloc'ed (if - * not NULL). */ - char *offValue; /* Value to store in variable when this - * button isn't selected. Malloc'ed - * (if not NULL). Valid only for check - * buttons. */ + Tcl_Obj *selVarNamePtr; /* Value of -variable option: specifies name + * of variable used to control selected + * state of button. */ + Tcl_Obj *onValuePtr; /* Value of -offvalue option: specifies value + * to store in variable when this button is + * selected. */ + Tcl_Obj *offValuePtr; /* Value of -offvalue option: specifies value + * to store in variable when this button + * isn't selected. Used only by + * checkbuttons. */ /* * Miscellaneous information: */ - Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *takeFocus; /* Value of -takefocus option; not used in + Tk_Cursor cursor; /* Value of -cursor option: if not None, + * specifies current cursor for window. */ + Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal - * scripts. Malloc'ed, but may be NULL. */ - char *command; /* Command to execute when button is - * invoked; valid for buttons only. - * If not NULL, it's malloc-ed. */ + * scripts. */ + Tcl_Obj *commandPtr; /* Value of -command option: specifies script + * to execute when button is invoked. If + * widget is label or has no command, this + * is NULL. */ int flags; /* Various flags; see below for * definitions. */ } TkButton; @@ -200,36 +252,31 @@ typedef struct { * so special highlight should be drawn. * GOT_FOCUS: Non-zero means this button currently * has the input focus. + * BUTTON_DELETED: Non-zero needs that this button has been + * deleted, or is in the process of being + * deleted. */ #define REDRAW_PENDING 1 #define SELECTED 2 #define GOT_FOCUS 4 - -/* - * Mask values used to selectively enable entries in the - * configuration specs: - */ - -#define LABEL_MASK TK_CONFIG_USER_BIT -#define BUTTON_MASK TK_CONFIG_USER_BIT << 1 -#define CHECK_BUTTON_MASK TK_CONFIG_USER_BIT << 2 -#define RADIO_BUTTON_MASK TK_CONFIG_USER_BIT << 3 -#define ALL_MASK (LABEL_MASK | BUTTON_MASK \ - | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK) +#define BUTTON_DELETED 0x8 /* * Declaration of variables shared between the files in the button module. */ extern TkClassProcs tkpButtonProcs; -extern Tk_ConfigSpec tkpButtonConfigSpecs[]; /* * Declaration of procedures used in the implementation of the button * widget. */ +#ifndef TkpButtonSetDefaults +EXTERN void TkpButtonSetDefaults _ANSI_ARGS_(( + Tk_OptionSpec *specPtr)); +#endif EXTERN void TkButtonWorldChanged _ANSI_ARGS_(( ClientData instanceData)); EXTERN void TkpComputeButtonGeometry _ANSI_ARGS_(( diff --git a/generic/tkCanvArc.c b/generic/tkCanvArc.c index ab48720..1b9e4e9 100644 --- a/generic/tkCanvArc.c +++ b/generic/tkCanvArc.c @@ -4,12 +4,12 @@ * This file implements arc items for canvas widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvArc.c,v 1.3 1998/09/14 18:23:04 stanton Exp $ + * RCS: @(#) $Id: tkCanvArc.c,v 1.4 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -168,14 +168,6 @@ Tk_ItemType tkArcType = { # define PI 3.14159265358979323846 #endif -/* - * The uid's below comprise the legal values for the "-style" - * option for arcs. - */ - -static Tk_Uid arcUid = NULL; -static Tk_Uid chordUid = NULL; -static Tk_Uid pieSliceUid = NULL; /* *-------------------------------------------------------------- @@ -188,7 +180,7 @@ static Tk_Uid pieSliceUid = NULL; * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is + * the interp's result; in this case itemPtr is * left uninitialized, so it can be safely freed by the * caller. * @@ -218,16 +210,6 @@ CreateArc(interp, canvas, itemPtr, argc, argv) } /* - * Carry out once-only initialization. - */ - - if (arcUid == NULL) { - arcUid = Tk_GetUid("arc"); - chordUid = Tk_GetUid("chord"); - pieSliceUid = Tk_GetUid("pieslice"); - } - - /* * Carry out initialization that is needed in order to clean * up after errors during the the remainder of this procedure. */ @@ -241,7 +223,7 @@ CreateArc(interp, canvas, itemPtr, argc, argv) arcPtr->fillColor = NULL; arcPtr->fillStipple = None; arcPtr->outlineStipple = None; - arcPtr->style = pieSliceUid; + arcPtr->style = Tk_GetUid("pieslice"); arcPtr->outlineGC = None; arcPtr->fillGC = None; @@ -276,7 +258,7 @@ CreateArc(interp, canvas, itemPtr, argc, argv) * on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -319,9 +301,10 @@ ArcCoords(interp, canvas, itemPtr, argc, argv) } ComputeArcBbox(canvas, arcPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 4, got %d", - argc); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -337,7 +320,7 @@ ArcCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information, such as colors and stipple @@ -381,12 +364,13 @@ ConfigureArc(interp, canvas, itemPtr, argc, argv, flags) i = (int) (arcPtr->extent/360.0); arcPtr->extent -= i*360.0; - if ((arcPtr->style != arcUid) && (arcPtr->style != chordUid) - && (arcPtr->style != pieSliceUid)) { + if ((arcPtr->style != Tk_GetUid("arc")) + && (arcPtr->style != Tk_GetUid("chord")) + && (arcPtr->style != Tk_GetUid("pieslice"))) { Tcl_AppendResult(interp, "bad -style option \"", arcPtr->style, "\": must be arc, chord, or pieslice", (char *) NULL); - arcPtr->style = pieSliceUid; + arcPtr->style = Tk_GetUid("pieslice"); return TCL_ERROR; } @@ -412,11 +396,11 @@ ConfigureArc(interp, canvas, itemPtr, argc, argv, flags) } arcPtr->outlineGC = newGC; - if ((arcPtr->fillColor == NULL) || (arcPtr->style == arcUid)) { + if ((arcPtr->fillColor == NULL) || (arcPtr->style == Tk_GetUid("arc"))) { newGC = None; } else { gcValues.foreground = arcPtr->fillColor->pixel; - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { gcValues.arc_mode = ArcChord; } else { gcValues.arc_mode = ArcPieSlice; @@ -545,7 +529,7 @@ ComputeArcBbox(canvas, arcPtr) TkIncludePoint((Tk_Item *) arcPtr, arcPtr->center2); center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2; center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2; - if (arcPtr->style == pieSliceUid) { + if (arcPtr->style == Tk_GetUid("pieslice")) { TkIncludePoint((Tk_Item *) arcPtr, center); } @@ -689,10 +673,10 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height) Tk_CanvasDrawableCoords(canvas, arcPtr->center2[0], arcPtr->center2[1], &x2, &y2); - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { XDrawLine(display, drawable, arcPtr->outlineGC, x1, y1, x2, y2); - } else if (arcPtr->style == pieSliceUid) { + } else if (arcPtr->style == Tk_GetUid("pieslice")) { short cx, cy; Tk_CanvasDrawableCoords(canvas, @@ -704,10 +688,10 @@ DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height) cx, cy, x2, y2); } } else { - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { TkFillPolygon(canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS, display, drawable, arcPtr->outlineGC, None); - } else if (arcPtr->style == pieSliceUid) { + } else if (arcPtr->style == Tk_GetUid("pieslice")) { TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS, display, drawable, arcPtr->outlineGC, None); TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS, @@ -785,7 +769,7 @@ ArcToPoint(canvas, itemPtr, pointPtr) * we're dealing with. */ - if (arcPtr->style == arcUid) { + if (arcPtr->style == Tk_GetUid("arc")) { if (angleInRange) { return TkOvalToPoint(arcPtr->bbox, (double) arcPtr->width, 0, pointPtr); @@ -811,7 +795,7 @@ ArcToPoint(canvas, itemPtr, pointPtr) width = arcPtr->width; } - if (arcPtr->style == pieSliceUid) { + if (arcPtr->style == Tk_GetUid("pieslice")) { if (width > 1.0) { dist = TkPolygonToPoint(arcPtr->outlinePtr, PIE_OUTLINE1_PTS, pointPtr); @@ -966,7 +950,7 @@ ArcToArea(canvas, itemPtr, rectPtr) numPoints = 2; pointPtr += 4; - if ((arcPtr->style == pieSliceUid) && (arcPtr->extent < 180.0)) { + if ((arcPtr->style == Tk_GetUid("pieslice")) && (arcPtr->extent < 180.0)) { pointPtr[0] = 0.0; pointPtr[1] = 0.0; numPoints++; @@ -1040,7 +1024,7 @@ ArcToArea(canvas, itemPtr, rectPtr) * polygon(s) forming the sides of a chord or pie-slice. */ - if (arcPtr->style == pieSliceUid) { + if (arcPtr->style == Tk_GetUid("pieslice")) { if (width >= 1.0) { if (TkPolygonToArea(arcPtr->outlinePtr, PIE_OUTLINE1_PTS, rectPtr) != -1) { @@ -1056,7 +1040,7 @@ ArcToArea(canvas, itemPtr, rectPtr) return 0; } } - } else if (arcPtr->style == chordUid) { + } else if (arcPtr->style == Tk_GetUid("chord")) { if (width >= 1.0) { if (TkPolygonToArea(arcPtr->outlinePtr, CHORD_OUTLINE_PTS, rectPtr) != -1) { @@ -1307,7 +1291,7 @@ ComputeArcOutline(arcPtr) * center point. The second point is the corner point. */ - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { outlinePtr[0] = outlinePtr[12] = corner1[0]; outlinePtr[1] = outlinePtr[13] = corner1[1]; TkGetButtPoints(arcPtr->center2, arcPtr->center1, @@ -1322,7 +1306,7 @@ ComputeArcOutline(arcPtr) - arcPtr->center1[0]; outlinePtr[9] = arcPtr->center2[1] + outlinePtr[11] - arcPtr->center1[1]; - } else if (arcPtr->style == pieSliceUid) { + } else if (arcPtr->style == Tk_GetUid("pieslice")) { /* * For pie slices, generate two polygons, one for each side * of the pie slice. The first arm has a shape like this, @@ -1574,7 +1558,7 @@ AngleInRange(x, y, start, extent) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used + * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * @@ -1618,7 +1602,7 @@ ArcToPostscript(interp, canvas, itemPtr, prepass) (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2, (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2); Tcl_AppendResult(interp, buffer, (char *) NULL); - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n", ang1, ang2); } else { @@ -1670,9 +1654,9 @@ ArcToPostscript(interp, canvas, itemPtr, prepass) } else { Tcl_AppendResult(interp, "stroke\n", (char *) NULL); } - if (arcPtr->style != arcUid) { + if (arcPtr->style != Tk_GetUid("arc")) { Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL); - if (arcPtr->style == chordUid) { + if (arcPtr->style == Tk_GetUid("chord")) { Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS); } else { diff --git a/generic/tkCanvBmap.c b/generic/tkCanvBmap.c index a09bf8d..dedc4e7 100644 --- a/generic/tkCanvBmap.c +++ b/generic/tkCanvBmap.c @@ -4,12 +4,12 @@ * This file implements bitmap items for canvas widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvBmap.c,v 1.2 1998/09/14 18:23:04 stanton Exp $ + * RCS: @(#) $Id: tkCanvBmap.c,v 1.3 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -129,7 +129,7 @@ Tk_ItemType tkBitmapType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is left uninitialized, + * the interp's result; in this case itemPtr is left uninitialized, * so it can be safely freed by the caller. * * Side effects: @@ -194,7 +194,7 @@ CreateBitmap(interp, canvas, itemPtr, argc, argv) * details on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -228,8 +228,10 @@ BitmapCoords(interp, canvas, itemPtr, argc, argv) } ComputeBitmapBbox(canvas, bmapPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 2, got %d", argc); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -245,7 +247,7 @@ BitmapCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information may be set for itemPtr. @@ -690,7 +692,7 @@ TranslateBitmap(canvas, itemPtr, deltaX, deltaY) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used to be there. + * left in the interp's result, replacing whatever used to be there. * If no error occurs, then Postscript for the item is appended * to the result. * @@ -715,7 +717,7 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass) double x, y; int width, height, rowsAtOnce, rowsThisTime; int curRow; - char buffer[200]; + char buffer[100 + TCL_DOUBLE_SPACE * 2 + TCL_INTEGER_SPACE * 4]; if (bmapPtr->bitmap == None) { return TCL_OK; @@ -749,7 +751,7 @@ BitmapToPostscript(interp, canvas, itemPtr, prepass) if (bmapPtr->bgColor != NULL) { sprintf(buffer, "%.15g %.15g moveto %d 0 rlineto 0 %d rlineto %d %s\n", - x, y, width, height, -width,"0 rlineto closepath"); + x, y, width, height, -width, "0 rlineto closepath"); Tcl_AppendResult(interp, buffer, (char *) NULL); if (Tk_CanvasPsColor(interp, canvas, bmapPtr->bgColor) != TCL_OK) { return TCL_ERROR; diff --git a/generic/tkCanvImg.c b/generic/tkCanvImg.c index 0432bd7..cf1106d 100644 --- a/generic/tkCanvImg.c +++ b/generic/tkCanvImg.c @@ -4,12 +4,12 @@ * This file implements image items for canvas widgets. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvImg.c,v 1.2 1998/09/14 18:23:05 stanton Exp $ + * RCS: @(#) $Id: tkCanvImg.c,v 1.3 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -126,7 +126,7 @@ Tk_ItemType tkImageType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is left uninitialized, + * the interp's result; in this case itemPtr is left uninitialized, * so it can be safely freed by the caller. * * Side effects: @@ -190,7 +190,7 @@ CreateImage(interp, canvas, itemPtr, argc, argv) * details on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -224,8 +224,10 @@ ImageCoords(interp, canvas, itemPtr, argc, argv) } ComputeImageBbox(canvas, imgPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 2, got %d", argc); + char buf[64]; + + sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -241,7 +243,7 @@ ImageCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information may be set for itemPtr. diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c index 1c35de5..131b73d 100644 --- a/generic/tkCanvLine.c +++ b/generic/tkCanvLine.c @@ -4,12 +4,13 @@ * This file implements line items for canvas widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvLine.c,v 1.3 1999/02/04 20:51:23 stanton Exp $ + * RCS: @(#) $Id: tkCanvLine.c,v 1.4 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -180,15 +181,6 @@ Tk_ItemType tkLineType = { }; /* - * The Tk_Uid's below refer to uids for the various arrow types: - */ - -static Tk_Uid noneUid = NULL; -static Tk_Uid firstUid = NULL; -static Tk_Uid lastUid = NULL; -static Tk_Uid bothUid = NULL; - -/* * The definition below determines how large are static arrays * used to hold spline points (splines larger than this have to * have their arrays malloc-ed). @@ -207,7 +199,7 @@ static Tk_Uid bothUid = NULL; * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is left uninitialized, + * the interp's result; in this case itemPtr is left uninitialized, * so it can be safely freed by the caller. * * Side effects: @@ -252,13 +244,7 @@ CreateLine(interp, canvas, itemPtr, argc, argv) linePtr->joinStyle = JoinRound; linePtr->gc = None; linePtr->arrowGC = None; - if (noneUid == NULL) { - noneUid = Tk_GetUid("none"); - firstUid = Tk_GetUid("first"); - lastUid = Tk_GetUid("last"); - bothUid = Tk_GetUid("both"); - } - linePtr->arrow = noneUid; + linePtr->arrow = Tk_GetUid("none"); linePtr->arrowShapeA = (float)8.0; linePtr->arrowShapeB = (float)10.0; linePtr->arrowShapeC = (float)3.0; @@ -302,7 +288,7 @@ CreateLine(interp, canvas, itemPtr, argc, argv) * on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -385,7 +371,7 @@ LineCoords(interp, canvas, itemPtr, argc, argv) ckfree((char *) linePtr->lastArrowPtr); linePtr->lastArrowPtr = NULL; } - if (linePtr->arrow != noneUid) { + if (linePtr->arrow != Tk_GetUid("none")) { ConfigureArrows(canvas, linePtr); } ComputeLineBbox(canvas, linePtr); @@ -403,7 +389,7 @@ LineCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information, such as colors and stipple @@ -426,6 +412,10 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags) GC newGC, arrowGC; unsigned long mask; Tk_Window tkwin; + Tk_Uid noneUid = Tk_GetUid("none"); + Tk_Uid bothUid = Tk_GetUid("both"); + Tk_Uid firstUid = Tk_GetUid("first"); + Tk_Uid lastUid = Tk_GetUid("last"); tkwin = Tk_CanvasTkwin(canvas); if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, @@ -493,8 +483,8 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags) ckfree((char *) linePtr->firstArrowPtr); linePtr->firstArrowPtr = NULL; } - if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != lastUid) - && (linePtr->arrow != bothUid)) { + if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != lastUid) + && (linePtr->arrow != bothUid)) { int i; i = 2*(linePtr->numPoints-1); @@ -505,7 +495,7 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags) } if (linePtr->arrow != noneUid) { if ((linePtr->arrow != firstUid) && (linePtr->arrow != lastUid) - && (linePtr->arrow != bothUid)) { + && (linePtr->arrow != bothUid)) { Tcl_AppendResult(interp, "bad arrow spec \"", linePtr->arrow, "\": must be none, first, last, or both", (char *) NULL); @@ -652,14 +642,14 @@ ComputeLineBbox(canvas, linePtr) * Add in the sizes of arrowheads, if any. */ - if (linePtr->arrow != noneUid) { - if (linePtr->arrow != lastUid) { + if (linePtr->arrow != Tk_GetUid("none")) { + if (linePtr->arrow != Tk_GetUid("last")) { for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; i++, coordPtr += 2) { TkIncludePoint((Tk_Item *) linePtr, coordPtr); } } - if (linePtr->arrow != firstUid) { + if (linePtr->arrow != Tk_GetUid("first")) { for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; i++, coordPtr += 2) { TkIncludePoint((Tk_Item *) linePtr, coordPtr); @@ -960,8 +950,8 @@ LineToPoint(canvas, itemPtr, pointPtr) * If there are arrowheads, check the distance to the arrowheads. */ - if (linePtr->arrow != noneUid) { - if (linePtr->arrow != lastUid) { + if (linePtr->arrow != Tk_GetUid("none")) { + if (linePtr->arrow != Tk_GetUid("last")) { dist = TkPolygonToPoint(linePtr->firstArrowPtr, PTS_IN_ARROW, pointPtr); if (dist <= 0.0) { @@ -971,7 +961,7 @@ LineToPoint(canvas, itemPtr, pointPtr) bestDist = dist; } } - if (linePtr->arrow != firstUid) { + if (linePtr->arrow != Tk_GetUid("first")) { dist = TkPolygonToPoint(linePtr->lastArrowPtr, PTS_IN_ARROW, pointPtr); if (dist <= 0.0) { @@ -1064,15 +1054,15 @@ LineToArea(canvas, itemPtr, rectPtr) * Check arrowheads, if any. */ - if (linePtr->arrow != noneUid) { - if (linePtr->arrow != lastUid) { + if (linePtr->arrow != Tk_GetUid("none")) { + if (linePtr->arrow != Tk_GetUid("last")) { if (TkPolygonToArea(linePtr->firstArrowPtr, PTS_IN_ARROW, rectPtr) != result) { result = 0; goto done; } } - if (linePtr->arrow != firstUid) { + if (linePtr->arrow != Tk_GetUid("first")) { if (TkPolygonToArea(linePtr->lastArrowPtr, PTS_IN_ARROW, rectPtr) != result) { result = 0; @@ -1145,7 +1135,7 @@ ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY) coordPtr[0] = originX + scaleX*(*coordPtr - originX); coordPtr[1] = originY + scaleY*(coordPtr[1] - originY); } - if (linePtr->arrow != noneUid) { + if (linePtr->arrow != Tk_GetUid("none")) { ConfigureArrows(canvas, linePtr); } ComputeLineBbox(canvas, linePtr); @@ -1366,7 +1356,7 @@ ConfigureArrows(canvas, linePtr) fracHeight = (linePtr->width/2.0)/shapeC; backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0; - if (linePtr->arrow != lastUid) { + if (linePtr->arrow != Tk_GetUid("last")) { poly = linePtr->firstArrowPtr; if (poly == NULL) { poly = (double *) ckalloc((unsigned) @@ -1411,7 +1401,7 @@ ConfigureArrows(canvas, linePtr) * Similar arrowhead calculation for the last point of the line. */ - if (linePtr->arrow != firstUid) { + if (linePtr->arrow != Tk_GetUid("first")) { coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2); poly = linePtr->lastArrowPtr; if (poly == NULL) { @@ -1460,7 +1450,7 @@ ConfigureArrows(canvas, linePtr) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used + * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * @@ -1482,7 +1472,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass) * final Postscript is being created. */ { LineItem *linePtr = (LineItem *) itemPtr; - char buffer[200]; + char buffer[64 + TCL_INTEGER_SPACE]; char *style; if (linePtr->fg == NULL) { @@ -1600,7 +1590,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used + * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * arrowhead is appended to the result. * diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c index 5f18bc7..ad5eb80 100644 --- a/generic/tkCanvPoly.c +++ b/generic/tkCanvPoly.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPoly.c,v 1.2 1998/09/14 18:23:05 stanton Exp $ + * RCS: @(#) $Id: tkCanvPoly.c,v 1.3 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -150,7 +150,7 @@ Tk_ItemType tkPolygonType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is + * the interp's result; in this case itemPtr is * left uninitialized, so it can be safely freed by the * caller. * @@ -234,7 +234,7 @@ CreatePolygon(interp, canvas, itemPtr, argc, argv) * on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -327,7 +327,7 @@ PolygonCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information, such as colors and stipple @@ -919,7 +919,7 @@ TranslatePolygon(canvas, itemPtr, deltaX, deltaY) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used + * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * @@ -940,7 +940,6 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass) * collect font information; 0 means * final Postscript is being created. */ { - char string[100]; PolygonItem *polyPtr = (PolygonItem *) itemPtr; /* @@ -977,6 +976,8 @@ PolygonToPostscript(interp, canvas, itemPtr, prepass) */ if (polyPtr->outlineColor != NULL) { + char string[32 + TCL_INTEGER_SPACE]; + if (!polyPtr->smooth) { Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr, polyPtr->numPoints); diff --git a/generic/tkCanvPs.c b/generic/tkCanvPs.c index b87068d..4c99b15 100644 --- a/generic/tkCanvPs.c +++ b/generic/tkCanvPs.c @@ -6,12 +6,12 @@ * procedures used for generating Postscript. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPs.c,v 1.4 1998/09/22 18:57:16 stanton Exp $ + * RCS: @(#) $Id: tkCanvPs.c,v 1.5 1999/04/16 01:51:11 stanton Exp $ */ #include "tkInt.h" @@ -115,6 +115,7 @@ static Tk_ConfigSpec configSpecs[] = { * The prolog data. Generated by str2c from prolog.ps * This was split in small chunks by str2c because * some C compiler have limitations on the size of static strings. + * (str2c is a small tcl script in tcl's tool directory (source release)) */ static CONST char * CONST prolog[]= { /* Start of part 1 (2000 characters) */ @@ -123,7 +124,7 @@ static CONST char * CONST prolog[]= { \n\ % This is a standard prolog for Postscript generated by Tk's canvas\n\ % widget.\n\ -% RCS: @(#) $Id: tkCanvPs.c,v 1.4 1998/09/22 18:57:16 stanton Exp $\n\ +% RCS: @(#) $Id: tkCanvPs.c,v 1.5 1999/04/16 01:51:11 stanton Exp $\n\ \n\ % The definitions below just define all of the variables used in\n\ % any of the procedures here. This is needed for obscure reasons\n\ @@ -710,20 +711,20 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) Tcl_AppendResult(canvasPtr->interp, "%!PS-Adobe-3.0 EPSF-3.0\n", "%%Creator: Tk Canvas Widget\n", (char *) NULL); -#if !(defined(__WIN32__) || defined(MAC_TCL)) +#ifdef HAVE_PW_GECOS if (!Tcl_IsSafe(interp)) { - struct passwd *pwPtr = getpwuid(getuid()); + struct passwd *pwPtr = getpwuid(getuid()); /* INTL: Native. */ Tcl_AppendResult(canvasPtr->interp, "%%For: ", (pwPtr != NULL) ? pwPtr->pw_gecos : "Unknown", "\n", (char *) NULL); endpwent(); } -#endif /* __WIN32__ || MAC_TCL */ +#endif /* HAVE_PW_GECOS */ Tcl_AppendResult(canvasPtr->interp, "%%Title: Window ", Tk_PathName(canvasPtr->tkwin), "\n", (char *) NULL); time(&now); Tcl_AppendResult(canvasPtr->interp, "%%CreationDate: ", - ctime(&now), (char *) NULL); + ctime(&now), (char *) NULL); /* INTL: Native. */ if (!psInfo.rotate) { sprintf(string, "%d %d %d %d", (int) (psInfo.pageX + psInfo.scale*deltaX), @@ -764,7 +765,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) } if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1); + Tcl_Write(psInfo.chan, Tcl_GetStringResult(canvasPtr->interp), -1); Tcl_ResetResult(canvasPtr->interp); } @@ -811,7 +812,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) Tcl_AppendResult(canvasPtr->interp, string, " lineto closepath clip newpath\n", (char *) NULL); if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1); + Tcl_Write(psInfo.chan, Tcl_GetStringResult(canvasPtr->interp), -1); Tcl_ResetResult(canvasPtr->interp); } @@ -836,7 +837,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) result = (*itemPtr->typePtr->postscriptProc)(canvasPtr->interp, (Tk_Canvas) canvasPtr, itemPtr, 0); if (result != TCL_OK) { - char msg[100]; + char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "\n (generating Postscript for item %d)", itemPtr->id); @@ -845,7 +846,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) } Tcl_AppendResult(canvasPtr->interp, "grestore\n", (char *) NULL); if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1); + Tcl_Write(psInfo.chan, Tcl_GetStringResult(canvasPtr->interp), -1); Tcl_ResetResult(canvasPtr->interp); } } @@ -860,7 +861,7 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) Tcl_AppendResult(canvasPtr->interp, "restore showpage\n\n", "%%Trailer\nend\n%%EOF\n", (char *) NULL); if (psInfo.chan != NULL) { - Tcl_Write(psInfo.chan, canvasPtr->interp->result, -1); + Tcl_Write(psInfo.chan, Tcl_GetStringResult(canvasPtr->interp), -1); Tcl_ResetResult(canvasPtr->interp); } @@ -916,9 +917,9 @@ TkCanvPostscriptCmd(canvasPtr, interp, argc, argv) * * Results: * Returns a standard Tcl return value. If an error occurs - * then an error message will be left in interp->result. + * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be - * appended to interp->result. + * appended to the interp's result. * * Side effects: * None. @@ -997,9 +998,9 @@ Tk_CanvasPsColor(interp, canvas, colorPtr) * * Results: * Returns a standard Tcl return value. If an error occurs - * then an error message will be left in interp->result. + * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be - * appended to the interp->result. + * appended to the interp's result. * * Side effects: * The Postscript font name is entered into psInfoPtr->fontTable @@ -1019,7 +1020,7 @@ Tk_CanvasPsFont(interp, canvas, tkfont) TkCanvas *canvasPtr = (TkCanvas *) canvas; TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr; char *end; - char pointString[20]; + char pointString[TCL_INTEGER_SPACE]; Tcl_DString ds; int i, points; @@ -1091,9 +1092,9 @@ Tk_CanvasPsFont(interp, canvas, tkfont) * * Results: * Returns a standard Tcl return value. If an error occurs - * then an error message will be left in interp->result. + * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be - * appended to interp->result. + * appended to the interp's result. * * Side effects: * None. @@ -1190,9 +1191,9 @@ Tk_CanvasPsBitmap(interp, canvas, bitmap, startX, startY, width, height) * * Results: * Returns a standard Tcl return value. If an error occurs - * then an error message will be left in interp->result. + * then an error message will be left in the interp's result. * If no error occurs, then additional Postscript will be - * appended to interp->result. + * appended to the interp's result. * * Side effects: * None. @@ -1210,7 +1211,7 @@ Tk_CanvasPsStipple(interp, canvas, bitmap) TkCanvas *canvasPtr = (TkCanvas *) canvas; TkPostscriptInfo *psInfoPtr = canvasPtr->psInfoPtr; int width, height; - char string[100]; + char string[TCL_INTEGER_SPACE * 2]; Window dummyRoot; int dummyX, dummyY; unsigned dummyBorderwidth, dummyDepth; @@ -1278,7 +1279,7 @@ Tk_CanvasPsY(canvas, y) * commands to create the path. * * Results: - * Postscript commands get appended to what's in interp->result. + * Postscript commands get appended to what's in the interp's result. * * Side effects: * None. @@ -1327,7 +1328,7 @@ Tk_CanvasPsPath(interp, canvas, coordPtr, numPoints) * TCL_OK is returned, then everything went well and the * screen distance is stored at *doublePtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c index 93230f7..b025e30 100644 --- a/generic/tkCanvText.c +++ b/generic/tkCanvText.c @@ -4,12 +4,12 @@ * This file implements text items for canvas widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvText.c,v 1.3 1998/10/16 00:46:19 rjohnson Exp $ + * RCS: @(#) $Id: tkCanvText.c,v 1.4 1999/04/16 01:51:11 stanton Exp $ */ #include <stdio.h> @@ -36,8 +36,8 @@ typedef struct TextItem { */ double x, y; /* Positioning point for text. */ - int insertPos; /* Insertion cursor is displayed just to left - * of character with this index. */ + int insertPos; /* Character index of character just before + * which the insertion cursor is displayed. */ /* * Configuration settings that are updated by Tk_ConfigureWidget. @@ -57,7 +57,8 @@ typedef struct TextItem { * configuration settings above. */ - int numChars; /* Number of non-NULL characters in text. */ + int numChars; /* Length of text in characters. */ + int numBytes; /* Length of text in bytes. */ Tk_TextLayout textLayout; /* Cached text layout information. */ int leftEdge; /* Pixel location of the left edge of the * text item; where the left border of the @@ -154,26 +155,26 @@ static void TranslateText _ANSI_ARGS_((Tk_Canvas canvas, */ Tk_ItemType tkTextType = { - "text", /* name */ - sizeof(TextItem), /* itemSize */ - CreateText, /* createProc */ - configSpecs, /* configSpecs */ - ConfigureText, /* configureProc */ - TextCoords, /* coordProc */ - DeleteText, /* deleteProc */ - DisplayCanvText, /* displayProc */ - 0, /* alwaysRedraw */ - TextToPoint, /* pointProc */ - TextToArea, /* areaProc */ - TextToPostscript, /* postscriptProc */ - ScaleText, /* scaleProc */ - TranslateText, /* translateProc */ - GetTextIndex, /* indexProc */ - SetTextCursor, /* icursorProc */ - GetSelText, /* selectionProc */ - TextInsert, /* insertProc */ - TextDeleteChars, /* dTextProc */ - (Tk_ItemType *) NULL /* nextPtr */ + "text", /* name */ + sizeof(TextItem), /* itemSize */ + CreateText, /* createProc */ + configSpecs, /* configSpecs */ + ConfigureText, /* configureProc */ + TextCoords, /* coordProc */ + DeleteText, /* deleteProc */ + DisplayCanvText, /* displayProc */ + 0, /* alwaysRedraw */ + TextToPoint, /* pointProc */ + TextToArea, /* areaProc */ + TextToPostscript, /* postscriptProc */ + ScaleText, /* scaleProc */ + TranslateText, /* translateProc */ + GetTextIndex, /* indexProc */ + SetTextCursor, /* icursorProc */ + GetSelText, /* selectionProc */ + TextInsert, /* insertProc */ + TextDeleteChars, /* dTextProc */ + (Tk_ItemType *) NULL /* nextPtr */ }; /* @@ -187,7 +188,7 @@ Tk_ItemType tkTextType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item then an error message is left in - * interp->result; in this case itemPtr is left uninitialized + * the interp's result; in this case itemPtr is left uninitialized * so it can be safely freed by the caller. * * Side effects: @@ -198,12 +199,12 @@ Tk_ItemType tkTextType = { static int CreateText(interp, canvas, itemPtr, argc, argv) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Canvas canvas; /* Canvas to hold new item. */ - Tk_Item *itemPtr; /* Record to hold new item; header - * has been initialized by caller. */ - int argc; /* Number of arguments in argv. */ - char **argv; /* Arguments describing rectangle. */ + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Canvas canvas; /* Canvas to hold new item. */ + Tk_Item *itemPtr; /* Record to hold new item; header has been + * initialized by caller. */ + int argc; /* Number of arguments in argv. */ + char **argv; /* Arguments describing rectangle. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -215,8 +216,8 @@ CreateText(interp, canvas, itemPtr, argc, argv) } /* - * Carry out initialization that is needed in order to clean - * up after errors during the the remainder of this procedure. + * Carry out initialization that is needed in order to clean up after + * errors during the the remainder of this procedure. */ textPtr->textInfoPtr = Tk_CanvasGetTextInfo(canvas); @@ -232,6 +233,7 @@ CreateText(interp, canvas, itemPtr, argc, argv) textPtr->width = 0; textPtr->numChars = 0; + textPtr->numBytes = 0; textPtr->textLayout = NULL; textPtr->leftEdge = 0; textPtr->rightEdge = 0; @@ -266,7 +268,7 @@ CreateText(interp, canvas, itemPtr, argc, argv) * details on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -276,14 +278,12 @@ CreateText(interp, canvas, itemPtr, argc, argv) static int TextCoords(interp, canvas, itemPtr, argc, argv) - Tcl_Interp *interp; /* Used for error reporting. */ - Tk_Canvas canvas; /* Canvas containing item. */ - Tk_Item *itemPtr; /* Item whose coordinates are to be - * read or modified. */ - int argc; /* Number of coordinates supplied in - * argv. */ - char **argv; /* Array of coordinates: x1, y1, - * x2, y2, ... */ + Tcl_Interp *interp; /* Used for error reporting. */ + Tk_Canvas canvas; /* Canvas containing item. */ + Tk_Item *itemPtr; /* Item whose coordinates are to be read or + * modified. */ + int argc; /* Number of coordinates supplied in argv. */ + char **argv; /* Array of coordinates: x1, y1, x2, y2, ... */ { TextItem *textPtr = (TextItem *) itemPtr; char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE]; @@ -300,8 +300,10 @@ TextCoords(interp, canvas, itemPtr, argc, argv) } ComputeTextBbox(canvas, textPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 2, got %d", argc); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -317,7 +319,7 @@ TextCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information, such as colors and stipple @@ -400,17 +402,19 @@ ConfigureText(interp, canvas, itemPtr, argc, argv, flags) * to keep them inside the item. */ - textPtr->numChars = strlen(textPtr->text); + textPtr->numBytes = strlen(textPtr->text); + textPtr->numChars = Tcl_NumUtfChars(textPtr->text, textPtr->numBytes); if (textInfoPtr->selItemPtr == itemPtr) { + if (textInfoPtr->selectFirst >= textPtr->numChars) { textInfoPtr->selItemPtr = NULL; } else { if (textInfoPtr->selectLast >= textPtr->numChars) { - textInfoPtr->selectLast = textPtr->numChars-1; + textInfoPtr->selectLast = textPtr->numChars - 1; } if ((textInfoPtr->anchorItemPtr == itemPtr) && (textInfoPtr->selectAnchor >= textPtr->numChars)) { - textInfoPtr->selectAnchor = textPtr->numChars-1; + textInfoPtr->selectAnchor = textPtr->numChars - 1; } } } @@ -441,10 +445,9 @@ ConfigureText(interp, canvas, itemPtr, argc, argv, flags) static void DeleteText(canvas, itemPtr, display) - Tk_Canvas canvas; /* Info about overall canvas widget. */ - Tk_Item *itemPtr; /* Item that is being deleted. */ - Display *display; /* Display containing window for - * canvas. */ + Tk_Canvas canvas; /* Info about overall canvas widget. */ + Tk_Item *itemPtr; /* Item that is being deleted. */ + Display *display; /* Display containing window for canvas. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -494,9 +497,8 @@ DeleteText(canvas, itemPtr, display) static void ComputeTextBbox(canvas, textPtr) - Tk_Canvas canvas; /* Canvas that contains item. */ - TextItem *textPtr; /* Item whose bbos is to be - * recomputed. */ + Tk_Canvas canvas; /* Canvas that contains item. */ + TextItem *textPtr; /* Item whose bbox is to be recomputed. */ { Tk_CanvasTextInfo *textInfoPtr; int leftX, topY, width, height, fudge; @@ -591,17 +593,16 @@ ComputeTextBbox(canvas, textPtr) static void DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height) - Tk_Canvas canvas; /* Canvas that contains item. */ - Tk_Item *itemPtr; /* Item to be displayed. */ - Display *display; /* Display on which to draw item. */ - Drawable drawable; /* Pixmap or window in which to draw - * item. */ - int x, y, width, height; /* Describes region of canvas that - * must be redisplayed (not used). */ + Tk_Canvas canvas; /* Canvas that contains item. */ + Tk_Item *itemPtr; /* Item to be displayed. */ + Display *display; /* Display on which to draw item. */ + Drawable drawable; /* Pixmap or window in which to draw item. */ + int x, y, width, height; /* Describes region of canvas that must be + * redisplayed (not used). */ { TextItem *textPtr; Tk_CanvasTextInfo *textInfoPtr; - int selFirst, selLast; + int selFirstChar, selLastChar; short drawableX, drawableY; textPtr = (TextItem *) itemPtr; @@ -621,26 +622,30 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height) Tk_CanvasSetStippleOrigin(canvas, textPtr->gc); } - selFirst = -1; - selLast = 0; /* lint. */ + selFirstChar = -1; + selLastChar = 0; /* lint. */ + if (textInfoPtr->selItemPtr == itemPtr) { - selFirst = textInfoPtr->selectFirst; - selLast = textInfoPtr->selectLast; - if (selLast >= textPtr->numChars) { - selLast = textPtr->numChars - 1; + char *text; + + text = textPtr->text; + selFirstChar = textInfoPtr->selectFirst; + selLastChar = textInfoPtr->selectLast; + if (selLastChar >= textPtr->numChars) { + selLastChar = textPtr->numChars - 1; } - if ((selFirst >= 0) && (selFirst <= selLast)) { + if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) { + int xFirst, yFirst, hFirst; + int xLast, yLast; + /* * Draw a special background under the selection. */ - int xFirst, yFirst, hFirst; - int xLast, yLast, wLast; - - Tk_CharBbox(textPtr->textLayout, selFirst, - &xFirst, &yFirst, NULL, &hFirst); - Tk_CharBbox(textPtr->textLayout, selLast, - &xLast, &yLast, &wLast, NULL); + Tk_CharBbox(textPtr->textLayout, selFirstChar, &xFirst, &yFirst, + NULL, &hFirst); + Tk_CharBbox(textPtr->textLayout, selLastChar, &xLast, &yLast, + NULL, NULL); /* * If the selection spans the end of this line, then display @@ -653,7 +658,7 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height) height = hFirst; for (y = yFirst ; y <= yLast; y += height) { if (y == yLast) { - width = (xLast + wLast) - x; + width = xLast - x; } else { width = textPtr->rightEdge - textPtr->leftEdge - x; } @@ -724,10 +729,10 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height) Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, 0, -1); - if ((selFirst >= 0) && (textPtr->selTextGC != textPtr->gc)) { + if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { Tk_DrawTextLayout(display, drawable, textPtr->selTextGC, - textPtr->textLayout, drawableX, drawableY, selFirst, - selLast + 1); + textPtr->textLayout, drawableX, drawableY, selFirstChar, + selLastChar + 1); } if (textPtr->stipple != None) { @@ -754,36 +759,42 @@ DisplayCanvText(canvas, itemPtr, display, drawable, x, y, width, height) */ static void -TextInsert(canvas, itemPtr, beforeThis, string) +TextInsert(canvas, itemPtr, index, string) Tk_Canvas canvas; /* Canvas containing text item. */ Tk_Item *itemPtr; /* Text item to be modified. */ - int beforeThis; /* Index of character before which text is + int index; /* Character index before which string is * to be inserted. */ char *string; /* New characters to be inserted. */ { TextItem *textPtr = (TextItem *) itemPtr; - int length; - char *new; + int byteIndex, byteCount, charsAdded; + char *new, *text; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - length = strlen(string); - if (length == 0) { - return; + text = textPtr->text; + + if (index < 0) { + index = 0; } - if (beforeThis < 0) { - beforeThis = 0; + if (index > textPtr->numChars) { + index = textPtr->numChars; } - if (beforeThis > textPtr->numChars) { - beforeThis = textPtr->numChars; + byteIndex = Tcl_UtfAtIndex(text, index) - text; + byteCount = strlen(string); + if (byteCount == 0) { + return; } - new = (char *) ckalloc((unsigned) (textPtr->numChars + length + 1)); - strncpy(new, textPtr->text, (size_t) beforeThis); - strcpy(new+beforeThis, string); - strcpy(new+beforeThis+length, textPtr->text+beforeThis); - ckfree(textPtr->text); + new = (char *) ckalloc((unsigned) textPtr->numBytes + byteCount + 1); + memcpy(new, text, (size_t) byteIndex); + strcpy(new + byteIndex, string); + strcpy(new + byteIndex + byteCount, text + byteIndex); + + ckfree(text); textPtr->text = new; - textPtr->numChars += length; + charsAdded = Tcl_NumUtfChars(string, byteCount); + textPtr->numChars += charsAdded; + textPtr->numBytes += byteCount; /* * Inserting characters invalidates indices such as those for the @@ -791,19 +802,19 @@ TextInsert(canvas, itemPtr, beforeThis, string) */ if (textInfoPtr->selItemPtr == itemPtr) { - if (textInfoPtr->selectFirst >= beforeThis) { - textInfoPtr->selectFirst += length; + if (textInfoPtr->selectFirst >= index) { + textInfoPtr->selectFirst += charsAdded; } - if (textInfoPtr->selectLast >= beforeThis) { - textInfoPtr->selectLast += length; + if (textInfoPtr->selectLast >= index) { + textInfoPtr->selectLast += charsAdded; } if ((textInfoPtr->anchorItemPtr == itemPtr) - && (textInfoPtr->selectAnchor >= beforeThis)) { - textInfoPtr->selectAnchor += length; + && (textInfoPtr->selectAnchor >= index)) { + textInfoPtr->selectAnchor += charsAdded; } } - if (textPtr->insertPos >= beforeThis) { - textPtr->insertPos += length; + if (textPtr->insertPos >= index) { + textPtr->insertPos += charsAdded; } ComputeTextBbox(canvas, textPtr); } @@ -830,31 +841,40 @@ static void TextDeleteChars(canvas, itemPtr, first, last) Tk_Canvas canvas; /* Canvas containing itemPtr. */ Tk_Item *itemPtr; /* Item in which to delete characters. */ - int first; /* Index of first character to delete. */ - int last; /* Index of last character to delete. */ + int first; /* Character index of first character to + * delete. */ + int last; /* Character index of last character to + * delete (inclusive). */ { TextItem *textPtr = (TextItem *) itemPtr; - int count; - char *new; + int byteIndex, byteCount, charsRemoved; + char *new, *text; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; + text = textPtr->text; if (first < 0) { first = 0; } if (last >= textPtr->numChars) { - last = textPtr->numChars-1; + last = textPtr->numChars - 1; } if (first > last) { return; } - count = last + 1 - first; + charsRemoved = last + 1 - first; + + byteIndex = Tcl_UtfAtIndex(text, first) - text; + byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved) + - (text + byteIndex); + + new = (char *) ckalloc((unsigned) (textPtr->numBytes + 1 - byteCount)); + memcpy(new, text, (size_t) byteIndex); + strcpy(new + byteIndex, text + byteIndex + byteCount); - new = (char *) ckalloc((unsigned) (textPtr->numChars + 1 - count)); - strncpy(new, textPtr->text, (size_t) first); - strcpy(new+first, textPtr->text+last+1); - ckfree(textPtr->text); + ckfree(text); textPtr->text = new; - textPtr->numChars -= count; + textPtr->numChars -= charsRemoved; + textPtr->numBytes -= byteCount; /* * Update indexes for the selection and cursor to reflect the @@ -863,15 +883,15 @@ TextDeleteChars(canvas, itemPtr, first, last) if (textInfoPtr->selItemPtr == itemPtr) { if (textInfoPtr->selectFirst > first) { - textInfoPtr->selectFirst -= count; + textInfoPtr->selectFirst -= charsRemoved; if (textInfoPtr->selectFirst < first) { textInfoPtr->selectFirst = first; } } if (textInfoPtr->selectLast >= first) { - textInfoPtr->selectLast -= count; - if (textInfoPtr->selectLast < (first-1)) { - textInfoPtr->selectLast = (first-1); + textInfoPtr->selectLast -= charsRemoved; + if (textInfoPtr->selectLast < first - 1) { + textInfoPtr->selectLast = first - 1; } } if (textInfoPtr->selectFirst > textInfoPtr->selectLast) { @@ -879,14 +899,14 @@ TextDeleteChars(canvas, itemPtr, first, last) } if ((textInfoPtr->anchorItemPtr == itemPtr) && (textInfoPtr->selectAnchor > first)) { - textInfoPtr->selectAnchor -= count; + textInfoPtr->selectAnchor -= charsRemoved; if (textInfoPtr->selectAnchor < first) { textInfoPtr->selectAnchor = first; } } } if (textPtr->insertPos > first) { - textPtr->insertPos -= count; + textPtr->insertPos -= charsRemoved; if (textPtr->insertPos < first) { textPtr->insertPos = first; } @@ -987,11 +1007,11 @@ TextToArea(canvas, itemPtr, rectPtr) /* ARGSUSED */ static void ScaleText(canvas, itemPtr, originX, originY, scaleX, scaleY) - Tk_Canvas canvas; /* Canvas containing rectangle. */ - Tk_Item *itemPtr; /* Rectangle to be scaled. */ - double originX, originY; /* Origin about which to scale rect. */ - double scaleX; /* Amount to scale in X direction. */ - double scaleY; /* Amount to scale in Y direction. */ + Tk_Canvas canvas; /* Canvas containing rectangle. */ + Tk_Item *itemPtr; /* Rectangle to be scaled. */ + double originX, originY; /* Origin about which to scale rect. */ + double scaleX; /* Amount to scale in X direction. */ + double scaleY; /* Amount to scale in Y direction. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -1022,10 +1042,9 @@ ScaleText(canvas, itemPtr, originX, originY, scaleX, scaleY) static void TranslateText(canvas, itemPtr, deltaX, deltaY) - Tk_Canvas canvas; /* Canvas containing item. */ - Tk_Item *itemPtr; /* Item that is being moved. */ - double deltaX, deltaY; /* Amount by which item is to be - * moved. */ + Tk_Canvas canvas; /* Canvas containing item. */ + Tk_Item *itemPtr; /* Item that is being moved. */ + double deltaX, deltaY; /* Amount by which item is to be moved. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -1046,7 +1065,7 @@ TranslateText(canvas, itemPtr, deltaX, deltaY) * A standard Tcl result. If all went well, then *indexPtr is * filled in with the index (into itemPtr) corresponding to * string. Otherwise an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -1062,7 +1081,8 @@ GetTextIndex(interp, canvas, itemPtr, string, indexPtr) * specified. */ char *string; /* Specification of a particular character * in itemPtr's text. */ - int *indexPtr; /* Where to store converted index. */ + int *indexPtr; /* Where to store converted character + * index. */ { TextItem *textPtr = (TextItem *) itemPtr; size_t length; @@ -1080,14 +1100,14 @@ GetTextIndex(interp, canvas, itemPtr, string, indexPtr) } else if ((c == 's') && (strncmp(string, "sel.first", length) == 0) && (length >= 5)) { if (textInfoPtr->selItemPtr != itemPtr) { - interp->result = "selection isn't in item"; + Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); return TCL_ERROR; } *indexPtr = textInfoPtr->selectFirst; } else if ((c == 's') && (strncmp(string, "sel.last", length) == 0) && (length >= 5)) { if (textInfoPtr->selItemPtr != itemPtr) { - interp->result = "selection isn't in item"; + Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); return TCL_ERROR; } *indexPtr = textInfoPtr->selectLast; @@ -1119,7 +1139,7 @@ GetTextIndex(interp, canvas, itemPtr, string, indexPtr) } } else { /* - * Some of the paths here leave messages in interp->result, + * Some of the paths here leave messages in the interp's result, * so we have to clear it out before storing our own message. */ @@ -1151,11 +1171,11 @@ GetTextIndex(interp, canvas, itemPtr, string, indexPtr) /* ARGSUSED */ static void SetTextCursor(canvas, itemPtr, index) - Tk_Canvas canvas; /* Record describing canvas widget. */ - Tk_Item *itemPtr; /* Text item in which cursor position - * is to be set. */ - int index; /* Index of character just before which - * cursor is to be positioned. */ + Tk_Canvas canvas; /* Record describing canvas widget. */ + Tk_Item *itemPtr; /* Text item in which cursor position is to + * be set. */ + int index; /* Character index of character just before + * which cursor is to be positioned. */ { TextItem *textPtr = (TextItem *) itemPtr; @@ -1191,34 +1211,38 @@ SetTextCursor(canvas, itemPtr, index) static int GetSelText(canvas, itemPtr, offset, buffer, maxBytes) - Tk_Canvas canvas; /* Canvas containing selection. */ - Tk_Item *itemPtr; /* Text item containing selection. */ - int offset; /* Offset within selection of first - * character to be returned. */ - char *buffer; /* Location in which to place - * selection. */ - int maxBytes; /* Maximum number of bytes to place - * at buffer, not including terminating - * NULL character. */ + Tk_Canvas canvas; /* Canvas containing selection. */ + Tk_Item *itemPtr; /* Text item containing selection. */ + int offset; /* Byte offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place selection. */ + int maxBytes; /* Maximum number of bytes to place at + * buffer, not including terminating NULL + * character. */ { TextItem *textPtr = (TextItem *) itemPtr; - int count; + int byteCount; + char *text, *selStart, *selEnd; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - count = textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst - offset; - if (textInfoPtr->selectLast == textPtr->numChars) { - count -= 1; + if ((textInfoPtr->selectFirst < 0) || + (textInfoPtr->selectFirst > textInfoPtr->selectLast)) { + return 0; } - if (count > maxBytes) { - count = maxBytes; + text = textPtr->text; + selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst); + selEnd = Tcl_UtfAtIndex(selStart, + textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst); + byteCount = selEnd - selStart - offset; + if (byteCount > maxBytes) { + byteCount = maxBytes; } - if (count <= 0) { + if (byteCount <= 0) { return 0; } - strncpy(buffer, textPtr->text + textInfoPtr->selectFirst + offset, - (size_t) count); - buffer[count] = '\0'; - return count; + memcpy(buffer, selStart + offset, (size_t) byteCount); + buffer[byteCount] = '\0'; + return byteCount; } /* @@ -1232,7 +1256,7 @@ GetSelText(canvas, itemPtr, offset, buffer, maxBytes) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used + * left in the interp's result, replacing whatever used * to be there. If no error occurs, then Postscript for the * item is appended to the result. * @@ -1244,14 +1268,12 @@ GetSelText(canvas, itemPtr, offset, buffer, maxBytes) static int TextToPostscript(interp, canvas, itemPtr, prepass) - Tcl_Interp *interp; /* Leave Postscript or error message - * here. */ - Tk_Canvas canvas; /* Information about overall canvas. */ - Tk_Item *itemPtr; /* Item for which Postscript is - * wanted. */ - int prepass; /* 1 means this is a prepass to - * collect font information; 0 means - * final Postscript is being created. */ + Tcl_Interp *interp; /* Leave Postscript or error message here. */ + Tk_Canvas canvas; /* Information about overall canvas. */ + Tk_Item *itemPtr; /* Item for which Postscript is wanted. */ + int prepass; /* 1 means this is a prepass to collect + * font information; 0 means final Postscript + * is being created. */ { TextItem *textPtr = (TextItem *) itemPtr; int x, y; diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c index 16a5ffa..7d203ec 100644 --- a/generic/tkCanvUtil.c +++ b/generic/tkCanvUtil.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvUtil.c,v 1.2 1998/09/14 18:23:06 stanton Exp $ + * RCS: @(#) $Id: tkCanvUtil.c,v 1.3 1999/04/16 01:51:12 stanton Exp $ */ #include "tk.h" @@ -177,7 +177,7 @@ Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) * TCL_OK is returned, then everything went well and the * canvas coordinate is stored at *doublePtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. diff --git a/generic/tkCanvWind.c b/generic/tkCanvWind.c index 5839cae..4dd8ee3 100644 --- a/generic/tkCanvWind.c +++ b/generic/tkCanvWind.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvWind.c,v 1.2 1998/09/14 18:23:06 stanton Exp $ + * RCS: @(#) $Id: tkCanvWind.c,v 1.3 1999/04/16 01:51:12 stanton Exp $ */ #include <stdio.h> @@ -147,7 +147,7 @@ static Tk_GeomMgr canvasGeomType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is + * the interp's result; in this case itemPtr is * left uninitialized, so it can be safely freed by the * caller. * @@ -214,7 +214,7 @@ CreateWinItem(interp, canvas, itemPtr, argc, argv) * details on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -248,8 +248,10 @@ WinItemCoords(interp, canvas, itemPtr, argc, argv) } ComputeWindowBbox(canvas, winItemPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 2, got %d", argc); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "wrong # coordinates: expected 0 or 2, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -265,7 +267,7 @@ WinItemCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information may be set for itemPtr. diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c index c095f7e..2ec336d 100644 --- a/generic/tkCanvas.c +++ b/generic/tkCanvas.c @@ -6,13 +6,13 @@ * objects such as rectangles, lines, and texts. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvas.c,v 1.3 1998/10/13 18:13:06 rjohnson Exp $ + * RCS: @(#) $Id: tkCanvas.c,v 1.4 1999/04/16 01:51:12 stanton Exp $ */ #include "default.h" @@ -152,20 +152,6 @@ extern Tk_ItemType tkOvalType, tkPolygonType; extern Tk_ItemType tkRectangleType, tkTextType, tkWindowType; /* - * Various Tk_Uid's used by this module (set up during initialization): - */ - -static Tk_Uid allUid = NULL; -static Tk_Uid currentUid = NULL; - -/* - * Statistics counters: - */ - -static int numIdSearches; -static int numSlowSearches; - -/* * Prototypes for procedures defined later in this file: */ @@ -356,7 +342,7 @@ Tk_CanvasCmd(clientData, interp, argc, argv) canvasPtr->nextId = 1; canvasPtr->psInfoPtr = NULL; Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS); - + Tk_SetClass(canvasPtr->tkwin, "Canvas"); TkSetClassProcs(canvasPtr->tkwin, &canvasClass, (ClientData) canvasPtr); Tk_CreateEventHandler(canvasPtr->tkwin, @@ -372,7 +358,7 @@ Tk_CanvasCmd(clientData, interp, argc, argv) goto error; } - interp->result = Tk_PathName(canvasPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(canvasPtr->tkwin), TCL_STATIC); return TCL_OK; error: @@ -475,7 +461,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv) } } if (gotAny) { - sprintf(interp->result, "%d %d %d %d", x1, y1, x2, y2); + char buf[TCL_INTEGER_SPACE * 4]; + + sprintf(buf, "%d %d %d %d", x1, y1, x2, y2); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 'b') && (strncmp(argv[1], "bind", length) == 0) && (length >= 2)) { @@ -565,15 +554,30 @@ CanvasWidgetCmd(clientData, interp, argc, argv) command = Tk_GetBinding(interp, canvasPtr->bindingTable, object, argv[3]); if (command == NULL) { - goto error; + char *string; + + string = Tcl_GetStringResult(interp); + /* + * Ignore missing binding errors. This is a special hack + * that relies on the error message returned by FindSequence + * in tkBind.c. + */ + + if (string[0] != '\0') { + goto error; + } else { + Tcl_ResetResult(interp); + } + } else { + Tcl_SetResult(interp, command, TCL_STATIC); } - interp->result = command; } else { Tk_GetAllBindings(interp, canvasPtr->bindingTable, object); } } else if ((c == 'c') && (strcmp(argv[1], "canvasx") == 0)) { int x; double grid; + char buf[TCL_DOUBLE_SPACE]; if ((argc < 3) || (argc > 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -593,10 +597,12 @@ CanvasWidgetCmd(clientData, interp, argc, argv) grid = 0.0; } x += canvasPtr->xOrigin; - Tcl_PrintDouble(interp, GridAlign((double) x, grid), interp->result); + Tcl_PrintDouble(interp, GridAlign((double) x, grid), buf); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'c') && (strcmp(argv[1], "canvasy") == 0)) { int y; double grid; + char buf[TCL_DOUBLE_SPACE]; if ((argc < 3) || (argc > 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -616,7 +622,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv) grid = 0.0; } y += canvasPtr->yOrigin; - Tcl_PrintDouble(interp, GridAlign((double) y, grid), interp->result); + Tcl_PrintDouble(interp, GridAlign((double) y, grid), buf); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) && (length >= 2)) { if (argc != 3) { @@ -667,9 +674,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv) Tk_ItemType *typePtr; Tk_ItemType *matchPtr = NULL; Tk_Item *itemPtr; + char buf[TCL_INTEGER_SPACE]; int isNew = 0; Tcl_HashEntry *entryPtr; - + if (argc < 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " create type ?arg arg ...?\"", (char *) NULL); @@ -722,7 +730,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv) Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2); canvasPtr->flags |= REPICK_NEEDED; - sprintf(interp->result, "%d", itemPtr->id); + sprintf(buf, "%d", itemPtr->id); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'd') && (strncmp(argv[1], "dchars", length) == 0) && (length >= 2)) { int first, last; @@ -870,7 +879,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv) itemPtr = canvasPtr->textInfo.focusItemPtr; if (argc == 2) { if (itemPtr != NULL) { - sprintf(interp->result, "%d", itemPtr->id); + char buf[TCL_INTEGER_SPACE]; + + sprintf(buf, "%d", itemPtr->id); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } goto done; } @@ -940,6 +952,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv) } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) && (length >= 3)) { int index; + char buf[TCL_INTEGER_SPACE]; if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -962,7 +975,8 @@ CanvasWidgetCmd(clientData, interp, argc, argv) itemPtr, argv[3], &index) != TCL_OK) { goto error; } - sprintf(interp->result, "%d", index); + sprintf(buf, "%d", index); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) && (length >= 3)) { int beforeThis; @@ -1145,7 +1159,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv) goto error; } if ((xScale == 0.0) || (yScale == 0.0)) { - interp->result = "scale factor cannot be zero"; + Tcl_SetResult(interp, "scale factor cannot be zero", TCL_STATIC); goto error; } for (itemPtr = StartTagSearch(canvasPtr, argv[2], &search); @@ -1280,8 +1294,10 @@ CanvasWidgetCmd(clientData, interp, argc, argv) goto error; } if (canvasPtr->textInfo.selItemPtr != NULL) { - sprintf(interp->result, "%d", - canvasPtr->textInfo.selItemPtr->id); + char buf[TCL_INTEGER_SPACE]; + + sprintf(buf, "%d", canvasPtr->textInfo.selItemPtr->id); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 't') && (strncmp(argv[2], "to", length) == 0)) { if (argc != 5) { @@ -1305,7 +1321,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv) } itemPtr = StartTagSearch(canvasPtr, argv[2], &search); if (itemPtr != NULL) { - interp->result = itemPtr->typePtr->name; + Tcl_SetResult(interp, itemPtr->typePtr->name, TCL_STATIC); } } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { int count, type; @@ -1317,7 +1333,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv) PrintScrollFractions(canvasPtr->xOrigin + canvasPtr->inset, canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin) - canvasPtr->inset, canvasPtr->scrollX1, - canvasPtr->scrollX2, interp->result); + canvasPtr->scrollX2, Tcl_GetStringResult(interp)); } else { type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); switch (type) { @@ -1355,7 +1371,7 @@ CanvasWidgetCmd(clientData, interp, argc, argv) PrintScrollFractions(canvasPtr->yOrigin + canvasPtr->inset, canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin) - canvasPtr->inset, canvasPtr->scrollY1, - canvasPtr->scrollY2, interp->result); + canvasPtr->scrollY2, Tcl_GetStringResult(interp)); } else { type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); switch (type) { @@ -1473,7 +1489,7 @@ DestroyCanvas(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, @@ -2141,8 +2157,6 @@ InitCanvas() tkBitmapType.nextPtr = &tkArcType; tkArcType.nextPtr = &tkWindowType; tkWindowType.nextPtr = NULL; - allUid = Tk_GetUid("all"); - currentUid = Tk_GetUid("current"); } /* @@ -2183,6 +2197,11 @@ StartTagSearch(canvasPtr, tag, searchPtr) Tk_Uid *tagPtr; Tk_Uid uid; int count; + TkWindow *tkwin; + TkDisplay *dispPtr; + + tkwin = (TkWindow *) canvasPtr->tkwin; + dispPtr = tkwin->dispPtr; /* * Initialize the search. @@ -2201,15 +2220,15 @@ StartTagSearch(canvasPtr, tag, searchPtr) if (isdigit(UCHAR(*tag))) { char *end; Tcl_HashEntry *entryPtr; - - numIdSearches++; + + dispPtr->numIdSearches++; id = strtoul(tag, &end, 0); if (*end == 0) { itemPtr = canvasPtr->hotPtr; - lastPtr = canvasPtr->hotPrevPtr; + lastPtr = canvasPtr->hotPrevPtr; if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL) || (lastPtr->nextPtr != itemPtr)) { - numSlowSearches++; + dispPtr->numSlowSearches++; entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id); if (entryPtr != NULL) { itemPtr = (Tk_Item *)Tcl_GetHashValue(entryPtr); @@ -2227,7 +2246,7 @@ StartTagSearch(canvasPtr, tag, searchPtr) } searchPtr->tag = uid = Tk_GetUid(tag); - if (uid == allUid) { + if (uid == Tk_GetUid("all")) { /* * All items match. @@ -2362,7 +2381,7 @@ NextItem(searchPtr) * * Side effects: * If tag is NULL then itemPtr's id is added as a list element - * to interp->result; otherwise tag is added to itemPtr's + * to the interp's result; otherwise tag is added to itemPtr's * list of tags. * *-------------------------------------------------------------- @@ -2384,7 +2403,8 @@ DoItem(interp, itemPtr, tag) */ if (tag == NULL) { - char msg[30]; + char msg[TCL_INTEGER_SPACE]; + sprintf(msg, "%d", itemPtr->id); Tcl_AppendElement(interp, msg); return; @@ -2438,9 +2458,9 @@ DoItem(interp, itemPtr, tag) * Results: * A standard Tcl return value. If newTag is NULL, then a * list of ids from all the items that match argc/argv is - * returned in interp->result. If newTag is NULL, then - * the normal interp->result is an empty string. If an error - * occurs, then interp->result will hold an error message. + * returned in the interp's result. If newTag is NULL, then + * the normal the interp's result is an empty string. If an error + * occurs, then the interp's result will hold an error message. * * Side effects: * If newTag is non-NULL, then all the items that match the @@ -2463,7 +2483,7 @@ FindItems(interp, canvasPtr, argc, argv, newTag, cmdName, option) char *newTag; /* If non-NULL, gives new tag to set * on all found items; if NULL, then * ids of found items are returned - * in interp->result. */ + * in the interp's result. */ char *cmdName; /* Name of original Tcl command, for * use in error messages. */ char *option; /* For error messages: gives option @@ -2671,9 +2691,9 @@ FindItems(interp, canvasPtr, argc, argv, newTag, cmdName, option) * Results: * A standard Tcl return value. If newTag is NULL, then a * list of ids from all the items overlapping or enclosed - * by the rectangle given by argc is returned in interp->result. - * If newTag is NULL, then the normal interp->result is an - * empty string. If an error occurs, then interp->result will + * by the rectangle given by argc is returned in the interp's result. + * If newTag is NULL, then the normal the interp's result is an + * empty string. If an error occurs, then the interp's result will * hold an error message. * * Side effects: @@ -2696,7 +2716,7 @@ FindArea(interp, canvasPtr, argv, uid, enclosed) Tk_Uid uid; /* If non-NULL, gives new tag to set * on all found items; if NULL, then * ids of found items are returned - * in interp->result. */ + * in the interp's result. */ int enclosed; /* 0 means overlapping or enclosed * items are OK, 1 means only enclosed * items are OK. */ @@ -3114,7 +3134,7 @@ PickCurrentItem(canvasPtr, eventPtr) if ((itemPtr == canvasPtr->currentItemPtr) && !buttonDown) { for (i = itemPtr->numTags-1; i >= 0; i--) { - if (itemPtr->tagPtr[i] == currentUid) { + if (itemPtr->tagPtr[i] == Tk_GetUid("current")) { itemPtr->tagPtr[i] = itemPtr->tagPtr[itemPtr->numTags-1]; itemPtr->numTags--; break; @@ -3144,7 +3164,8 @@ PickCurrentItem(canvasPtr, eventPtr) if (canvasPtr->currentItemPtr != NULL) { XEvent event; - DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr, currentUid); + DoItem((Tcl_Interp *) NULL, canvasPtr->currentItemPtr, + Tk_GetUid("current")); event = canvasPtr->pickEvent; event.type = EnterNotify; event.xcrossing.detail = NotifyAncestor; @@ -3260,7 +3281,7 @@ CanvasDoEvent(canvasPtr, eventPtr) objectPtr = (ClientData *) ckalloc((unsigned) (numObjects * sizeof(ClientData))); } - objectPtr[0] = (ClientData) allUid; + objectPtr[0] = (ClientData) Tk_GetUid("all"); for (i = itemPtr->numTags-1; i >= 0; i--) { objectPtr[i+1] = (ClientData) itemPtr->tagPtr[i]; } diff --git a/generic/tkClipboard.c b/generic/tkClipboard.c index 7df518a..e2a5187 100644 --- a/generic/tkClipboard.c +++ b/generic/tkClipboard.c @@ -6,12 +6,12 @@ * supplied on demand to requesting applications. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkClipboard.c,v 1.2 1998/09/14 18:23:07 stanton Exp $ + * RCS: @(#) $Id: tkClipboard.c,v 1.3 1999/04/16 01:51:12 stanton Exp $ */ #include "tkInt.h" @@ -226,7 +226,7 @@ ClipboardLostSel(clientData) * * Results: * A standard Tcl result. If an error occurs, an error message is - * left in interp->result. + * left in the interp's result. * * Side effects: * From now on, requests for the CLIPBOARD selection will be @@ -311,7 +311,7 @@ Tk_ClipboardClear(interp, tkwin) * * Results: * A standard Tcl result. If an error is returned, an error message - * is left in interp->result. + * is left in the interp's result. * * Side effects: * The specified buffer will be copied onto the end of the clipboard. @@ -528,9 +528,10 @@ Tk_ClipboardCmd(clientData, interp, argc, argv) } return Tk_ClipboardClear(interp, tkwin); } else { - sprintf(interp->result, - "bad option \"%.50s\": must be clear or append", - argv[1]); + char buf[100 + TCL_INTEGER_SPACE]; + + sprintf(buf, "bad option \"%.50s\": must be clear or append", argv[1]); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } } @@ -546,8 +547,8 @@ Tk_ClipboardCmd(clientData, interp, argc, argv) * * Results: * The result is a standard Tcl return value, which is normally TCL_OK. - * If an error occurs then an error message is left in interp->result - * and TCL_ERROR is returned. + * If an error occurs then an error message is left in the interp's + * result and TCL_ERROR is returned. * * Side effects: * Sets up the clipWindow and related data structures. diff --git a/generic/tkCmds.c b/generic/tkCmds.c index 19d05ca..b655fc0 100644 --- a/generic/tkCmds.c +++ b/generic/tkCmds.c @@ -5,13 +5,12 @@ * that didn't fit in any particular file of the toolkit. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. - * Copyright (c) 1998 by Scriptics Corporation. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCmds.c,v 1.5 1999/03/10 07:04:39 stanton Exp $ + * RCS: @(#) $Id: tkCmds.c,v 1.6 1999/04/16 01:51:12 stanton Exp $ */ #include "tkPort.h" @@ -26,6 +25,7 @@ #include "tkUnixInt.h" #endif + /* * Forward declarations for procedures defined later in this file: */ @@ -63,12 +63,10 @@ Tk_BellObjCmd(clientData, interp, objc, objv) int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { + static char *bellOptions[] = {"-displayof", (char *) NULL}; Tk_Window tkwin = (Tk_Window) clientData; + char *displayName; int index; - char *string; - static char *optionStrings[] = { - "-displayof", NULL - }; if ((objc != 1) && (objc != 3)) { Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window?"); @@ -76,12 +74,13 @@ Tk_BellObjCmd(clientData, interp, objc, objv) } if (objc == 3) { - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, + if (Tcl_GetIndexFromObj(interp, objv[1], bellOptions, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } - string = Tcl_GetStringFromObj(objv[2], NULL); - tkwin = Tk_NameToWindow(interp, string, tkwin); + displayName = Tcl_GetStringFromObj(objv[2], (int *) NULL); + + tkwin = Tk_NameToWindow(interp, displayName, tkwin); if (tkwin == NULL) { return TCL_ERROR; } @@ -162,7 +161,7 @@ Tk_BindCmd(clientData, interp, argc, argv) Tcl_ResetResult(interp); return TCL_OK; } - interp->result = command; + Tcl_SetResult(interp, command, TCL_STATIC); } else { Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object); } @@ -194,7 +193,6 @@ TkBindEventProc(winPtr, eventPtr) { #define MAX_OBJS 20 ClientData objects[MAX_OBJS], *objPtr; - static Tk_Uid allUid = NULL; TkWindow *topLevPtr; int i, count; char *p; @@ -242,10 +240,7 @@ TkBindEventProc(winPtr, eventPtr) } else { count = 3; } - if (allUid == NULL) { - allUid = Tk_GetUid("all"); - } - objPtr[count-1] = (ClientData) allUid; + objPtr[count-1] = (ClientData) Tk_GetUid("all"); } Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr, count, objPtr); @@ -606,7 +601,7 @@ Tk_TkObjCmd(clientData, interp, objc, objv) string = Tcl_GetStringFromObj(objv[2], NULL); winPtr->nameUid = Tk_GetUid(Tk_SetAppName(tkwin, string)); } - Tcl_SetStringObj(Tcl_GetObjResult(interp), winPtr->nameUid, -1); + Tcl_AppendResult(interp, winPtr->nameUid, NULL); break; } case TK_SCALING: { @@ -808,7 +803,7 @@ WaitWindowProc(clientData, eventPtr) /* *---------------------------------------------------------------------- * - * Tk_UpdateCmd -- + * Tk_UpdateObjCmd -- * * This procedure is invoked to process the "update" Tcl command. * See the user documentation for details on what it does. @@ -824,28 +819,27 @@ WaitWindowProc(clientData, eventPtr) /* ARGSUSED */ int -Tk_UpdateCmd(clientData, interp, argc, argv) +Tk_UpdateObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { - int flags; + static char *updateOptions[] = {"idletasks", (char *) NULL}; + int flags, index; TkDisplay *dispPtr; - if (argc == 1) { + if (objc == 1) { flags = TCL_DONT_WAIT; - } else if (argc == 2) { - if (strncmp(argv[1], "idletasks", strlen(argv[1])) != 0) { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be idletasks", (char *) NULL); + } else if (objc == 2) { + if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions, "option", 0, + &index) != TCL_OK) { return TCL_ERROR; } flags = TCL_IDLE_EVENTS; } else { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " ?idletasks?\"", (char *) NULL); + Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?"); return TCL_ERROR; } @@ -857,12 +851,12 @@ Tk_UpdateCmd(clientData, interp, argc, argv) * Thus, don't use any information from tkwin after calling * Tcl_DoOneEvent. */ - + while (1) { while (Tcl_DoOneEvent(flags) != 0) { /* Empty loop body */ } - for (dispPtr = tkDisplayList; dispPtr != NULL; + for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { XSync(dispPtr->display, False); } @@ -906,10 +900,10 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* Argument objects. */ { int index, x, y, width, height, useX, useY, class, skip; - char buf[128]; char *string; TkWindow *winPtr; Tk_Window tkwin; + Tcl_Obj *resultPtr; static TkStateMap visualMap[] = { {PseudoColor, "pseudocolor"}, @@ -982,85 +976,73 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) } } winPtr = (TkWindow *) tkwin; + resultPtr = Tcl_GetObjResult(interp); switch ((enum options) index) { case WIN_CELLS: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - Tk_Visual(tkwin)->map_entries); + Tcl_SetIntObj(resultPtr, Tk_Visual(tkwin)->map_entries); break; } case WIN_CHILDREN: { Tcl_Obj *strPtr; - Tcl_ResetResult(interp); winPtr = winPtr->childList; for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) { strPtr = Tcl_NewStringObj(winPtr->pathName, -1); - Tcl_ListObjAppendElement(NULL, - Tcl_GetObjResult(interp), strPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } break; } case WIN_CLASS: { - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_Class(tkwin), -1); + Tcl_SetStringObj(resultPtr, Tk_Class(tkwin), -1); break; } case WIN_COLORMAPFULL: { - Tcl_ResetResult(interp); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), + Tcl_SetBooleanObj(resultPtr, TkpCmapStressed(tkwin, Tk_Colormap(tkwin))); break; } case WIN_DEPTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Depth(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_Depth(tkwin)); break; } case WIN_GEOMETRY: { - Tcl_ResetResult(interp); + char buf[16 + TCL_INTEGER_SPACE * 4]; + sprintf(buf, "%dx%d+%d+%d", Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin)); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_SetStringObj(resultPtr, buf, -1); break; } case WIN_HEIGHT: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Height(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_Height(tkwin)); break; } case WIN_ID: { + char buf[TCL_INTEGER_SPACE]; + Tk_MakeWindowExist(tkwin); TkpPrintWindowId(buf, Tk_WindowId(tkwin)); - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_SetStringObj(resultPtr, buf, -1); break; } case WIN_ISMAPPED: { - Tcl_ResetResult(interp); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), - (int) Tk_IsMapped(tkwin)); + Tcl_SetBooleanObj(resultPtr, (int) Tk_IsMapped(tkwin)); break; } case WIN_MANAGER: { - Tcl_ResetResult(interp); if (winPtr->geomMgrPtr != NULL) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - winPtr->geomMgrPtr->name, -1); + Tcl_SetStringObj(resultPtr, winPtr->geomMgrPtr->name, -1); } break; } case WIN_NAME: { - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_Name(tkwin), -1); + Tcl_SetStringObj(resultPtr, Tk_Name(tkwin), -1); break; } case WIN_PARENT: { - Tcl_ResetResult(interp); if (winPtr->parentPtr != NULL) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - winPtr->parentPtr->pathName, -1); + Tcl_SetStringObj(resultPtr, winPtr->parentPtr->pathName, -1); } break; } @@ -1086,80 +1068,66 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) } else { TkGetPointerCoords((Tk_Window) winPtr, &x, &y); } - Tcl_ResetResult(interp); if (useX & useY) { + char buf[TCL_INTEGER_SPACE * 2]; + sprintf(buf, "%d %d", x, y); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_SetStringObj(resultPtr, buf, -1); } else if (useX) { - Tcl_SetIntObj(Tcl_GetObjResult(interp), x); + Tcl_SetIntObj(resultPtr, x); } else { - Tcl_SetIntObj(Tcl_GetObjResult(interp), y); + Tcl_SetIntObj(resultPtr, y); } break; } case WIN_REQHEIGHT: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_ReqHeight(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_ReqHeight(tkwin)); break; } case WIN_REQWIDTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_ReqWidth(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_ReqWidth(tkwin)); break; } case WIN_ROOTX: { Tk_GetRootCoords(tkwin, &x, &y); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), x); + Tcl_SetIntObj(resultPtr, x); break; } case WIN_ROOTY: { Tk_GetRootCoords(tkwin, &x, &y); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), y); + Tcl_SetIntObj(resultPtr, y); break; } case WIN_SCREEN: { + char buf[TCL_INTEGER_SPACE]; + sprintf(buf, "%d", Tk_ScreenNumber(tkwin)); - Tcl_ResetResult(interp); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - Tk_DisplayName(tkwin), ".", buf, NULL); + Tcl_AppendStringsToObj(resultPtr, Tk_DisplayName(tkwin), ".", + buf, NULL); break; } case WIN_SCREENCELLS: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - CellsOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, CellsOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENDEPTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - DefaultDepthOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, DefaultDepthOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENHEIGHT: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - HeightOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, HeightOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENWIDTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - WidthOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, WidthOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENMMHEIGHT: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - HeightMMOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, HeightMMOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENMMWIDTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), - WidthMMOfScreen(Tk_Screen(tkwin))); + Tcl_SetIntObj(resultPtr, WidthMMOfScreen(Tk_Screen(tkwin))); break; } case WIN_SCREENVISUAL: { @@ -1173,9 +1141,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) case WIN_TOPLEVEL: { winPtr = GetToplevel(tkwin); if (winPtr != NULL) { - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), - winPtr->pathName, -1); + Tcl_SetStringObj(resultPtr, winPtr->pathName, -1); } break; } @@ -1192,8 +1158,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) break; } } - Tcl_ResetResult(interp); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), viewable); + Tcl_SetBooleanObj(resultPtr, viewable); break; } case WIN_VISUAL: { @@ -1204,54 +1169,47 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) if (string == NULL) { string = "unknown"; } - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), string, -1); + Tcl_SetStringObj(resultPtr, string, -1); break; } case WIN_VISUALID: { - Tcl_ResetResult(interp); + char buf[TCL_INTEGER_SPACE]; + sprintf(buf, "0x%x", (unsigned int) XVisualIDFromVisual(Tk_Visual(tkwin))); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_SetStringObj(resultPtr, buf, -1); break; } case WIN_VROOTHEIGHT: { Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), height); + Tcl_SetIntObj(resultPtr, height); break; } case WIN_VROOTWIDTH: { Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), width); + Tcl_SetIntObj(resultPtr, width); break; } case WIN_VROOTX: { Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), x); + Tcl_SetIntObj(resultPtr, x); break; } case WIN_VROOTY: { Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), y); + Tcl_SetIntObj(resultPtr, y); break; } case WIN_WIDTH: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Width(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_Width(tkwin)); break; } case WIN_X: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_X(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_X(tkwin)); break; } case WIN_Y: { - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_Y(tkwin)); + Tcl_SetIntObj(resultPtr, Tk_Y(tkwin)); break; } @@ -1270,9 +1228,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) } objv += skip; string = Tcl_GetStringFromObj(objv[2], NULL); - Tcl_ResetResult(interp); - Tcl_SetLongObj(Tcl_GetObjResult(interp), - (long) Tk_InternAtom(tkwin, string)); + Tcl_SetLongObj(resultPtr, (long) Tk_InternAtom(tkwin, string)); break; } case WIN_ATOMNAME: { @@ -1291,15 +1247,14 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) if (Tcl_GetLongFromObj(interp, objv[2], &id) != TCL_OK) { return TCL_ERROR; } - Tcl_ResetResult(interp); name = Tk_GetAtomName(tkwin, (Atom) id); if (strcmp(name, "?bad atom?") == 0) { string = Tcl_GetStringFromObj(objv[2], NULL); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + Tcl_AppendStringsToObj(resultPtr, "no atom exists with id \"", string, "\"", NULL); return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); + Tcl_SetStringObj(resultPtr, name, -1); break; } case WIN_CONTAINING: { @@ -1323,9 +1278,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) } tkwin = Tk_CoordsToWindow(x, y, tkwin); if (tkwin != NULL) { - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), - Tk_PathName(tkwin), -1); + Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1); } break; } @@ -1362,9 +1315,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) Tk_IdToWindow(Tk_Display(tkwin), (Window) id); if ((winPtr == NULL) || (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr)) { - Tcl_ResetResult(interp); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "window id \"", string, + Tcl_AppendStringsToObj(resultPtr, "window id \"", string, "\" doesn't exist in this application", (char *) NULL); return TCL_ERROR; } @@ -1377,9 +1328,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) tkwin = (Tk_Window) winPtr; if (Tk_PathName(tkwin) != NULL) { - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), - Tk_PathName(tkwin), -1); + Tcl_SetStringObj(resultPtr, Tk_PathName(tkwin), -1); } break; } @@ -1397,12 +1346,14 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) } string = Tcl_GetStringFromObj(objv[2], NULL); winPtr = (TkWindow *) Tk_NameToWindow(interp, string, tkwin); + Tcl_ResetResult(interp); + resultPtr = Tcl_GetObjResult(interp); + alive = 1; if ((winPtr == NULL) || (winPtr->flags & TK_ALREADY_DEAD)) { alive = 0; } - Tcl_ResetResult(interp); /* clear any error msg */ - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), alive); + Tcl_SetBooleanObj(resultPtr, alive); break; } case WIN_FPIXELS: { @@ -1422,9 +1373,8 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } pixels = mm * WidthOfScreen(Tk_Screen(tkwin)) - / WidthMMOfScreen(Tk_Screen(tkwin)); - Tcl_ResetResult(interp); - Tcl_SetDoubleObj(Tcl_GetObjResult(interp), pixels); + / WidthMMOfScreen(Tk_Screen(tkwin)); + Tcl_SetDoubleObj(resultPtr, pixels); break; } case WIN_PIXELS: { @@ -1443,12 +1393,12 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) { return TCL_ERROR; } - Tcl_ResetResult(interp); - Tcl_SetIntObj(Tcl_GetObjResult(interp), pixels); + Tcl_SetIntObj(resultPtr, pixels); break; } case WIN_RGB: { XColor *colorPtr; + char buf[TCL_INTEGER_SPACE * 3]; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "window colorName"); @@ -1467,16 +1417,16 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) sprintf(buf, "%d %d %d", colorPtr->red, colorPtr->green, colorPtr->blue); Tk_FreeColor(colorPtr); - Tcl_ResetResult(interp); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_SetStringObj(resultPtr, buf, -1); break; } case WIN_VISUALSAVAILABLE: { XVisualInfo template, *visInfoPtr; int count, i; - char visualIdString[16]; int includeVisualId; Tcl_Obj *strPtr; + char buf[16 + TCL_INTEGER_SPACE]; + char visualIdString[TCL_INTEGER_SPACE]; if (objc == 3) { includeVisualId = 0; @@ -1498,9 +1448,8 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) template.screen = Tk_ScreenNumber(tkwin); visInfoPtr = XGetVisualInfo(Tk_Display(tkwin), VisualScreenMask, &template, &count); - Tcl_ResetResult(interp); if (visInfoPtr == NULL) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), + Tcl_SetStringObj(resultPtr, "can't find any visuals for screen", -1); return TCL_ERROR; } @@ -1517,8 +1466,7 @@ Tk_WinfoObjCmd(clientData, interp, objc, objv) strcat(buf, visualIdString); } strPtr = Tcl_NewStringObj(buf, -1); - Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), - strPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } XFree((char *) visInfoPtr); break; diff --git a/generic/tkColor.c b/generic/tkColor.c index 108bf70..e37b331 100644 --- a/generic/tkColor.c +++ b/generic/tkColor.c @@ -6,63 +6,157 @@ * map color names to pixel values. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkColor.c,v 1.2 1998/09/14 18:23:08 stanton Exp $ + * RCS: @(#) $Id: tkColor.c,v 1.3 1999/04/16 01:51:12 stanton Exp $ */ -#include <tkColor.h> +#include "tkColor.h" /* - * A two-level data structure is used to manage the color database. - * The top level consists of one entry for each color name that is - * currently active, and the bottom level contains one entry for each - * pixel value that is still in use. The distinction between - * levels is necessary because the same pixel may have several - * different names. There are two hash tables, one used to index into - * each of the data structures. The name hash table is used when - * allocating colors, and the pixel hash table is used when freeing - * colors. + * Structures of the following following type are used as keys for + * colorValueTable (in TkDisplay). */ - -/* - * Hash table for name -> TkColor mapping, and key structure used to - * index into that table: - */ - -static Tcl_HashTable nameTable; typedef struct { - Tk_Uid name; /* Name of desired color. */ + int red, green, blue; /* Values for desired color. */ Colormap colormap; /* Colormap from which color will be * allocated. */ Display *display; /* Display for colormap. */ -} NameKey; +} ValueKey; + /* - * Hash table for value -> TkColor mapping, and key structure used to - * index into that table: + * The structure below is used to allocate thread-local data. */ -static Tcl_HashTable valueTable; -typedef struct { - int red, green, blue; /* Values for desired color. */ - Colormap colormap; /* Colormap from which color will be - * allocated. */ - Display *display; /* Display for colormap. */ -} ValueKey; - -static int initialized = 0; /* 0 means static structures haven't been - * initialized yet. */ +typedef struct ThreadSpecificData { + char rgbString[20]; /* */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Forward declarations for procedures defined in this file: */ -static void ColorInit _ANSI_ARGS_((void)); +static void ColorInit _ANSI_ARGS_((TkDisplay *dispPtr)); +static void DupColorObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, + Tcl_Obj *dupObjPtr)); +static void FreeColorObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); +static void InitColorObj _ANSI_ARGS_((Tcl_Obj *objPtr)); + +/* + * The following structure defines the implementation of the "color" Tcl + * object, which maps a string color name to a TkColor object. The + * ptr1 field of the Tcl_Obj points to a TkColor object. + */ + +static Tcl_ObjType colorObjType = { + "color", /* name */ + FreeColorObjProc, /* freeIntRepProc */ + DupColorObjProc, /* dupIntRepProc */ + NULL, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + +/* + *---------------------------------------------------------------------- + * + * Tk_AllocColorFromObj -- + * + * Given a Tcl_Obj *, map the value to a corresponding + * XColor structure based on the tkwin given. + * + * Results: + * The return value is a pointer to an XColor structure that + * indicates the red, blue, and green intensities for the color + * given by the string in objPtr, and also specifies a pixel value + * to use to draw in that color. If an error occurs, NULL is + * returned and an error message will be left in interp's result + * (unless interp is NULL). + * + * Side effects: + * The color is added to an internal database with a reference count. + * For each call to this procedure, there should eventually be a call + * to Tk_FreeColorFromObj so that the database is cleaned up when colors + * aren't in use anymore. + * + *---------------------------------------------------------------------- + */ + +XColor * +Tk_AllocColorFromObj(interp, tkwin, objPtr) + Tcl_Interp *interp; /* Used only for error reporting. If NULL, + * then no messages are provided. */ + Tk_Window tkwin; /* Window in which the color will be used.*/ + Tcl_Obj *objPtr; /* Object that describes the color; string + * value is a color name such as "red" or + * "#ff0000".*/ +{ + TkColor *tkColPtr; + + if (objPtr->typePtr != &colorObjType) { + InitColorObj(objPtr); + } + tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + + /* + * If the object currently points to a TkColor, see if it's the + * one we want. If so, increment its reference count and return. + */ + + if (tkColPtr != NULL) { + if (tkColPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a TkColor that's + * no longer in use. Clear the reference. + */ + + FreeColorObjProc(objPtr); + tkColPtr = NULL; + } else if ((Tk_Screen(tkwin) == tkColPtr->screen) + && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { + tkColPtr->resourceRefCount++; + return (XColor *) tkColPtr; + } + } + + /* + * The object didn't point to the TkColor that we wanted. Search + * the list of TkColors with the same name to see if one of the + * other TkColors is the right one. + */ + + if (tkColPtr != NULL) { + TkColor *firstColorPtr = + (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr); + FreeColorObjProc(objPtr); + for (tkColPtr = firstColorPtr; tkColPtr != NULL; + tkColPtr = tkColPtr->nextPtr) { + if ((Tk_Screen(tkwin) == tkColPtr->screen) + && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { + tkColPtr->resourceRefCount++; + tkColPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr; + return (XColor *) tkColPtr; + } + } + } + + /* + * Still no luck. Call Tk_GetColor to allocate a new TkColor object. + */ + + tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr)); + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr; + if (tkColPtr != NULL) { + tkColPtr->objRefCount++; + } + return (XColor *) tkColPtr; +} /* *---------------------------------------------------------------------- @@ -77,7 +171,7 @@ static void ColorInit _ANSI_ARGS_((void)); * indicates the red, blue, and green intensities for the color * given by "name", and also specifies a pixel value to use to * draw in that color. If an error occurs, NULL is returned and - * an error message will be left in interp->result. + * an error message will be left in the interp's result. * * Side effects: * The color is added to an internal database with a reference count. @@ -93,17 +187,17 @@ Tk_GetColor(interp, tkwin, name) Tcl_Interp *interp; /* Place to leave error message if * color can't be found. */ Tk_Window tkwin; /* Window in which color will be used. */ - Tk_Uid name; /* Name of color to allocated (in form + char *name; /* Name of color to be allocated (in form * suitable for passing to XParseColor). */ { - NameKey nameKey; Tcl_HashEntry *nameHashPtr; int new; TkColor *tkColPtr; - Display *display = Tk_Display(tkwin); + TkColor *existingColPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - ColorInit(); + if (!dispPtr->colorInit) { + ColorInit(dispPtr); } /* @@ -111,14 +205,19 @@ Tk_GetColor(interp, tkwin, name) * name. */ - nameKey.name = name; - nameKey.colormap = Tk_Colormap(tkwin); - nameKey.display = display; - nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &nameKey, &new); + nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &new); if (!new) { - tkColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr); - tkColPtr->refCount++; - return &tkColPtr->color; + existingColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr); + for (tkColPtr = existingColPtr; tkColPtr != NULL; + tkColPtr = tkColPtr->nextPtr) { + if ((tkColPtr->screen == Tk_Screen(tkwin)) + && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { + tkColPtr->resourceRefCount++; + return &tkColPtr->color; + } + } + } else { + existingColPtr = NULL; } /* @@ -137,22 +236,27 @@ Tk_GetColor(interp, tkwin, name) "\"", (char *) NULL); } } - Tcl_DeleteHashEntry(nameHashPtr); + if (new) { + Tcl_DeleteHashEntry(nameHashPtr); + } return (XColor *) NULL; } /* - * Now create a new TkColor structure and add it to nameTable. + * Now create a new TkColor structure and add it to colorNameTable + * (in TkDisplay). */ tkColPtr->magic = COLOR_MAGIC; tkColPtr->gc = None; tkColPtr->screen = Tk_Screen(tkwin); - tkColPtr->colormap = nameKey.colormap; + tkColPtr->colormap = Tk_Colormap(tkwin); tkColPtr->visual = Tk_Visual(tkwin); - tkColPtr->refCount = 1; - tkColPtr->tablePtr = &nameTable; + tkColPtr->resourceRefCount = 1; + tkColPtr->objRefCount = 0; + tkColPtr->tablePtr = &dispPtr->colorNameTable; tkColPtr->hashPtr = nameHashPtr; + tkColPtr->nextPtr = existingColPtr; Tcl_SetHashValue(nameHashPtr, tkColPtr); return &tkColPtr->color; @@ -193,9 +297,10 @@ Tk_GetColorByValue(tkwin, colorPtr) int new; TkColor *tkColPtr; Display *display = Tk_Display(tkwin); + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { - ColorInit(); + if (!dispPtr->colorInit) { + ColorInit(dispPtr); } /* @@ -208,16 +313,17 @@ Tk_GetColorByValue(tkwin, colorPtr) valueKey.blue = colorPtr->blue; valueKey.colormap = Tk_Colormap(tkwin); valueKey.display = display; - valueHashPtr = Tcl_CreateHashEntry(&valueTable, (char *) &valueKey, &new); + valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable, + (char *) &valueKey, &new); if (!new) { tkColPtr = (TkColor *) Tcl_GetHashValue(valueHashPtr); - tkColPtr->refCount++; + tkColPtr->resourceRefCount++; return &tkColPtr->color; } /* * The name isn't currently known. Find a pixel value for this - * color and add a new structure to valueTable. + * color and add a new structure to colorValueTable (in TkDisplay). */ tkColPtr = TkpGetColorByValue(tkwin, colorPtr); @@ -226,9 +332,11 @@ Tk_GetColorByValue(tkwin, colorPtr) tkColPtr->screen = Tk_Screen(tkwin); tkColPtr->colormap = valueKey.colormap; tkColPtr->visual = Tk_Visual(tkwin); - tkColPtr->refCount = 1; - tkColPtr->tablePtr = &valueTable; + tkColPtr->resourceRefCount = 1; + tkColPtr->objRefCount = 0; + tkColPtr->tablePtr = &dispPtr->colorValueTable; tkColPtr->hashPtr = valueHashPtr; + tkColPtr->nextPtr = NULL; Tcl_SetHashValue(valueHashPtr, tkColPtr); return &tkColPtr->color; } @@ -260,15 +368,15 @@ Tk_NameOfColor(colorPtr) XColor *colorPtr; /* Color whose name is desired. */ { register TkColor *tkColPtr = (TkColor *) colorPtr; - static char string[20]; - - if ((tkColPtr->magic == COLOR_MAGIC) - && (tkColPtr->tablePtr == &nameTable)) { - return ((NameKey *) tkColPtr->hashPtr->key.words)->name; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tkColPtr->magic == COLOR_MAGIC) { + return tkColPtr->hashPtr->key.string; } - sprintf(string, "#%04x%04x%04x", colorPtr->red, colorPtr->green, - colorPtr->blue); - return string; + sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red, + colorPtr->green, colorPtr->blue); + return tsdPtr->rgbString; } /* @@ -347,8 +455,9 @@ Tk_FreeColor(colorPtr) * allocated by Tk_GetColor or * Tk_GetColorByValue. */ { - register TkColor *tkColPtr = (TkColor *) colorPtr; + TkColor *tkColPtr = (TkColor *) colorPtr; Screen *screen = tkColPtr->screen; + TkColor *prevPtr; /* * Do a quick sanity check to make sure this color was really @@ -359,15 +468,45 @@ Tk_FreeColor(colorPtr) panic("Tk_FreeColor called with bogus color"); } - tkColPtr->refCount--; - if (tkColPtr->refCount == 0) { - if (tkColPtr->gc != None) { - XFreeGC(DisplayOfScreen(screen), tkColPtr->gc); - tkColPtr->gc = None; + tkColPtr->resourceRefCount--; + if (tkColPtr->resourceRefCount > 0) { + return; + } + + /* + * This color is no longer being actively used, so free the color + * resources associated with it and remove it from the hash table. + * no longer any objects referencing it. + */ + + if (tkColPtr->gc != None) { + XFreeGC(DisplayOfScreen(screen), tkColPtr->gc); + tkColPtr->gc = None; + } + TkpFreeColor(tkColPtr); + + prevPtr = (TkColor *) Tcl_GetHashValue(tkColPtr->hashPtr); + if (prevPtr == tkColPtr) { + if (tkColPtr->nextPtr == NULL) { + Tcl_DeleteHashEntry(tkColPtr->hashPtr); + } else { + Tcl_SetHashValue(tkColPtr->hashPtr, tkColPtr->nextPtr); + } + } else { + while (prevPtr->nextPtr != tkColPtr) { + prevPtr = prevPtr->nextPtr; } - TkpFreeColor(tkColPtr); - Tcl_DeleteHashEntry(tkColPtr->hashPtr); - tkColPtr->magic = 0; + prevPtr->nextPtr = tkColPtr->nextPtr; + } + + /* + * Free the TkColor structure if there are no objects referencing + * it. However, if there are objects referencing it then keep the + * structure around; it will get freed when the last reference is + * cleared + */ + + if (tkColPtr->objRefCount == 0) { ckfree((char *) tkColPtr); } } @@ -375,6 +514,223 @@ Tk_FreeColor(colorPtr) /* *---------------------------------------------------------------------- * + * Tk_FreeColorFromObj -- + * + * This procedure is called to release a color allocated by + * Tk_AllocColorFromObj. It does not throw away the Tcl_Obj *; + * it only gets rid of the hash table entry for this color + * and clears the cached value that is normally stored in the object. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with the color represented by + * objPtr is decremented, and the color is released to X if there are + * no remaining uses for it. + * + *---------------------------------------------------------------------- + */ + +void +Tk_FreeColorFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window this color lives in. Needed + * for the screen and colormap values. */ + Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ +{ + Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr)); +} + +/* + *--------------------------------------------------------------------------- + * + * FreeColorObjProc -- + * + * This proc is called to release an object reference to a color. + * Called when the object's internal rep is released or when + * the cached tkColPtr needs to be changed. + * + * Results: + * None. + * + * Side effects: + * The object reference count is decremented. When both it + * and the hash ref count go to zero, the color's resources + * are released. + * + *--------------------------------------------------------------------------- + */ + +static void +FreeColorObjProc(objPtr) + Tcl_Obj *objPtr; /* The object we are releasing. */ +{ + TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + + if (tkColPtr != NULL) { + tkColPtr->objRefCount--; + if ((tkColPtr->objRefCount == 0) + && (tkColPtr->resourceRefCount == 0)) { + ckfree((char *) tkColPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; + } +} + +/* + *--------------------------------------------------------------------------- + * + * DupColorObjProc -- + * + * When a cached color object is duplicated, this is called to + * update the internal reps. + * + * Results: + * None. + * + * Side effects: + * The color's objRefCount is incremented and the internal rep + * of the copy is set to point to it. + * + *--------------------------------------------------------------------------- + */ + +static void +DupColorObjProc(srcObjPtr, dupObjPtr) + Tcl_Obj *srcObjPtr; /* The object we are copying from. */ + Tcl_Obj *dupObjPtr; /* The object we are copying to. */ +{ + TkColor *tkColPtr = (TkColor *) srcObjPtr->internalRep.twoPtrValue.ptr1; + + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr; + + if (tkColPtr != NULL) { + tkColPtr->objRefCount++; + } +} + +/* + *---------------------------------------------------------------------- + * + * Tk_GetColorFromObj -- + * + * Returns the color referred to by a Tcl object. The color must + * already have been allocated via a call to Tk_AllocColorFromObj + * or Tk_GetColor. + * + * Results: + * Returns the XColor * that matches the tkwin and the string rep + * of objPtr. + * + * Side effects: + * If the object is not already a color, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +XColor * +Tk_GetColorFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window in which the color will be + * used. */ + Tcl_Obj *objPtr; /* String value contains the name of the + * desired color. */ +{ + TkColor *tkColPtr; + Tcl_HashEntry *hashPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + if (objPtr->typePtr != &colorObjType) { + InitColorObj(objPtr); + } + + tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + if (tkColPtr != NULL) { + if ((tkColPtr->resourceRefCount > 0) + && (Tk_Screen(tkwin) == tkColPtr->screen) + && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { + /* + * The object already points to the right TkColor structure. + * Just return it. + */ + + return (XColor *) tkColPtr; + } + hashPtr = tkColPtr->hashPtr; + FreeColorObjProc(objPtr); + } else { + hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, + Tcl_GetString(objPtr)); + if (hashPtr == NULL) { + goto error; + } + } + + /* + * At this point we've got a hash table entry, off of which hang + * one or more TkColor structures. See if any of them will work. + */ + + for (tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr); + (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { + if ((Tk_Screen(tkwin) == tkColPtr->screen) + && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkColPtr; + tkColPtr->objRefCount++; + return (XColor *) tkColPtr; + } + } + + error: + panic(" Tk_GetColorFromObj called with non-existent color!"); + /* + * The following code isn't reached; it's just there to please compilers. + */ + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * InitColorObj -- + * + * Bookeeping procedure to change an objPtr to a color type. + * + * Results: + * None. + * + * Side effects: + * The old internal rep of the object is freed. The object's + * type is set to color with a NULL TkColor pointer (the pointer + * will be set later by either Tk_AllocColorFromObj or + * Tk_GetColorFromObj). + * + *---------------------------------------------------------------------- + */ + +static void +InitColorObj(objPtr) + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetString(objPtr); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &colorObjType; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; +} + +/* + *---------------------------------------------------------------------- + * * ColorInit -- * * Initialize the structure used for color management. @@ -389,9 +745,62 @@ Tk_FreeColor(colorPtr) */ static void -ColorInit() +ColorInit(dispPtr) + TkDisplay *dispPtr; +{ + if (!dispPtr->colorInit) { + dispPtr->colorInit = 1; + Tcl_InitHashTable(&dispPtr->colorNameTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&dispPtr->colorValueTable, + sizeof(ValueKey)/sizeof(int)); + } +} + +/* + *---------------------------------------------------------------------- + * + * TkDebugColor -- + * + * This procedure returns debugging information about a color. + * + * Results: + * The return value is a list with one sublist for each TkColor + * corresponding to "name". Each sublist has two elements that + * contain the resourceRefCount and objRefCount fields from the + * TkColor structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkDebugColor(tkwin, name) + Tk_Window tkwin; /* The window in which the color will be + * used (not currently used). */ + char *name; /* Name of the desired color. */ { - initialized = 1; - Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); - Tcl_InitHashTable(&valueTable, sizeof(ValueKey)/sizeof(int)); + TkColor *tkColPtr; + Tcl_HashEntry *hashPtr; + Tcl_Obj *resultPtr, *objPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + resultPtr = Tcl_NewObj(); + hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, name); + if (hashPtr != NULL) { + tkColPtr = (TkColor *) Tcl_GetHashValue(hashPtr); + if (tkColPtr == NULL) { + panic("TkDebugColor found empty hash table entry"); + } + for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(tkColPtr->resourceRefCount)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(tkColPtr->objRefCount)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return resultPtr; } diff --git a/generic/tkColor.h b/generic/tkColor.h index 8aa2e59..7e1ab3b 100644 --- a/generic/tkColor.h +++ b/generic/tkColor.h @@ -4,12 +4,12 @@ * Declarations of data types and functions used by the * Tk color module. * - * Copyright (c) 1996 by Sun Microsystems, Inc. + * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkColor.h,v 1.4 1998/09/14 18:23:08 stanton Exp $ + * RCS: @(#) $Id: tkColor.h,v 1.5 1999/04/16 01:51:12 stanton Exp $ */ #ifndef _TKCOLOR @@ -24,8 +24,8 @@ /* * One of the following data structures is used to keep track of - * each color that the color module has allocated from the X display - * server. + * each color that is being used by the application; typically there + * is a colormap entry allocated for each of these colors. */ #define COLOR_MAGIC ((unsigned int) 0x46140277) @@ -43,11 +43,30 @@ typedef struct TkColor { Colormap colormap; /* Colormap from which this entry was * allocated. */ Visual *visual; /* Visual associated with colormap. */ - int refCount; /* Number of uses of this structure. */ + int resourceRefCount; /* Number of active uses of this color (each + * active use corresponds to a call to + * Tk_AllocColorFromObj or Tk_GetColor). + * If this count is 0, then this TkColor + * structure is no longer valid and it isn't + * present in a hash table: it is being + * kept around only because there are objects + * referring to it. The structure is freed + * when resourceRefCount and objRefCount + * are both 0. */ + int objRefCount; /* The number of Tcl objects that reference + * this structure. */ Tcl_HashTable *tablePtr; /* Hash table that indexes this structure * (needed when deleting structure). */ Tcl_HashEntry *hashPtr; /* Pointer to hash table entry for this * structure. (for use in deleting entry). */ + struct TkColor *nextPtr; /* Points to the next TkColor structure with + * the same color name. Colors with the + * same name but different screens or + * colormaps are chained together off a + * single entry in nameTable. For colors in + * valueTable (those allocated by + * Tk_GetColorByValue) this field is always + * NULL. */ } TkColor; /* diff --git a/generic/tkConfig.c b/generic/tkConfig.c index 9714feb..0b78f4a 100644 --- a/generic/tkConfig.c +++ b/generic/tkConfig.c @@ -1,579 +1,1630 @@ /* * tkConfig.c -- * - * This file contains the Tk_ConfigureWidget procedure. + * This file contains procedures that manage configuration options + * for widgets and other things. * - * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1997-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkConfig.c,v 1.2 1998/09/14 18:23:08 stanton Exp $ + * RCS: @(#) $Id: tkConfig.c,v 1.3 1999/04/16 01:51:12 stanton Exp $ */ -#include "tkPort.h" +/* + * Temporary flag for working on new config package. + */ + +#if 0 + +/* + * used only for removing the old config code + */ + +#define __NO_OLD_CONFIG +#endif + #include "tk.h" +#include "tkInt.h" +#include "tkPort.h" +#include "tkFont.h" /* - * Values for "flags" field of Tk_ConfigSpec structures. Be sure - * to coordinate these values with those defined in tk.h - * (TK_CONFIG_COLOR_ONLY, etc.). There must not be overlap! + * The following definition is an AssocData key used to keep track of + * all of the option tables that have been created for an interpreter. + */ + +#define OPTION_HASH_KEY "TkOptionTable" + +/* + * The following two structures are used along with Tk_OptionSpec + * structures to manage configuration options. Tk_OptionSpecs are + * static templates that are compiled into the code of a widget + * or other object manager. However, to look up options efficiently + * we need to supplement the static information with additional + * dynamic information, and this dynamic information may be different + * for each application. Thus we create structures of the following + * two types to hold all of the dynamic information; this is done + * by Tk_CreateOptionTable. + * + * One of the following structures corresponds to each Tk_OptionSpec. + * These structures exist as arrays inside TkOptionTable structures. + */ + +typedef struct TkOption { + CONST Tk_OptionSpec *specPtr; /* The original spec from the template + * passed to Tk_CreateOptionTable.*/ + Tk_Uid dbNameUID; /* The Uid form of the option database + * name. */ + Tk_Uid dbClassUID; /* The Uid form of the option database + * class name. */ + Tcl_Obj *defaultPtr; /* Default value for this option. */ + union { + Tcl_Obj *monoColorPtr; /* For color and border options, this + * is an alternate default value to + * use on monochrome displays. */ + struct TkOption *synonymPtr; /* For synonym options, this points to + * the master entry. */ + } extra; + int flags; /* Miscellaneous flag values; see + * below for definitions. */ +} Option; + +/* + * Flag bits defined for Option structures: * - * INIT - Non-zero means (char *) things have been - * converted to Tk_Uid's. + * OPTION_NEEDS_FREEING - 1 means that FreeResources must be + * invoke to free resources associated with + * the option when it is no longer needed. */ -#define INIT 0x20 +#define OPTION_NEEDS_FREEING 1 + +/* + * One of the following exists for each Tk_OptionSpec array that has + * been passed to Tk_CreateOptionTable. + */ + +typedef struct OptionTable { + int refCount; /* Counts the number of uses of this + * table (the number of times + * Tk_CreateOptionTable has returned + * it). This can be greater than 1 if + * it is shared along several option + * table chains, or if the same table + * is used for multiple purposes. */ + Tcl_HashEntry *hashEntryPtr; /* Hash table entry that refers to this + * table; used to delete the entry. */ + struct OptionTable *nextPtr; /* If templatePtr was part of a chain + * of templates, this points to the + * table corresponding to the next + * template in the chain. */ + int numOptions; /* The number of items in the options + * array below. */ + Option options[1]; /* Information about the individual + * options in the table. This must be + * the last field in the structure: + * the actual size of the array will + * be numOptions, not 1. */ +} OptionTable; /* * Forward declarations for procedures defined later in this file: */ -static int DoConfig _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specPtr, - Tk_Uid value, int valueIsUid, char *widgRec)); -static Tk_ConfigSpec * FindConfigSpec _ANSI_ARGS_((Tcl_Interp *interp, - Tk_ConfigSpec *specs, char *argvName, - int needFlags, int hateFlags)); -static char * FormatConfigInfo _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specPtr, - char *widgRec)); -static char * FormatConfigValue _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, Tk_ConfigSpec *specPtr, - char *widgRec, char *buffer, - Tcl_FreeProc **freeProcPtr)); +static int DoObjConfig _ANSI_ARGS_((Tcl_Interp *interp, + char *recordPtr, Option *optionPtr, + Tcl_Obj *valuePtr, Tk_Window tkwin, + Tk_SavedOption *savePtr)); +static void DestroyOptionHashTable _ANSI_ARGS_(( + ClientData clientData, Tcl_Interp *interp)); +static void FreeResources _ANSI_ARGS_((Option *optionPtr, + Tcl_Obj *objPtr, char *internalPtr, + Tk_Window tkwin)); +static Tcl_Obj * GetConfigList _ANSI_ARGS_((char *recordPtr, + Option *optionPtr, Tk_Window tkwin)); +static Tcl_Obj * GetObjectForOption _ANSI_ARGS_((char *recordPtr, + Option *optionPtr, Tk_Window tkwin)); +static Option * GetOptionFromObj _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr, OptionTable *tablePtr)); +static int ObjectIsEmpty _ANSI_ARGS_((Tcl_Obj *objPtr)); +static int SetOptionFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); + +/* + * The structure below defines an object type that is used to cache the + * result of looking up an option name. If an object has this type, then + * its internalPtr1 field points to the OptionTable in which it was looked up, + * and the internalPtr2 field points to the entry that matched. + */ + +Tcl_ObjType optionType = { + "option", /* name */ + (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ + (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */ + (Tcl_UpdateStringProc *) NULL, /* updateStringProc */ + SetOptionFromAny /* setFromAnyProc */ +}; /* *-------------------------------------------------------------- * - * Tk_ConfigureWidget -- + * Tk_CreateOptionTable -- * - * Process command-line options and database options to - * fill in fields of a widget record with resources and - * other parameters. + * Given a template for configuration options, this procedure + * creates a table that may be used to look up options efficiently. * * Results: - * A standard Tcl return value. In case of an error, - * interp->result will hold an error message. + * Returns a token to a structure that can be passed to procedures + * such as Tk_InitOptions, Tk_SetOptions, and Tk_FreeConfigOptions. * * Side effects: - * The fields of widgRec get filled in with information - * from argc/argv and the option database. Old information - * in widgRec's fields gets recycled. + * Storage is allocated. * *-------------------------------------------------------------- */ -int -Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Window tkwin; /* Window containing widget (needed to - * set up X resources). */ - Tk_ConfigSpec *specs; /* Describes legal options. */ - int argc; /* Number of elements in argv. */ - char **argv; /* Command-line options. */ - char *widgRec; /* Record whose fields are to be - * modified. Values must be properly - * initialized. */ - int flags; /* Used to specify additional flags - * that must be present in config specs - * for them to be considered. Also, - * may have TK_CONFIG_ARGV_ONLY set. */ +Tk_OptionTable +Tk_CreateOptionTable(interp, templatePtr) + Tcl_Interp *interp; /* Interpreter associated with the + * application in which this table + * will be used. */ + CONST Tk_OptionSpec *templatePtr; /* Static information about the + * configuration options. */ { - register Tk_ConfigSpec *specPtr; - Tk_Uid value; /* Value of option from database. */ - int needFlags; /* Specs must contain this set of flags - * or else they are not considered. */ - int hateFlags; /* If a spec contains any bits here, it's - * not considered. */ - - needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); - if (Tk_Depth(tkwin) <= 1) { - hateFlags = TK_CONFIG_COLOR_ONLY; - } else { - hateFlags = TK_CONFIG_MONO_ONLY; + Tcl_HashTable *hashTablePtr; + Tcl_HashEntry *hashEntryPtr; + int newEntry; + OptionTable *tablePtr; + CONST Tk_OptionSpec *specPtr, *specPtr2; + Option *optionPtr; + int numOptions, i; + + /* + * We use an AssocData value in the interpreter to keep a hash + * table of all the option tables we've created for this application. + * This is used for two purposes. First, it allows us to share the + * tables (e.g. in several chains) and second, we use the deletion + * callback for the AssocData to delete all the option tables when + * the interpreter is deleted. The code below finds the hash table + * or creates a new one if it doesn't already exist. + */ + + hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY, + NULL); + if (hashTablePtr == NULL) { + hashTablePtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(hashTablePtr, TCL_ONE_WORD_KEYS); + Tcl_SetAssocData(interp, OPTION_HASH_KEY, DestroyOptionHashTable, + (ClientData) hashTablePtr); } /* - * Pass one: scan through all the option specs, replacing strings - * with Tk_Uids (if this hasn't been done already) and clearing - * the TK_CONFIG_OPTION_SPECIFIED flags. + * See if a table has already been created for this template. If + * so, just reuse the existing table. */ - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - if (!(specPtr->specFlags & INIT) && (specPtr->argvName != NULL)) { + hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr, + &newEntry); + if (!newEntry) { + tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr); + tablePtr->refCount++; + return (Tk_OptionTable) tablePtr; + } + + /* + * Count the number of options in the template, then create the + * table structure. + */ + + numOptions = 0; + for (specPtr = templatePtr; specPtr->type != TK_OPTION_END; specPtr++) { + numOptions++; + } + tablePtr = (OptionTable *) (ckalloc(sizeof(OptionTable) + + ((numOptions - 1) * sizeof(Option)))); + tablePtr->refCount = 1; + tablePtr->hashEntryPtr = hashEntryPtr; + tablePtr->nextPtr = NULL; + tablePtr->numOptions = numOptions; + + /* + * Initialize all of the Option structures in the table. + */ + + for (specPtr = templatePtr, optionPtr = tablePtr->options; + specPtr->type != TK_OPTION_END; specPtr++, optionPtr++) { + optionPtr->specPtr = specPtr; + optionPtr->dbNameUID = NULL; + optionPtr->dbClassUID = NULL; + optionPtr->defaultPtr = NULL; + optionPtr->extra.monoColorPtr = NULL; + optionPtr->flags = 0; + + if (specPtr->type == TK_OPTION_SYNONYM) { + /* + * This is a synonym option; find the master option that it + * refers to and create a pointer from the synonym to the + * master. + */ + + for (specPtr2 = templatePtr, i = 0; ; specPtr2++, i++) { + if (specPtr2->type == TK_OPTION_END) { + panic("Tk_CreateOptionTable couldn't find synonym"); + } + if (strcmp(specPtr2->optionName, + (char *) specPtr->clientData) == 0) { + optionPtr->extra.synonymPtr = tablePtr->options + i; + break; + } + } + } else { if (specPtr->dbName != NULL) { - specPtr->dbName = Tk_GetUid(specPtr->dbName); + optionPtr->dbNameUID = Tk_GetUid(specPtr->dbName); } if (specPtr->dbClass != NULL) { - specPtr->dbClass = Tk_GetUid(specPtr->dbClass); + optionPtr->dbClassUID = + Tk_GetUid(specPtr->dbClass); } if (specPtr->defValue != NULL) { - specPtr->defValue = Tk_GetUid(specPtr->defValue); + optionPtr->defaultPtr = + Tcl_NewStringObj(specPtr->defValue, -1); + Tcl_IncrRefCount(optionPtr->defaultPtr); + } + if (((specPtr->type == TK_OPTION_COLOR) + || (specPtr->type == TK_OPTION_BORDER)) + && (specPtr->clientData != NULL)) { + optionPtr->extra.monoColorPtr = + Tcl_NewStringObj((char *) specPtr->clientData, -1); + Tcl_IncrRefCount(optionPtr->extra.monoColorPtr); } } - specPtr->specFlags = (specPtr->specFlags & ~TK_CONFIG_OPTION_SPECIFIED) - | INIT; + if (((specPtr->type == TK_OPTION_STRING) + && (specPtr->internalOffset >= 0)) + || (specPtr->type == TK_OPTION_COLOR) + || (specPtr->type == TK_OPTION_FONT) + || (specPtr->type == TK_OPTION_BITMAP) + || (specPtr->type == TK_OPTION_BORDER) + || (specPtr->type == TK_OPTION_CURSOR)) { + optionPtr->flags |= OPTION_NEEDS_FREEING; + } } + tablePtr->hashEntryPtr = hashEntryPtr; + Tcl_SetHashValue(hashEntryPtr, tablePtr); /* - * Pass two: scan through all of the arguments, processing those - * that match entries in the specs. + * Finally, check to see if this template chains to another template + * with additional options. If so, call ourselves recursively to + * create the next table(s). */ - for ( ; argc > 0; argc -= 2, argv += 2) { - specPtr = FindConfigSpec(interp, specs, *argv, needFlags, hateFlags); - if (specPtr == NULL) { - return TCL_ERROR; + if (specPtr->clientData != NULL) { + tablePtr->nextPtr = (OptionTable *) Tk_CreateOptionTable(interp, + (Tk_OptionSpec *) specPtr->clientData); + } + + return (Tk_OptionTable) tablePtr; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_DeleteOptionTable -- + * + * Called to release resources used by an option table when + * the table is no longer needed. + * + * Results: + * None. + * + * Side effects: + * The option table and associated resources (such as additional + * option tables chained off it) are destroyed. + * + *---------------------------------------------------------------------- + */ + +void +Tk_DeleteOptionTable(optionTable) + Tk_OptionTable optionTable; /* The option table to delete. */ +{ + OptionTable *tablePtr = (OptionTable *) optionTable; + Option *optionPtr; + int count; + + tablePtr->refCount--; + if (tablePtr->refCount > 0) { + return; + } + + if (tablePtr->nextPtr != NULL) { + Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr); + } + + for (count = tablePtr->numOptions - 1, optionPtr = tablePtr->options; + count > 0; count--, optionPtr++) { + if (optionPtr->defaultPtr != NULL) { + Tcl_DecrRefCount(optionPtr->defaultPtr); } + if (((optionPtr->specPtr->type == TK_OPTION_COLOR) + || (optionPtr->specPtr->type == TK_OPTION_BORDER)) + && (optionPtr->extra.monoColorPtr != NULL)) { + Tcl_DecrRefCount(optionPtr->extra.monoColorPtr); + } + } + Tcl_DeleteHashEntry(tablePtr->hashEntryPtr); + ckfree((char *) tablePtr); +} + +/* + *---------------------------------------------------------------------- + * + * DestroyOptionHashTable -- + * + * This procedure is the deletion callback associated with the + * AssocData entry created by Tk_CreateOptionTable. It is + * invoked when an interpreter is deleted, and deletes all of + * the option tables associated with that interpreter. + * + * Results: + * None. + * + * Side effects: + * The option hash table is destroyed along with all of the + * OptionTable structures that it refers to. + * + *---------------------------------------------------------------------- + */ + +static void +DestroyOptionHashTable(clientData, interp) + ClientData clientData; /* The hash table we are destroying */ + Tcl_Interp *interp; /* The interpreter we are destroying */ +{ + Tcl_HashTable *hashTablePtr = (Tcl_HashTable *) clientData; + Tcl_HashSearch search; + Tcl_HashEntry *hashEntryPtr; + OptionTable *tablePtr; + + for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); + hashEntryPtr != NULL; + hashEntryPtr = Tcl_NextHashEntry(&search)) { + tablePtr = (OptionTable *) Tcl_GetHashValue(hashEntryPtr); /* - * Process the entry. + * The following statements do two tricky things: + * 1. They ensure that the option table is deleted, even if + * there are outstanding references to it. + * 2. They ensure that Tk_DeleteOptionTable doesn't delete + * other tables chained from this one; we'll do it when + * we come across the hash table entry for the chained + * table (in fact, the chained table may already have + * been deleted). */ - if (argc < 2) { - Tcl_AppendResult(interp, "value for \"", *argv, - "\" missing", (char *) NULL); - return TCL_ERROR; - } - if (DoConfig(interp, tkwin, specPtr, argv[1], 0, widgRec) != TCL_OK) { - char msg[100]; + tablePtr->refCount = 1; + tablePtr->nextPtr = NULL; + Tk_DeleteOptionTable((Tk_OptionTable) tablePtr); + } + Tcl_DeleteHashTable(hashTablePtr); + ckfree((char *) hashTablePtr); +} + +/* + *-------------------------------------------------------------- + * + * Tk_InitOptions -- + * + * This procedure is invoked when an object such as a widget + * is created. It supplies an initial value for each configuration + * option (the value may come from the option database, a system + * default, or the default in the option table). + * + * Results: + * The return value is TCL_OK if the procedure completed + * successfully, and TCL_ERROR if one of the initial values was + * bogus. If an error occurs and interp isn't NULL, then an + * error message will be left in its result. + * + * Side effects: + * Fields of recordPtr are filled in with initial values. + * + *-------------------------------------------------------------- + */ - sprintf(msg, "\n (processing \"%.40s\" option)", - specPtr->argvName); - Tcl_AddErrorInfo(interp, msg); +int +Tk_InitOptions(interp, recordPtr, optionTable, tkwin) + Tcl_Interp *interp; /* Interpreter for error reporting. NULL + * means don't leave an error message. */ + char *recordPtr; /* Pointer to the record to configure. + * Note: the caller should have properly + * initialized the record with NULL + * pointers for each option value. */ + Tk_OptionTable optionTable; /* The token which matches the config + * specs for the widget in question. */ + Tk_Window tkwin; /* Certain options types (such as + * TK_OPTION_COLOR) need fields out + * of the window they are used in to + * be able to calculate their values. + * Not needed unless one of these + * options is in the configSpecs record. */ +{ + OptionTable *tablePtr = (OptionTable *) optionTable; + Option *optionPtr; + int count; + char *value; + Tcl_Obj *valuePtr; + enum { + OPTION_DATABASE, SYSTEM_DEFAULT, TABLE_DEFAULT + } source; + + /* + * If this table chains to other tables, handle their initialization + * first. That way, if both tables refer to the same field of the + * record, the value in the first table will win. + */ + + if (tablePtr->nextPtr != NULL) { + if (Tk_InitOptions(interp, recordPtr, + (Tk_OptionTable) tablePtr->nextPtr, tkwin) != TCL_OK) { return TCL_ERROR; } - specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED; } /* - * Pass three: scan through all of the specs again; if no - * command-line argument matched a spec, then check for info - * in the option database. If there was nothing in the - * database, then use the default. + * Iterate over all of the options in the table, initializing each in + * turn. */ - if (!(flags & TK_CONFIG_ARGV_ONLY)) { - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED) - || (specPtr->argvName == NULL) - || (specPtr->type == TK_CONFIG_SYNONYM)) { - continue; + for (optionPtr = tablePtr->options, count = tablePtr->numOptions; + count > 0; optionPtr++, count--) { + + if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { + continue; + } + source = TABLE_DEFAULT; + + /* + * We look in three places for the initial value, using the first + * non-NULL value that we find. First, check the option database. + */ + + valuePtr = NULL; + if (optionPtr->dbNameUID != NULL) { + value = Tk_GetOption(tkwin, optionPtr->dbNameUID, + optionPtr->dbClassUID); + if (value != NULL) { + valuePtr = Tcl_NewStringObj(value, -1); + source = OPTION_DATABASE; } - if (((specPtr->specFlags & needFlags) != needFlags) - || (specPtr->specFlags & hateFlags)) { - continue; + } + + /* + * Second, check for a system-specific default value. + */ + + if ((valuePtr == NULL) + && (optionPtr->dbNameUID != NULL)) { + valuePtr = TkpGetSystemDefault(tkwin, optionPtr->dbNameUID, + optionPtr->dbClassUID); + if (valuePtr != NULL) { + source = SYSTEM_DEFAULT; } - value = NULL; - if (specPtr->dbName != NULL) { - value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass); + } + + /* + * Third and last, use the default value supplied by the option + * table. In the case of color objects, we pick one of two + * values depending on whether the screen is mono or color. + */ + + if (valuePtr == NULL) { + if ((tkwin != NULL) + && ((optionPtr->specPtr->type == TK_OPTION_COLOR) + || (optionPtr->specPtr->type == TK_OPTION_BORDER)) + && (Tk_Depth(tkwin) <= 1) + && (optionPtr->extra.monoColorPtr != NULL)) { + valuePtr = optionPtr->extra.monoColorPtr; + } else { + valuePtr = optionPtr->defaultPtr; } - if (value != NULL) { - if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != - TCL_OK) { - char msg[200]; + } + + if (valuePtr == NULL) { + continue; + } + + if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, + (Tk_SavedOption *) NULL) != TCL_OK) { + if (interp != NULL) { + char msg[200]; - sprintf(msg, "\n (%s \"%.50s\" in widget \"%.50s\")", - "database entry for", - specPtr->dbName, Tk_PathName(tkwin)); - Tcl_AddErrorInfo(interp, msg); - return TCL_ERROR; + switch (source) { + case OPTION_DATABASE: + sprintf(msg, "\n (database entry for \"%.50s\")", + optionPtr->specPtr->optionName); + break; + case SYSTEM_DEFAULT: + sprintf(msg, "\n (system default for \"%.50s\")", + optionPtr->specPtr->optionName); + break; + case TABLE_DEFAULT: + sprintf(msg, "\n (default value for \"%.50s\")", + optionPtr->specPtr->optionName); } - } else { - value = specPtr->defValue; - if ((value != NULL) && !(specPtr->specFlags - & TK_CONFIG_DONT_SET_DEFAULT)) { - if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != - TCL_OK) { - char msg[200]; - - sprintf(msg, - "\n (%s \"%.50s\" in widget \"%.50s\")", - "default value for", - specPtr->dbName, Tk_PathName(tkwin)); - Tcl_AddErrorInfo(interp, msg); - return TCL_ERROR; - } + if (tkwin != NULL) { + sprintf(msg + strlen(msg) - 1, " in widget \"%.50s\")", + Tk_PathName(tkwin)); } + Tcl_AddErrorInfo(interp, msg); } + return TCL_ERROR; } } - return TCL_OK; } /* *-------------------------------------------------------------- * - * FindConfigSpec -- + * DoObjConfig -- * - * Search through a table of configuration specs, looking for - * one that matches a given argvName. + * This procedure applies a new value for a configuration option + * to the record being configured. * * Results: - * The return value is a pointer to the matching entry, or NULL - * if nothing matched. In that case an error message is left - * in interp->result. + * The return value is TCL_OK if the procedure completed + * successfully. If an error occurred then TCL_ERROR is + * returned and an error message is left in interp's result, if + * interp isn't NULL. In addition, if oldValuePtrPtr isn't + * NULL then it *oldValuePtrPtr is filled in with a pointer + * to the option's old value. * * Side effects: - * None. + * RecordPtr gets modified to hold the new value in the form of + * a Tcl_Obj, an internal representation, or both. The old + * value is freed if oldValuePtrPtr is NULL. * *-------------------------------------------------------------- */ -static Tk_ConfigSpec * -FindConfigSpec(interp, specs, argvName, needFlags, hateFlags) - Tcl_Interp *interp; /* Used for reporting errors. */ - Tk_ConfigSpec *specs; /* Pointer to table of configuration - * specifications for a widget. */ - char *argvName; /* Name (suitable for use in a "config" - * command) identifying particular option. */ - int needFlags; /* Flags that must be present in matching - * entry. */ - int hateFlags; /* Flags that must NOT be present in - * matching entry. */ +static int +DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) + Tcl_Interp *interp; /* Interpreter for error reporting. If + * NULL, then no message is left if an error + * occurs. */ + char *recordPtr; /* The record to modify to hold the new + * option value. */ + Option *optionPtr; /* Pointer to information about the + * option. */ + Tcl_Obj *valuePtr; /* New value for option. */ + Tk_Window tkwin; /* Window in which option will be used (needed + * to allocate resources for some options). + * May be NULL if the option doesn't + * require window-related resources. */ + Tk_SavedOption *savedOptionPtr; + /* If NULL, the old value for the option will + * be freed. If non-NULL, the old value will + * be stored here, and it becomes the property + * of the caller (the caller must eventually + * free the old value). */ { - register Tk_ConfigSpec *specPtr; - register char c; /* First character of current argument. */ - Tk_ConfigSpec *matchPtr; /* Matching spec, or NULL. */ - size_t length; - - c = argvName[1]; - length = strlen(argvName); - matchPtr = NULL; - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - if (specPtr->argvName == NULL) { - continue; + Tcl_Obj **slotPtrPtr, *oldPtr; + char *internalPtr; /* Points to location in record where + * internal representation of value should + * be stored, or NULL. */ + char *oldInternalPtr; /* Points to location in which to save old + * internal representation of value. */ + Tk_SavedOption internal; /* Used to save the old internal representation + * of the value if savedOptionPtr is NULL. */ + CONST Tk_OptionSpec *specPtr; + int nullOK; + + /* + * Save the old object form for the value, if there is one. + */ + + specPtr = optionPtr->specPtr; + if (specPtr->objOffset >= 0) { + slotPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset); + oldPtr = *slotPtrPtr; + } else { + slotPtrPtr = NULL; + oldPtr = NULL; + } + + /* + * Apply the new value in a type-specific way. Also remember the + * old object and internal forms, if they exist. + */ + + if (specPtr->internalOffset >= 0) { + internalPtr = recordPtr + specPtr->internalOffset; + } else { + internalPtr = NULL; + } + if (savedOptionPtr != NULL) { + savedOptionPtr->optionPtr = optionPtr; + savedOptionPtr->valuePtr = oldPtr; + oldInternalPtr = (char *) &savedOptionPtr->internalForm; + } else { + oldInternalPtr = (char *) &internal.internalForm; + } + nullOK = (optionPtr->specPtr->flags & TK_OPTION_NULL_OK); + switch (optionPtr->specPtr->type) { + case TK_OPTION_BOOLEAN: { + int new; + + if (Tcl_GetBooleanFromObj(interp, valuePtr, &new) + != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = new; + } + break; } - if ((specPtr->argvName[1] != c) - || (strncmp(specPtr->argvName, argvName, length) != 0)) { - continue; + case TK_OPTION_INT: { + int new; + + if (Tcl_GetIntFromObj(interp, valuePtr, &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = new; + } + break; } - if (((specPtr->specFlags & needFlags) != needFlags) - || (specPtr->specFlags & hateFlags)) { - continue; + case TK_OPTION_DOUBLE: { + double new; + + if (Tcl_GetDoubleFromObj(interp, valuePtr, &new) + != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((double *) oldInternalPtr) = *((double *) internalPtr); + *((double *) internalPtr) = new; + } + break; + } + case TK_OPTION_STRING: { + char *new, *value; + int length; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + } + if (internalPtr != NULL) { + if (valuePtr != NULL) { + value = Tcl_GetStringFromObj(valuePtr, &length); + new = ckalloc((unsigned) (length + 1)); + strcpy(new, value); + } else { + new = NULL; + } + *((char **) oldInternalPtr) = *((char **) internalPtr); + *((char **) internalPtr) = new; + } + break; } - if (specPtr->argvName[length] == 0) { - matchPtr = specPtr; - goto gotMatch; + case TK_OPTION_STRING_TABLE: { + int new; + + if (Tcl_GetIndexFromObj(interp, valuePtr, + (char **) optionPtr->specPtr->clientData, + optionPtr->specPtr->optionName+1, 0, &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = new; + } + break; } - if (matchPtr != NULL) { - Tcl_AppendResult(interp, "ambiguous option \"", argvName, - "\"", (char *) NULL); - return (Tk_ConfigSpec *) NULL; + case TK_OPTION_COLOR: { + XColor *newPtr; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newPtr = NULL; + } else { + newPtr = Tk_AllocColorFromObj(interp, tkwin, valuePtr); + if (newPtr == NULL) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((XColor **) oldInternalPtr) = *((XColor **) internalPtr); + *((XColor **) internalPtr) = newPtr; + } + break; } - matchPtr = specPtr; - } + case TK_OPTION_FONT: { + Tk_Font new; - if (matchPtr == NULL) { - Tcl_AppendResult(interp, "unknown option \"", argvName, - "\"", (char *) NULL); - return (Tk_ConfigSpec *) NULL; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + new = NULL; + } else { + new = Tk_AllocFontFromObj(interp, tkwin, valuePtr); + if (new == NULL) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((Tk_Font *) oldInternalPtr) = *((Tk_Font *) internalPtr); + *((Tk_Font *) internalPtr) = new; + } + break; + } + case TK_OPTION_BITMAP: { + Pixmap new; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + new = None; + } else { + new = Tk_AllocBitmapFromObj(interp, tkwin, valuePtr); + if (new == None) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((Pixmap *) oldInternalPtr) = *((Pixmap *) internalPtr); + *((Pixmap *) internalPtr) = new; + } + break; + } + case TK_OPTION_BORDER: { + Tk_3DBorder new; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + new = NULL; + } else { + new = Tk_Alloc3DBorderFromObj(interp, tkwin, valuePtr); + if (new == NULL) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((Tk_3DBorder *) oldInternalPtr) = + *((Tk_3DBorder *) internalPtr); + *((Tk_3DBorder *) internalPtr) = new; + } + break; + } + case TK_OPTION_RELIEF: { + int new; + + if (Tk_GetReliefFromObj(interp, valuePtr, &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = new; + } + break; + } + case TK_OPTION_CURSOR: { + Tk_Cursor new; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + new = None; + valuePtr = NULL; + } else { + new = Tk_AllocCursorFromObj(interp, tkwin, valuePtr); + if (new == None) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr); + *((Tk_Cursor *) internalPtr) = new; + } + Tk_DefineCursor(tkwin, new); + break; + } + case TK_OPTION_JUSTIFY: { + Tk_Justify new; + + if (Tk_GetJustifyFromObj(interp, valuePtr, &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((Tk_Justify *) oldInternalPtr) + = *((Tk_Justify *) internalPtr); + *((Tk_Justify *) internalPtr) = new; + } + break; + } + case TK_OPTION_ANCHOR: { + Tk_Anchor new; + + if (Tk_GetAnchorFromObj(interp, valuePtr, &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((Tk_Anchor *) oldInternalPtr) + = *((Tk_Anchor *) internalPtr); + *((Tk_Anchor *) internalPtr) = new; + } + break; + } + case TK_OPTION_PIXELS: { + int new; + + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, + &new) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = new; + } + break; + } + case TK_OPTION_WINDOW: { + Tk_Window new; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + new = None; + } else { + if (TkGetWindowFromObj(interp, tkwin, valuePtr, &new) + != TCL_OK) { + return TCL_ERROR; + } + } + if (internalPtr != NULL) { + *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr); + *((Tk_Window *) internalPtr) = new; + } + break; + } + default: { + sprintf(interp->result, "bad config table: unknown type %d", + optionPtr->specPtr->type); + return TCL_ERROR; + } } /* - * Found a matching entry. If it's a synonym, then find the - * entry that it's a synonym for. + * Release resources associated with the old value, if we're not + * returning it to the caller, then install the new object value into + * the record. */ - gotMatch: - specPtr = matchPtr; - if (specPtr->type == TK_CONFIG_SYNONYM) { - for (specPtr = specs; ; specPtr++) { - if (specPtr->type == TK_CONFIG_END) { - Tcl_AppendResult(interp, - "couldn't find synonym for option \"", - argvName, "\"", (char *) NULL); - return (Tk_ConfigSpec *) NULL; - } - if ((specPtr->dbName == matchPtr->dbName) - && (specPtr->type != TK_CONFIG_SYNONYM) - && ((specPtr->specFlags & needFlags) == needFlags) - && !(specPtr->specFlags & hateFlags)) { - break; - } + if (savedOptionPtr == NULL) { + if (optionPtr->flags & OPTION_NEEDS_FREEING) { + FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin); + } + if (oldPtr != NULL) { + Tcl_DecrRefCount(oldPtr); } } - return specPtr; + if (slotPtrPtr != NULL) { + *slotPtrPtr = valuePtr; + if (valuePtr != NULL) { + Tcl_IncrRefCount(valuePtr); + } + } + return TCL_OK; } /* - *-------------------------------------------------------------- + *---------------------------------------------------------------------- * - * DoConfig -- + * ObjectIsEmpty -- * - * This procedure applies a single configuration option - * to a widget record. + * This procedure tests whether the string value of an object is + * empty. * * Results: - * A standard Tcl return value. + * The return value is 1 if the string value of objPtr has length + * zero, and 0 otherwise. * * Side effects: - * WidgRec is modified as indicated by specPtr and value. - * The old value is recycled, if that is appropriate for - * the value type. + * None. * - *-------------------------------------------------------------- + *---------------------------------------------------------------------- */ static int -DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Window tkwin; /* Window containing widget (needed to - * set up X resources). */ - Tk_ConfigSpec *specPtr; /* Specifier to apply. */ - char *value; /* Value to use to fill in widgRec. */ - int valueIsUid; /* Non-zero means value is a Tk_Uid; - * zero means it's an ordinary string. */ - char *widgRec; /* Record whose fields are to be - * modified. Values must be properly - * initialized. */ +ObjectIsEmpty(objPtr) + Tcl_Obj *objPtr; /* Object to test. May be NULL. */ { - char *ptr; - Tk_Uid uid; - int nullValue; + int length; - nullValue = 0; - if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { - nullValue = 1; + if (objPtr == NULL) { + return 1; } + if (objPtr->bytes != NULL) { + return (objPtr->length == 0); + } + Tcl_GetStringFromObj(objPtr, &length); + return (length == 0); +} + +/* + *---------------------------------------------------------------------- + * + * GetOptionFromObj -- + * + * This procedure searches through a chained option table to find + * the entry for a particular option name. + * + * Results: + * The return value is a pointer to the matching entry, or NULL + * if no matching entry could be found. If NULL is returned and + * interp is not NULL than an error message is left in its result. + * Note: if the matching entry is a synonym then this procedure + * returns a pointer to the synonym entry, *not* the "real" entry + * that the synonym refers to. + * + * Side effects: + * Information about the matching entry is cached in the object + * containing the name, so that future lookups can proceed more + * quickly. + * + *---------------------------------------------------------------------- + */ - do { - ptr = widgRec + specPtr->offset; - switch (specPtr->type) { - case TK_CONFIG_BOOLEAN: - if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { - return TCL_ERROR; - } - break; - case TK_CONFIG_INT: - if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) { - return TCL_ERROR; - } - break; - case TK_CONFIG_DOUBLE: - if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) { - return TCL_ERROR; - } - break; - case TK_CONFIG_STRING: { - char *old, *new; +static Option * +GetOptionFromObj(interp, objPtr, tablePtr) + Tcl_Interp *interp; /* Used only for error reporting; if NULL + * no message is left after an error. */ + Tcl_Obj *objPtr; /* Object whose string value is to be + * looked up in the option table. */ + OptionTable *tablePtr; /* Table in which to look up objPtr. */ +{ + Option *bestPtr, *optionPtr; + OptionTable *tablePtr2; + char *p1, *p2, *name; + int count; - if (nullValue) { - new = NULL; - } else { - new = (char *) ckalloc((unsigned) (strlen(value) + 1)); - strcpy(new, value); - } - old = *((char **) ptr); - if (old != NULL) { - ckfree(old); + /* + * First, check to see if the object already has the answer cached. + */ + + if (objPtr->typePtr == &optionType) { + if (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr) { + return (Option *) objPtr->internalRep.twoPtrValue.ptr2; + } + } + + /* + * The answer isn't cached. Search through all of the option tables + * in the chain to find the best match. Some tricky aspects: + * + * 1. We have to accept unique abbreviations. + * 2. The same name could appear in different tables in the chain. + * If this happens, we use the entry from the first table. We + * have to be careful to distinguish this case from an ambiguous + * abbreviation. + */ + + bestPtr = NULL; + name = Tcl_GetStringFromObj(objPtr, (int *) NULL); + for (tablePtr2 = tablePtr; tablePtr2 != NULL; + tablePtr2 = tablePtr2->nextPtr) { + for (optionPtr = tablePtr2->options, count = tablePtr2->numOptions; + count > 0; optionPtr++, count--) { + for (p1 = name, p2 = optionPtr->specPtr->optionName; + *p1 == *p2; p1++, p2++) { + if (*p1 == 0) { + /* + * This is an exact match. We're done. + */ + + bestPtr = optionPtr; + goto done; } - *((char **) ptr) = new; - break; } - case TK_CONFIG_UID: - if (nullValue) { - *((Tk_Uid *) ptr) = NULL; - } else { - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - *((Tk_Uid *) ptr) = uid; - } - break; - case TK_CONFIG_COLOR: { - XColor *newPtr, *oldPtr; + if (*p1 == 0) { + /* + * The name is an abbreviation for this option. Keep + * to make sure that the abbreviation only matches one + * option name. If we've already found a match in the + * past, then it is an error unless the full names for + * the two options are identical; in this case, the first + * option overrides the second. + */ - if (nullValue) { - newPtr = NULL; + if (bestPtr == NULL) { + bestPtr = optionPtr; } else { - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - newPtr = Tk_GetColor(interp, tkwin, uid); - if (newPtr == NULL) { - return TCL_ERROR; + if (strcmp(bestPtr->specPtr->optionName, + optionPtr->specPtr->optionName) != 0) { + goto error; } } - oldPtr = *((XColor **) ptr); - if (oldPtr != NULL) { - Tk_FreeColor(oldPtr); - } - *((XColor **) ptr) = newPtr; - break; } - case TK_CONFIG_FONT: { - Tk_Font new; + } + } + if (bestPtr == NULL) { + goto error; + } - if (nullValue) { - new = NULL; - } else { - new = Tk_GetFont(interp, tkwin, value); - if (new == NULL) { - return TCL_ERROR; - } - } - Tk_FreeFont(*((Tk_Font *) ptr)); - *((Tk_Font *) ptr) = new; - break; + done: + if ((objPtr->typePtr != NULL) + && (objPtr->typePtr->freeIntRepProc != NULL)) { + objPtr->typePtr->freeIntRepProc(objPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tablePtr; + objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) bestPtr; + objPtr->typePtr = &optionType; + return bestPtr; + + error: + if (interp != NULL) { + Tcl_AppendResult(interp, "unknown option \"", name, + "\"", (char *) NULL); + } + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * SetOptionFromAny -- + * + * This procedure is called to convert a Tcl object to option + * internal form. However, this doesn't make sense (need to have a + * table of options in order to do the conversion) so the + * procedure always generates an error. + * + * Results: + * The return value is always TCL_ERROR, and an error message is + * left in interp's result if interp isn't NULL. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +SetOptionFromAny(interp, objPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + register Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_AppendToObj(Tcl_GetObjResult(interp), + "can't convert value to option except via GetOptionFromObj API", + -1); + return TCL_ERROR; +} + +/* + *-------------------------------------------------------------- + * + * Tk_SetOptions -- + * + * Process one or more name-value pairs for configuration options + * and fill in fields of a record with new values. + * + * Results: + * If all goes well then TCL_OK is returned and the old values of + * any modified objects are saved in *savePtr, if it isn't NULL (the + * caller must eventually call Tk_RestoreSavedOptions or + * Tk_FreeSavedOptions to free the contents of *savePtr). In + * addition, if maskPtr isn't NULL then *maskPtr is filled in with + * the OR of the typeMask bits from all modified options. If an + * error occurs then TCL_ERROR is returned and a message + * is left in interp's result unless interp is NULL; nothing is + * saved in *savePtr or *maskPtr in this case. + * + * Side effects: + * The fields of recordPtr get filled in with object pointers + * from objc/objv. Old information in widgRec's fields gets + * recycled. Information may be left at *savePtr. + * + *-------------------------------------------------------------- + */ + +int +Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, + maskPtr) + Tcl_Interp *interp; /* Interpreter for error reporting. + * If NULL, then no error message is + * returned.*/ + char *recordPtr; /* The record to configure. */ + Tk_OptionTable optionTable; /* Describes valid options. */ + int objc; /* The number of elements in objv. */ + Tcl_Obj *CONST objv[]; /* Contains one or more name-value + * pairs. */ + Tk_Window tkwin; /* Window associated with the thing + * being configured; needed for some + * options (such as colors). */ + Tk_SavedOptions *savePtr; /* If non-NULL, the old values of + * modified options are saved here + * so that they can be restored + * after an error. */ + int *maskPtr; /* It non-NULL, this word is modified + * on a successful return to hold the + * bit-wise OR of the typeMask fields + * of all options that were modified + * by this call. Used by the caller + * to figure out which options + * actually changed. */ +{ + OptionTable *tablePtr = (OptionTable *) optionTable; + Option *optionPtr; + Tk_SavedOptions *lastSavePtr, *newSavePtr; + int mask; + + if (savePtr != NULL) { + savePtr->recordPtr = recordPtr; + savePtr->tkwin = tkwin; + savePtr->numItems = 0; + savePtr->nextPtr = NULL; + } + lastSavePtr = savePtr; + + /* + * Scan through all of the arguments, processing those + * that match entries in the option table. + */ + + mask = 0; + for ( ; objc > 0; objc -= 2, objv += 2) { + optionPtr = GetOptionFromObj(interp, objv[0], tablePtr); + if (optionPtr == NULL) { + goto error; + } + if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { + optionPtr = optionPtr->extra.synonymPtr; + } + + if (objc < 2) { + if (interp != NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "value for \"", Tcl_GetStringFromObj(*objv, NULL), + "\" missing", (char *) NULL); + goto error; } - case TK_CONFIG_BITMAP: { - Pixmap new, old; + } + if ((savePtr != NULL) + && (lastSavePtr->numItems >= TK_NUM_SAVED_OPTIONS)) { + /* + * We've run out of space for saving old option values. Allocate + * more space. + */ - if (nullValue) { - new = None; - } else { - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - new = Tk_GetBitmap(interp, tkwin, uid); - if (new == None) { - return TCL_ERROR; - } + newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof( + Tk_SavedOptions)); + newSavePtr->recordPtr = recordPtr; + newSavePtr->tkwin = tkwin; + newSavePtr->numItems = 0; + newSavePtr->nextPtr = NULL; + lastSavePtr->nextPtr = newSavePtr; + lastSavePtr = newSavePtr; + } + if (DoObjConfig(interp, recordPtr, optionPtr, objv[1], tkwin, + (savePtr != NULL) ? &lastSavePtr->items[lastSavePtr->numItems] + : (Tk_SavedOption *) NULL) != TCL_OK) { + char msg[100]; + + sprintf(msg, "\n (processing \"%.40s\" option)", + Tcl_GetStringFromObj(*objv, NULL)); + Tcl_AddErrorInfo(interp, msg); + goto error; + } + if (savePtr != NULL) { + lastSavePtr->numItems++; + } + mask |= optionPtr->specPtr->typeMask; + } + if (maskPtr != NULL) { + *maskPtr = mask; + } + return TCL_OK; + + error: + if (savePtr != NULL) { + Tk_RestoreSavedOptions(savePtr); + } + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_RestoreSavedOptions -- + * + * This procedure undoes the effect of a previous call to + * Tk_SetOptions by restoring all of the options to their value + * before the call to Tk_SetOptions. + * + * Results: + * None. + * + * Side effects: + * The configutation record is restored and all the information + * stored in savePtr is freed. + * + *---------------------------------------------------------------------- + */ + +void +Tk_RestoreSavedOptions(savePtr) + Tk_SavedOptions *savePtr; /* Holds saved option information; must + * have been passed to Tk_SetOptions. */ +{ + int i; + Option *optionPtr; + Tcl_Obj *newPtr; /* New object value of option, which we + * replace with old value and free. Taken + * from record. */ + char *internalPtr; /* Points to internal value of option in + * record. */ + CONST Tk_OptionSpec *specPtr; + + /* + * Be sure to restore the options in the opposite order they were + * set. This is important because it's possible that the same + * option name was used twice in a single call to Tk_SetOptions. + */ + + if (savePtr->nextPtr != NULL) { + Tk_RestoreSavedOptions(savePtr->nextPtr); + ckfree((char *) savePtr->nextPtr); + savePtr->nextPtr = NULL; + } + for (i = savePtr->numItems - 1; i >= 0; i--) { + optionPtr = savePtr->items[i].optionPtr; + specPtr = optionPtr->specPtr; + + /* + * First free the new value of the option, which is currently + * in the record. + */ + + if (specPtr->objOffset >= 0) { + newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset)); + } else { + newPtr = NULL; + } + if (specPtr->internalOffset >= 0) { + internalPtr = savePtr->recordPtr + specPtr->internalOffset; + } else { + internalPtr = NULL; + } + if (optionPtr->flags & OPTION_NEEDS_FREEING) { + FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin); + } + if (newPtr != NULL) { + Tcl_DecrRefCount(newPtr); + } + + /* + * Now restore the old value of the option. + */ + + if (specPtr->objOffset >= 0) { + *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset)) + = savePtr->items[i].valuePtr; + } + if (specPtr->internalOffset >= 0) { + switch (specPtr->type) { + case TK_OPTION_BOOLEAN: { + *((int *) internalPtr) + = *((int *) &savePtr->items[i].internalForm); + break; } - old = *((Pixmap *) ptr); - if (old != None) { - Tk_FreeBitmap(Tk_Display(tkwin), old); + case TK_OPTION_INT: { + *((int *) internalPtr) + = *((int *) &savePtr->items[i].internalForm); + break; } - *((Pixmap *) ptr) = new; - break; - } - case TK_CONFIG_BORDER: { - Tk_3DBorder new, old; - - if (nullValue) { - new = NULL; - } else { - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - new = Tk_Get3DBorder(interp, tkwin, uid); - if (new == NULL) { - return TCL_ERROR; - } + case TK_OPTION_DOUBLE: { + *((double *) internalPtr) + = *((double *) &savePtr->items[i].internalForm); + break; } - old = *((Tk_3DBorder *) ptr); - if (old != NULL) { - Tk_Free3DBorder(old); + case TK_OPTION_STRING: { + *((char **) internalPtr) + = *((char **) &savePtr->items[i].internalForm); + break; } - *((Tk_3DBorder *) ptr) = new; - break; - } - case TK_CONFIG_RELIEF: - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_STRING_TABLE: { + *((int *) internalPtr) + = *((int *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_CURSOR: - case TK_CONFIG_ACTIVE_CURSOR: { - Tk_Cursor new, old; - - if (nullValue) { - new = None; - } else { - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - new = Tk_GetCursor(interp, tkwin, uid); - if (new == None) { - return TCL_ERROR; - } + case TK_OPTION_COLOR: { + *((XColor **) internalPtr) + = *((XColor **) &savePtr->items[i].internalForm); + break; } - old = *((Tk_Cursor *) ptr); - if (old != None) { - Tk_FreeCursor(Tk_Display(tkwin), old); + case TK_OPTION_FONT: { + *((Tk_Font *) internalPtr) + = *((Tk_Font *) &savePtr->items[i].internalForm); + break; } - *((Tk_Cursor *) ptr) = new; - if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) { - Tk_DefineCursor(tkwin, new); + case TK_OPTION_BITMAP: { + *((Pixmap *) internalPtr) + = *((Pixmap *) &savePtr->items[i].internalForm); + break; } - break; - } - case TK_CONFIG_JUSTIFY: - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_BORDER: { + *((Tk_3DBorder *) internalPtr) + = *((Tk_3DBorder *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_ANCHOR: - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_RELIEF: { + *((int *) internalPtr) + = *((int *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_CAP_STYLE: - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_CURSOR: { + *((Tk_Cursor *) internalPtr) + = *((Tk_Cursor *) &savePtr->items[i].internalForm); + Tk_DefineCursor(savePtr->tkwin, + *((Tk_Cursor *) internalPtr)); + break; } - break; - case TK_CONFIG_JOIN_STYLE: - uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); - if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_JUSTIFY: { + *((Tk_Justify *) internalPtr) + = *((Tk_Justify *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_PIXELS: - if (Tk_GetPixels(interp, tkwin, value, (int *) ptr) - != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_ANCHOR: { + *((Tk_Anchor *) internalPtr) + = *((Tk_Anchor *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_MM: - if (Tk_GetScreenMM(interp, tkwin, value, (double *) ptr) - != TCL_OK) { - return TCL_ERROR; + case TK_OPTION_PIXELS: { + *((int *) internalPtr) + = *((int *) &savePtr->items[i].internalForm); + break; + } + case TK_OPTION_WINDOW: { + *((Tk_Window *) internalPtr) + = *((Tk_Window *) &savePtr->items[i].internalForm); + break; } - break; - case TK_CONFIG_WINDOW: { - Tk_Window tkwin2; + default: { + panic("bad option type in Tk_RestoreSavedOptions"); + } + } + } + } + savePtr->numItems = 0; +} + +/* + *-------------------------------------------------------------- + * + * Tk_FreeSavedOptions -- + * + * Free all of the saved configuration option values from a + * previous call to Tk_SetOptions. + * + * Results: + * None. + * + * Side effects: + * Storage and system resources are freed. + * + *-------------------------------------------------------------- + */ - if (nullValue) { - tkwin2 = NULL; - } else { - tkwin2 = Tk_NameToWindow(interp, value, tkwin); - if (tkwin2 == NULL) { - return TCL_ERROR; - } +void +Tk_FreeSavedOptions(savePtr) + Tk_SavedOptions *savePtr; /* Contains options saved in a previous + * call to Tk_SetOptions. */ +{ + int count; + Tk_SavedOption *savedOptionPtr; + + if (savePtr->nextPtr != NULL) { + Tk_FreeSavedOptions(savePtr->nextPtr); + ckfree((char *) savePtr->nextPtr); + } + for (count = savePtr->numItems, + savedOptionPtr = &savePtr->items[savePtr->numItems-1]; + count > 0; count--, savedOptionPtr--) { + if (savedOptionPtr->optionPtr->flags & OPTION_NEEDS_FREEING) { + FreeResources(savedOptionPtr->optionPtr, savedOptionPtr->valuePtr, + (char *) &savedOptionPtr->internalForm, savePtr->tkwin); + } + if (savedOptionPtr->valuePtr != NULL) { + Tcl_DecrRefCount(savedOptionPtr->valuePtr); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * Tk_FreeConfigOptions -- + * + * Free all resources associated with configuration options. + * + * Results: + * None. + * + * Side effects: + * All of the Tcl_Obj's in recordPtr that are controlled by + * configuration options in optionTable are freed. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +void +Tk_FreeConfigOptions(recordPtr, optionTable, tkwin) + char *recordPtr; /* Record whose fields contain current + * values for options. */ + Tk_OptionTable optionTable; /* Describes legal options. */ + Tk_Window tkwin; /* Window associated with recordPtr; needed + * for freeing some options. */ +{ + OptionTable *tablePtr; + Option *optionPtr; + int count; + Tcl_Obj **oldPtrPtr, *oldPtr; + char *oldInternalPtr; + CONST Tk_OptionSpec *specPtr; + + for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL; + tablePtr = tablePtr->nextPtr) { + for (optionPtr = tablePtr->options, count = tablePtr->numOptions; + count > 0; optionPtr++, count--) { + specPtr = optionPtr->specPtr; + if (specPtr->type == TK_OPTION_SYNONYM) { + continue; + } + if (specPtr->objOffset >= 0) { + oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset); + oldPtr = *oldPtrPtr; + *oldPtrPtr = NULL; + } else { + oldPtr = NULL; + } + if (specPtr->internalOffset >= 0) { + oldInternalPtr = recordPtr + specPtr->internalOffset; + } else { + oldInternalPtr = NULL; + } + if (optionPtr->flags & OPTION_NEEDS_FREEING) { + FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin); + } + if (oldPtr != NULL) { + Tcl_DecrRefCount(oldPtr); + } + } + } +} + +/* + *---------------------------------------------------------------------- + * + * FreeResources -- + * + * Free system resources associated with a configuration option, + * such as colors or fonts. + * + * Results: + * None. + * + * Side effects: + * Any system resources associated with objPtr are released. However, + * objPtr itself is not freed. + * + *---------------------------------------------------------------------- + */ + +static void +FreeResources(optionPtr, objPtr, internalPtr, tkwin) + Option *optionPtr; /* Description of the configuration option. */ + Tcl_Obj *objPtr; /* The current value of the option, specified + * as an object. */ + char *internalPtr; /* A pointer to an internal representation for + * the option's value, such as an int or + * (XColor *). Only valid if + * optionPtr->specPtr->internalOffset >= 0. */ + Tk_Window tkwin; /* The window in which this option is used. */ +{ + int internalFormExists; + + /* + * If there exists an internal form for the value, use it to free + * resources (also zero out the internal form). If there is no + * internal form, then use the object form. + */ + + internalFormExists = optionPtr->specPtr->internalOffset >= 0; + switch (optionPtr->specPtr->type) { + case TK_OPTION_STRING: + if (internalFormExists) { + if (*((char **) internalPtr) != NULL) { + ckfree(*((char **) internalPtr)); + *((char **) internalPtr) = NULL; } - *((Tk_Window *) ptr) = tkwin2; - break; } - case TK_CONFIG_CUSTOM: - if ((*specPtr->customPtr->parseProc)( - specPtr->customPtr->clientData, interp, tkwin, - value, widgRec, specPtr->offset) != TCL_OK) { - return TCL_ERROR; + break; + case TK_OPTION_COLOR: + if (internalFormExists) { + if (*((XColor **) internalPtr) != NULL) { + Tk_FreeColor(*((XColor **) internalPtr)); + *((XColor **) internalPtr) = NULL; } - break; - default: { - sprintf(interp->result, "bad config table: unknown type %d", - specPtr->type); - return TCL_ERROR; + } else if (objPtr != NULL) { + Tk_FreeColorFromObj(tkwin, objPtr); } - } - specPtr++; - } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); - return TCL_OK; + break; + case TK_OPTION_FONT: + if (internalFormExists) { + Tk_FreeFont(*((Tk_Font *) internalPtr)); + *((Tk_Font *) internalPtr) = NULL; + } else if (objPtr != NULL) { + Tk_FreeFontFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_BITMAP: + if (internalFormExists) { + if (*((Pixmap *) internalPtr) != None) { + Tk_FreeBitmap(Tk_Display(tkwin), *((Pixmap *) internalPtr)); + *((Pixmap *) internalPtr) = None; + } + } else if (objPtr != NULL) { + Tk_FreeBitmapFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_BORDER: + if (internalFormExists) { + if (*((Tk_3DBorder *) internalPtr) != NULL) { + Tk_Free3DBorder(*((Tk_3DBorder *) internalPtr)); + *((Tk_3DBorder *) internalPtr) = NULL; + } + } else if (objPtr != NULL) { + Tk_Free3DBorderFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_CURSOR: + if (internalFormExists) { + if (*((Tk_Cursor *) internalPtr) != None) { + Tk_FreeCursor(Tk_Display(tkwin), + *((Tk_Cursor *) internalPtr)); + *((Tk_Cursor *) internalPtr) = None; + } + } else if (objPtr != NULL) { + Tk_FreeCursorFromObj(tkwin, objPtr); + } + break; + default: + break; + } } /* *-------------------------------------------------------------- * - * Tk_ConfigureInfo -- + * Tk_GetOptionInfo -- * - * Return information about the configuration options - * for a window, and their current values. + * Returns a list object containing complete information about + * either a single option or all the configuration options in a + * table. * * Results: - * Always returns TCL_OK. Interp->result will be modified - * hold a description of either a single configuration option - * available for "widgRec" via "specs", or all the configuration - * options available. In the "all" case, the result will - * available for "widgRec" via "specs". The result will - * be a list, each of whose entries describes one option. - * Each entry will itself be a list containing the option's - * name for use on command lines, database name, database - * class, default value, and current value (empty string - * if none). For options that are synonyms, the list will - * contain only two values: name and synonym name. If the - * "name" argument is non-NULL, then the only information - * returned is that for the named argument (i.e. the corresponding - * entry in the overall list is returned). + * This procedure normally returns a pointer to an object. + * If namePtr isn't NULL, then the result object is a list with + * five elements: the option's name, its database name, database + * class, default value, and current value. If the option is a + * synonym then the list will contain only two values: the option + * name and the name of the option it refers to. If namePtr is + * NULL, then information is returned for every option in the + * option table: the result will have one sub-list (in the form + * described above) for each option in the table. If an error + * occurs (e.g. because namePtr isn't valid) then NULL is returned + * and an error message will be left in interp's result unless + * interp is NULL. * * Side effects: * None. @@ -581,47 +1632,40 @@ DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec) *-------------------------------------------------------------- */ -int -Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Window tkwin; /* Window corresponding to widgRec. */ - Tk_ConfigSpec *specs; /* Describes legal options. */ - char *widgRec; /* Record whose fields contain current +Tcl_Obj * +Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) + Tcl_Interp *interp; /* Interpreter for error reporting. If + * NULL, then no error message is created. */ + char *recordPtr; /* Record whose fields contain current * values for options. */ - char *argvName; /* If non-NULL, indicates a single option - * whose info is to be returned. Otherwise - * info is returned for all options. */ - int flags; /* Used to specify additional flags - * that must be present in config specs - * for them to be considered. */ + Tk_OptionTable optionTable; /* Describes all the legal options. */ + Tcl_Obj *namePtr; /* If non-NULL, the string value selects + * a single option whose info is to be + * returned. Otherwise info is returned for + * all options in optionTable. */ + Tk_Window tkwin; /* Window associated with recordPtr; needed + * to compute correct default value for some + * options. */ { - register Tk_ConfigSpec *specPtr; - int needFlags, hateFlags; - char *list; - char *leader = "{"; - - needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); - if (Tk_Depth(tkwin) <= 1) { - hateFlags = TK_CONFIG_COLOR_ONLY; - } else { - hateFlags = TK_CONFIG_MONO_ONLY; - } + Tcl_Obj *resultPtr; + OptionTable *tablePtr = (OptionTable *) optionTable; + Option *optionPtr; + int count; /* * If information is only wanted for a single configuration * spec, then handle that one spec specially. */ - Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); - if (argvName != NULL) { - specPtr = FindConfigSpec(interp, specs, argvName, needFlags, - hateFlags); - if (specPtr == NULL) { - return TCL_ERROR; + if (namePtr != NULL) { + optionPtr = GetOptionFromObj(interp, namePtr, tablePtr); + if (optionPtr == NULL) { + return (Tcl_Obj *) NULL; } - interp->result = FormatConfigInfo(interp, tkwin, specPtr, widgRec); - interp->freeProc = TCL_DYNAMIC; - return TCL_OK; + if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { + optionPtr = optionPtr->extra.synonymPtr; + } + return GetConfigList(recordPtr, optionPtr, tkwin); } /* @@ -629,29 +1673,21 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) * their information. */ - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - if ((argvName != NULL) && (specPtr->argvName != argvName)) { - continue; - } - if (((specPtr->specFlags & needFlags) != needFlags) - || (specPtr->specFlags & hateFlags)) { - continue; - } - if (specPtr->argvName == NULL) { - continue; + resultPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); + for (; tablePtr != NULL; tablePtr = tablePtr->nextPtr) { + for (optionPtr = tablePtr->options, count = tablePtr->numOptions; + count > 0; optionPtr++, count--) { + Tcl_ListObjAppendElement(interp, resultPtr, + GetConfigList(recordPtr, optionPtr, tkwin)); } - list = FormatConfigInfo(interp, tkwin, specPtr, widgRec); - Tcl_AppendResult(interp, leader, list, "}", (char *) NULL); - ckfree(list); - leader = " {"; } - return TCL_OK; + return resultPtr; } /* *-------------------------------------------------------------- * - * FormatConfigInfo -- + * GetConfigList -- * * Create a valid Tcl list holding the configuration information * for a single configuration option. @@ -666,67 +1702,78 @@ Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) *-------------------------------------------------------------- */ -static char * -FormatConfigInfo(interp, tkwin, specPtr, widgRec) - Tcl_Interp *interp; /* Interpreter to use for things - * like floating-point precision. */ - Tk_Window tkwin; /* Window corresponding to widget. */ - register Tk_ConfigSpec *specPtr; /* Pointer to information describing - * option. */ - char *widgRec; /* Pointer to record holding current - * values of info for widget. */ +static Tcl_Obj * +GetConfigList(recordPtr, optionPtr, tkwin) + char *recordPtr; /* Pointer to record holding current + * values of configuration options. */ + Option *optionPtr; /* Pointer to information describing a + * particular option. */ + Tk_Window tkwin; /* Window corresponding to recordPtr. */ { - char *argv[6], *result; - char buffer[200]; - Tcl_FreeProc *freeProc = (Tcl_FreeProc *) NULL; - - argv[0] = specPtr->argvName; - argv[1] = specPtr->dbName; - argv[2] = specPtr->dbClass; - argv[3] = specPtr->defValue; - if (specPtr->type == TK_CONFIG_SYNONYM) { - return Tcl_Merge(2, argv); - } - argv[4] = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, - &freeProc); - if (argv[1] == NULL) { - argv[1] = ""; - } - if (argv[2] == NULL) { - argv[2] = ""; - } - if (argv[3] == NULL) { - argv[3] = ""; - } - if (argv[4] == NULL) { - argv[4] = ""; - } - result = Tcl_Merge(5, argv); - if (freeProc != NULL) { - if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) { - ckfree(argv[4]); + Tcl_Obj *listPtr, *elementPtr; + + listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, + Tcl_NewStringObj(optionPtr->specPtr->optionName, -1)); + + if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { + elementPtr = Tcl_NewStringObj( + optionPtr->extra.synonymPtr->specPtr->optionName, -1); + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr); + } else { + if (optionPtr->dbNameUID == NULL) { + elementPtr = Tcl_NewObj(); + } else { + elementPtr = Tcl_NewStringObj(optionPtr->dbNameUID, -1); + } + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr); + + if (optionPtr->dbClassUID == NULL) { + elementPtr = Tcl_NewObj(); + } else { + elementPtr = Tcl_NewStringObj(optionPtr->dbClassUID, -1); + } + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr); + + if ((tkwin != NULL) && ((optionPtr->specPtr->type == TK_OPTION_COLOR) + || (optionPtr->specPtr->type == TK_OPTION_BORDER)) + && (Tk_Depth(tkwin) <= 1) + && (optionPtr->extra.monoColorPtr != NULL)) { + elementPtr = optionPtr->extra.monoColorPtr; + } else if (optionPtr->defaultPtr != NULL) { + elementPtr = optionPtr->defaultPtr; } else { - (*freeProc)(argv[4]); + elementPtr = Tcl_NewObj(); } + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr); + + if (optionPtr->specPtr->objOffset >= 0) { + elementPtr = *((Tcl_Obj **) (recordPtr + + optionPtr->specPtr->objOffset)); + if (elementPtr == NULL) { + elementPtr = Tcl_NewObj(); + } + } else { + elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin); + } + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, elementPtr); } - return result; + return listPtr; } /* *---------------------------------------------------------------------- * - * FormatConfigValue -- + * GetObjectForOption -- * - * This procedure formats the current value of a configuration - * option. + * This procedure is called to create an object that contains the + * value for an option. It is invoked by GetConfigList and + * Tk_GetOptionValue when only the internal form of an option is + * stored in the record. * * Results: - * The return value is the formatted value of the option given - * by specPtr and widgRec. If the value is static, so that it - * need not be freed, *freeProcPtr will be set to NULL; otherwise - * *freeProcPtr will be set to the address of a procedure to - * free the result, and the caller must invoke this procedure - * when it is finished with the result. + * The return value is a pointer to a Tcl object. The caller + * must call Tcl_IncrRefCount on this object to preserve it. * * Side effects: * None. @@ -734,146 +1781,130 @@ FormatConfigInfo(interp, tkwin, specPtr, widgRec) *---------------------------------------------------------------------- */ -static char * -FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr) - Tcl_Interp *interp; /* Interpreter for use in real conversions. */ - Tk_Window tkwin; /* Window corresponding to widget. */ - Tk_ConfigSpec *specPtr; /* Pointer to information describing option. - * Must not point to a synonym option. */ - char *widgRec; /* Pointer to record holding current - * values of info for widget. */ - char *buffer; /* Static buffer to use for small values. - * Must have at least 200 bytes of storage. */ - Tcl_FreeProc **freeProcPtr; /* Pointer to word to fill in with address - * of procedure to free the result, or NULL - * if result is static. */ +static Tcl_Obj * +GetObjectForOption(recordPtr, optionPtr, tkwin) + char *recordPtr; /* Pointer to record holding current + * values of configuration options. */ + Option *optionPtr; /* Pointer to information describing an + * option whose internal value is stored + * in *recordPtr. */ + Tk_Window tkwin; /* Window corresponding to recordPtr. */ { - char *ptr, *result; - - *freeProcPtr = NULL; - ptr = widgRec + specPtr->offset; - result = ""; - switch (specPtr->type) { - case TK_CONFIG_BOOLEAN: - if (*((int *) ptr) == 0) { - result = "0"; - } else { - result = "1"; - } + Tcl_Obj *objPtr; + char *internalPtr; /* Points to internal value of option in + * record. */ + + internalPtr = recordPtr + optionPtr->specPtr->internalOffset; + objPtr = NULL; + switch (optionPtr->specPtr->type) { + case TK_OPTION_BOOLEAN: { + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); break; - case TK_CONFIG_INT: - sprintf(buffer, "%d", *((int *) ptr)); - result = buffer; + } + case TK_OPTION_INT: { + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); break; - case TK_CONFIG_DOUBLE: - Tcl_PrintDouble(interp, *((double *) ptr), buffer); - result = buffer; + } + case TK_OPTION_DOUBLE: { + objPtr = Tcl_NewDoubleObj(*((double *) internalPtr)); break; - case TK_CONFIG_STRING: - result = (*(char **) ptr); - if (result == NULL) { - result = ""; - } + } + case TK_OPTION_STRING: { + objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1); break; - case TK_CONFIG_UID: { - Tk_Uid uid = *((Tk_Uid *) ptr); - if (uid != NULL) { - result = uid; - } + } + case TK_OPTION_STRING_TABLE: { + objPtr = Tcl_NewStringObj( + ((char **) optionPtr->specPtr->clientData)[ + *((int *) internalPtr)], -1); break; } - case TK_CONFIG_COLOR: { - XColor *colorPtr = *((XColor **) ptr); + case TK_OPTION_COLOR: { + XColor *colorPtr = *((XColor **) internalPtr); if (colorPtr != NULL) { - result = Tk_NameOfColor(colorPtr); + objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1); } break; } - case TK_CONFIG_FONT: { - Tk_Font tkfont = *((Tk_Font *) ptr); + case TK_OPTION_FONT: { + Tk_Font tkfont = *((Tk_Font *) internalPtr); if (tkfont != NULL) { - result = Tk_NameOfFont(tkfont); + objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1); } break; } - case TK_CONFIG_BITMAP: { - Pixmap pixmap = *((Pixmap *) ptr); + case TK_OPTION_BITMAP: { + Pixmap pixmap = *((Pixmap *) internalPtr); if (pixmap != None) { - result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap); + objPtr = Tcl_NewStringObj(Tk_NameOfBitmap(Tk_Display(tkwin), + pixmap), -1); } break; } - case TK_CONFIG_BORDER: { - Tk_3DBorder border = *((Tk_3DBorder *) ptr); + case TK_OPTION_BORDER: { + Tk_3DBorder border = *((Tk_3DBorder *) internalPtr); if (border != NULL) { - result = Tk_NameOf3DBorder(border); + objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1); } break; } - case TK_CONFIG_RELIEF: - result = Tk_NameOfRelief(*((int *) ptr)); + case TK_OPTION_RELIEF: { + objPtr = Tcl_NewStringObj(Tk_NameOfRelief( + *((int *) internalPtr)), -1); break; - case TK_CONFIG_CURSOR: - case TK_CONFIG_ACTIVE_CURSOR: { - Tk_Cursor cursor = *((Tk_Cursor *) ptr); + } + case TK_OPTION_CURSOR: { + Tk_Cursor cursor = *((Tk_Cursor *) internalPtr); if (cursor != None) { - result = Tk_NameOfCursor(Tk_Display(tkwin), cursor); + objPtr = Tcl_NewStringObj( + Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1); } break; } - case TK_CONFIG_JUSTIFY: - result = Tk_NameOfJustify(*((Tk_Justify *) ptr)); - break; - case TK_CONFIG_ANCHOR: - result = Tk_NameOfAnchor(*((Tk_Anchor *) ptr)); - break; - case TK_CONFIG_CAP_STYLE: - result = Tk_NameOfCapStyle(*((int *) ptr)); + case TK_OPTION_JUSTIFY: { + objPtr = Tcl_NewStringObj(Tk_NameOfJustify( + *((Tk_Justify *) internalPtr)), -1); break; - case TK_CONFIG_JOIN_STYLE: - result = Tk_NameOfJoinStyle(*((int *) ptr)); - break; - case TK_CONFIG_PIXELS: - sprintf(buffer, "%d", *((int *) ptr)); - result = buffer; + } + case TK_OPTION_ANCHOR: { + objPtr = Tcl_NewStringObj(Tk_NameOfAnchor( + *((Tk_Anchor *) internalPtr)), -1); break; - case TK_CONFIG_MM: - Tcl_PrintDouble(interp, *((double *) ptr), buffer); - result = buffer; + } + case TK_OPTION_PIXELS: { + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); break; - case TK_CONFIG_WINDOW: { - Tk_Window tkwin; - - tkwin = *((Tk_Window *) ptr); + } + case TK_OPTION_WINDOW: { + Tk_Window tkwin = *((Tk_Window *) internalPtr); if (tkwin != NULL) { - result = Tk_PathName(tkwin); + objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); } break; } - case TK_CONFIG_CUSTOM: - result = (*specPtr->customPtr->printProc)( - specPtr->customPtr->clientData, tkwin, widgRec, - specPtr->offset, freeProcPtr); - break; - default: - result = "?? unknown type ??"; + default: { + panic("bad option type in GetObjectForOption"); + } } - return result; + if (objPtr == NULL) { + objPtr = Tcl_NewObj(); + } + return objPtr; } /* *---------------------------------------------------------------------- * - * Tk_ConfigureValue -- + * Tk_GetOptionValue -- * * This procedure returns the current value of a configuration - * option for a widget. + * option. * * Results: - * The return value is a standard Tcl completion code (TCL_OK or - * TCL_ERROR). Interp->result will be set to hold either the value - * of the option given by argvName (if TCL_OK is returned) or - * an error message (if TCL_ERROR is returned). + * The return value is the object holding the current value of + * the option given by namePtr. If no such option exists, then + * the return value is NULL and an error message is left in + * interp's result (if interp isn't NULL). * * Side effects: * None. @@ -881,110 +1912,113 @@ FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr) *---------------------------------------------------------------------- */ -int -Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Window tkwin; /* Window corresponding to widgRec. */ - Tk_ConfigSpec *specs; /* Describes legal options. */ - char *widgRec; /* Record whose fields contain current +Tcl_Obj * +Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin) + Tcl_Interp *interp; /* Interpreter for error reporting. If + * NULL then no messages are provided for + * errors. */ + char *recordPtr; /* Record whose fields contain current * values for options. */ - char *argvName; /* Gives the command-line name for the + Tk_OptionTable optionTable; /* Describes legal options. */ + Tcl_Obj *namePtr; /* Gives the command-line name for the * option whose value is to be returned. */ - int flags; /* Used to specify additional flags - * that must be present in config specs - * for them to be considered. */ + Tk_Window tkwin; /* Window corresponding to recordPtr. */ { - Tk_ConfigSpec *specPtr; - int needFlags, hateFlags; + OptionTable *tablePtr = (OptionTable *) optionTable; + Option *optionPtr; + Tcl_Obj *resultPtr; - needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); - if (Tk_Depth(tkwin) <= 1) { - hateFlags = TK_CONFIG_COLOR_ONLY; - } else { - hateFlags = TK_CONFIG_MONO_ONLY; + optionPtr = GetOptionFromObj(interp, namePtr, tablePtr); + if (optionPtr == NULL) { + return NULL; } - specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags); - if (specPtr == NULL) { - return TCL_ERROR; + if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { + optionPtr = optionPtr->extra.synonymPtr; } - interp->result = FormatConfigValue(interp, tkwin, specPtr, widgRec, - interp->result, &interp->freeProc); - return TCL_OK; + if (optionPtr->specPtr->objOffset >= 0) { + resultPtr = *((Tcl_Obj **) (recordPtr + optionPtr->specPtr->objOffset)); + if (resultPtr == NULL) { + /* + * This option has a null value and is represented by a null + * object pointer. We can't return the null pointer, since that + * would indicate an error. Instead, return a new empty object. + */ + + resultPtr = Tcl_NewObj(); + } + } else { + resultPtr = GetObjectForOption(recordPtr, optionPtr, tkwin); + } + return resultPtr; } /* *---------------------------------------------------------------------- * - * Tk_FreeOptions -- + * TkDebugConfig -- * - * Free up all resources associated with configuration options. + * This is a debugging procedure that returns information about + * one of the configuration tables that currently exists for an + * interpreter. * * Results: - * None. + * If the specified table exists in the given interpreter, then a + * list is returned describing the table and any other tables that + * it chains to: for each table there will be three list elements + * giving the reference count for the table, the number of elements + * in the table, and the command-line name for the first option + * in the table. If the table doesn't exist in the interpreter + * then an empty object is returned. The reference count for the + * returned object is 0. * * Side effects: - * Any resource in widgRec that is controlled by a configuration - * option (e.g. a Tk_3DBorder or XColor) is freed in the appropriate - * fashion. + * None. * *---------------------------------------------------------------------- */ - /* ARGSUSED */ -void -Tk_FreeOptions(specs, widgRec, display, needFlags) - Tk_ConfigSpec *specs; /* Describes legal options. */ - char *widgRec; /* Record whose fields contain current - * values for options. */ - Display *display; /* X display; needed for freeing some - * resources. */ - int needFlags; /* Used to specify additional flags - * that must be present in config specs - * for them to be considered. */ +Tcl_Obj * +TkDebugConfig(interp, table) + Tcl_Interp *interp; /* Interpreter in which the table is + * defined. */ + Tk_OptionTable table; /* Table about which information is to + * be returned. May not necessarily + * exist in the interpreter anymore. */ { - register Tk_ConfigSpec *specPtr; - char *ptr; + OptionTable *tablePtr = (OptionTable *) table; + Tcl_HashTable *hashTablePtr; + Tcl_HashEntry *hashEntryPtr; + Tcl_HashSearch search; + Tcl_Obj *objPtr; - for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { - if ((specPtr->specFlags & needFlags) != needFlags) { - continue; - } - ptr = widgRec + specPtr->offset; - switch (specPtr->type) { - case TK_CONFIG_STRING: - if (*((char **) ptr) != NULL) { - ckfree(*((char **) ptr)); - *((char **) ptr) = NULL; - } - break; - case TK_CONFIG_COLOR: - if (*((XColor **) ptr) != NULL) { - Tk_FreeColor(*((XColor **) ptr)); - *((XColor **) ptr) = NULL; - } - break; - case TK_CONFIG_FONT: - Tk_FreeFont(*((Tk_Font *) ptr)); - *((Tk_Font *) ptr) = NULL; - break; - case TK_CONFIG_BITMAP: - if (*((Pixmap *) ptr) != None) { - Tk_FreeBitmap(display, *((Pixmap *) ptr)); - *((Pixmap *) ptr) = None; - } - break; - case TK_CONFIG_BORDER: - if (*((Tk_3DBorder *) ptr) != NULL) { - Tk_Free3DBorder(*((Tk_3DBorder *) ptr)); - *((Tk_3DBorder *) ptr) = NULL; - } - break; - case TK_CONFIG_CURSOR: - case TK_CONFIG_ACTIVE_CURSOR: - if (*((Tk_Cursor *) ptr) != None) { - Tk_FreeCursor(display, *((Tk_Cursor *) ptr)); - *((Tk_Cursor *) ptr) = None; - } + objPtr = Tcl_NewObj(); + hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY, + NULL); + if (hashTablePtr == NULL) { + return objPtr; + } + + /* + * Scan all the tables for this interpreter to make sure that the + * one we want still is valid. + */ + + for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); + hashEntryPtr != NULL; + hashEntryPtr = Tcl_NextHashEntry(&search)) { + if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) { + for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) { + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr, + Tcl_NewIntObj(tablePtr->refCount)); + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr, + Tcl_NewIntObj(tablePtr->numOptions)); + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr, + Tcl_NewStringObj( + tablePtr->options[0].specPtr->optionName, + -1)); + } + break; } } + return objPtr; } diff --git a/generic/tkConsole.c b/generic/tkConsole.c index 810847e..cbbef79 100644 --- a/generic/tkConsole.c +++ b/generic/tkConsole.c @@ -10,13 +10,14 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkConsole.c,v 1.4 1999/03/10 07:04:39 stanton Exp $ + * RCS: @(#) $Id: tkConsole.c,v 1.5 1999/04/16 01:51:13 stanton Exp $ */ #include "tk.h" -#include "tkInt.h" #include <string.h> +#include "tkInt.h" + /* * A data structure of the following type holds information for each console * which a handler (i.e. a Tcl command) has been defined for a particular @@ -28,7 +29,10 @@ typedef struct ConsoleInfo { Tcl_Interp *interp; /* Interpreter to send console commands. */ } ConsoleInfo; -static Tcl_Interp *gStdoutInterp = NULL; +typedef struct ThreadSpecificData { + Tcl_Interp *gStdoutInterp; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Forward declarations for procedures defined later in this file: @@ -36,7 +40,6 @@ static Tcl_Interp *gStdoutInterp = NULL; * The first three will be used in the tk app shells... */ -void TkConsoleCreate _ANSI_ARGS_((void)); void TkConsoleCreate_ _ANSI_ARGS_((void)); int TkConsoleInit _ANSI_ARGS_((Tcl_Interp *interp)); void TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp, @@ -101,10 +104,10 @@ void TkConsoleCreate() { /* - * This function is being disabled so we don't end up calling it - * twice. Once from WinMain() and once from Tk_Main(). The real - * function is now TkConsoleCreate_ and is only called from Tk_Main. - * All of is an ugly hack. + * This function is being diabled so we don't end up calling it + * twice. Once from WinMain() and once from Tk_MainEx(). The real + * function is now tkCreateConsole_ and is only called from Tk_MainEx. + * All of this is an ugly hack. */ } @@ -113,27 +116,50 @@ TkConsoleCreate_() { Tcl_Channel consoleChannel; - consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0", - (ClientData) TCL_STDIN, TCL_READABLE); - if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + /* + * check for STDIN, otherwise create it + */ + + if (Tcl_GetStdChannel(TCL_STDIN) == NULL) { + consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console0", + (ClientData) TCL_STDIN, TCL_READABLE); + if (consoleChannel != NULL) { + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); + } + Tcl_SetStdChannel(consoleChannel, TCL_STDIN); } - Tcl_SetStdChannel(consoleChannel, TCL_STDIN); - consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1", - (ClientData) TCL_STDOUT, TCL_WRITABLE); - if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + + /* + * check for STDOUT, otherwise create it + */ + + if (Tcl_GetStdChannel(TCL_STDOUT) == NULL) { + consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console1", + (ClientData) TCL_STDOUT, TCL_WRITABLE); + if (consoleChannel != NULL) { + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); + } + Tcl_SetStdChannel(consoleChannel, TCL_STDOUT); } - Tcl_SetStdChannel(consoleChannel, TCL_STDOUT); - consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2", - (ClientData) TCL_STDERR, TCL_WRITABLE); - if (consoleChannel != NULL) { - Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); - Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + + /* + * check for STDERR, otherwise create it + */ + + if (Tcl_GetStdChannel(TCL_STDERR) == NULL) { + consoleChannel = Tcl_CreateChannel(&consoleChannelType, "console2", + (ClientData) TCL_STDERR, TCL_WRITABLE); + if (consoleChannel != NULL) { + Tcl_SetChannelOption(NULL, consoleChannel, "-translation", "lf"); + Tcl_SetChannelOption(NULL, consoleChannel, "-buffering", "none"); + Tcl_SetChannelOption(NULL, consoleChannel, "-encoding", "utf-8"); + } + Tcl_SetStdChannel(consoleChannel, TCL_STDERR); } - Tcl_SetStdChannel(consoleChannel, TCL_STDERR); } /* @@ -161,6 +187,8 @@ TkConsoleInit(interp) Tcl_Interp *consoleInterp; ConsoleInfo *info; Tk_Window mainWindow = Tk_MainWindow(interp); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); #ifdef MAC_TCL static char initCmd[] = "source -rsrc {Console}"; #else @@ -168,7 +196,6 @@ TkConsoleInit(interp) #endif consoleInterp = Tcl_CreateInterp(); - if (consoleInterp == NULL) { goto error; } @@ -183,7 +210,7 @@ TkConsoleInit(interp) if (Tk_Init(consoleInterp) != TCL_OK) { goto error; } - gStdoutInterp = interp; + tsdPtr->gStdoutInterp = interp; /* * Add console commands to the interp @@ -239,11 +266,15 @@ ConsoleOutput(instanceData, buf, toWrite, errorCode) int toWrite; /* How many bytes to write? */ int *errorCode; /* Where to store error code. */ { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + *errorCode = 0; Tcl_SetErrno(0); - if (gStdoutInterp != NULL) { - TkConsolePrint(gStdoutInterp, (int) instanceData, buf, toWrite); + if (tsdPtr->gStdoutInterp != NULL) { + TkConsolePrint(tsdPtr->gStdoutInterp, (int) instanceData, buf, + toWrite); } return toWrite; @@ -390,6 +421,7 @@ ConsoleCmd(clientData, interp, argc, argv) int length; int result; Tcl_Interp *consoleInterp; + Tcl_DString dString; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -402,20 +434,20 @@ ConsoleCmd(clientData, interp, argc, argv) result = TCL_OK; consoleInterp = info->consoleInterp; Tcl_Preserve((ClientData) consoleInterp); + Tcl_DStringInit(&dString); + if ((c == 't') && (strncmp(argv[1], "title", length)) == 0) { - Tcl_DString dString; - - Tcl_DStringInit(&dString); Tcl_DStringAppend(&dString, "wm title . ", -1); if (argc == 3) { Tcl_DStringAppendElement(&dString, argv[2]); } Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); - Tcl_DStringFree(&dString); } else if ((c == 'h') && (strncmp(argv[1], "hide", length)) == 0) { - Tcl_Eval(consoleInterp, "wm withdraw ."); + Tcl_DStringAppend(&dString, "wm withdraw . ", -1); + Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); } else if ((c == 's') && (strncmp(argv[1], "show", length)) == 0) { - Tcl_Eval(consoleInterp, "wm deiconify ."); + Tcl_DStringAppend(&dString, "wm deiconify . ", -1); + Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); } else if ((c == 'e') && (strncmp(argv[1], "eval", length)) == 0) { if (argc == 3) { result = Tcl_Eval(consoleInterp, argv[2]); @@ -432,6 +464,7 @@ ConsoleCmd(clientData, interp, argc, argv) (char *) NULL); result = TCL_ERROR; } + Tcl_DStringFree(&dString); Tcl_Release((ClientData) consoleInterp); return result; } @@ -547,9 +580,13 @@ ConsoleEventProc(clientData, eventPtr) { ConsoleInfo *info = (ConsoleInfo *) clientData; Tcl_Interp *consoleInterp; + Tcl_DString dString; if (eventPtr->type == DestroyNotify) { - consoleInterp = info->consoleInterp; + + Tcl_DStringInit(&dString); + + consoleInterp = info->consoleInterp; /* * It is possible that the console interpreter itself has @@ -562,7 +599,9 @@ ConsoleEventProc(clientData, eventPtr) return; } Tcl_Preserve((ClientData) consoleInterp); - Tcl_Eval(consoleInterp, "tkConsoleExit"); + Tcl_DStringAppend(&dString, "tkConsoleExit", -1); + Tcl_Eval(consoleInterp, Tcl_DStringValue(&dString)); + Tcl_DStringFree(&dString); Tcl_Release((ClientData) consoleInterp); } } diff --git a/generic/tkCursor.c b/generic/tkCursor.c index 297cd3e..87b284d 100644 --- a/generic/tkCursor.c +++ b/generic/tkCursor.c @@ -6,12 +6,12 @@ * also avoids round-trips to the X server. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCursor.c,v 1.2 1998/09/14 18:23:09 stanton Exp $ + * RCS: @(#) $Id: tkCursor.c,v 1.3 1999/04/16 01:51:13 stanton Exp $ */ #include "tkPort.h" @@ -20,28 +20,11 @@ /* * A TkCursor structure exists for each cursor that is currently * active. Each structure is indexed with two hash tables defined - * below. One of the tables is idTable, and the other is either - * nameTable or dataTable, also defined below. + * below. One of the tables is cursorIdTable, and the other is either + * cursorNameTable or cursorDataTable, each of which are stored in the + * TkDisplay structure for the current thread. */ -/* - * Hash table to map from a textual description of a cursor to the - * TkCursor record for the cursor, and key structure used in that - * hash table: - */ - -static Tcl_HashTable nameTable; -typedef struct { - Tk_Uid name; /* Textual name for desired cursor. */ - Display *display; /* Display for which cursor will be used. */ -} NameKey; - -/* - * Hash table to map from a collection of in-core data about a - * cursor (bitmap contents, etc.) to a TkCursor structure: - */ - -static Tcl_HashTable dataTable; typedef struct { char *source; /* Cursor bits. */ char *mask; /* Mask bits. */ @@ -53,24 +36,129 @@ typedef struct { } DataKey; /* - * Hash table that maps from <display + cursor id> to the TkCursor structure - * for the cursor. This table is used by Tk_FreeCursor. + * Forward declarations for procedures defined in this file: */ -static Tcl_HashTable idTable; -typedef struct { - Display *display; /* Display for which cursor was allocated. */ - Tk_Cursor cursor; /* Cursor identifier. */ -} IdKey; +static void CursorInit _ANSI_ARGS_((TkDisplay *dispPtr)); +static void DupCursorObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, + Tcl_Obj *dupObjPtr)); +static void FreeCursor _ANSI_ARGS_((TkCursor *cursorPtr)); +static void FreeCursorObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); +static TkCursor * GetCursor _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, char *name)); +static TkCursor * GetCursorFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj *objPtr)); +static void InitCursorObj _ANSI_ARGS_((Tcl_Obj *objPtr)); -static int initialized = 0; /* 0 means static structures haven't been - * initialized yet. */ +/* + * The following structure defines the implementation of the "cursor" Tcl + * object, used for drawing. The color object remembers the hash table + * entry associated with a color. The actual allocation and deallocation + * of the color should be done by the configuration package when the cursor + * option is set. + */ +static Tcl_ObjType cursorObjType = { + "cursor", /* name */ + FreeCursorObjProc, /* freeIntRepProc */ + DupCursorObjProc, /* dupIntRepProc */ + NULL, /* updateStringProc */ + NULL /* setFromAnyProc */ +}; + /* - * Forward declarations for procedures defined in this file: + *---------------------------------------------------------------------- + * + * Tk_AllocCursorFromObj -- + * + * Given a Tcl_Obj *, map the value to a corresponding + * Tk_Cursor structure based on the tkwin given. + * + * Results: + * The return value is the X identifer for the desired cursor, + * unless objPtr couldn't be parsed correctly. In this case, + * None is returned and an error message is left in the interp's result. + * The caller should never modify the cursor that is returned, and + * should eventually call Tk_FreeCursorFromObj when the cursor is no + * longer needed. + * + * Side effects: + * The cursor is added to an internal database with a reference count. + * For each call to this procedure, there should eventually be a call + * to Tk_FreeCursorFromObj, so that the database can be cleaned up + * when cursors aren't needed anymore. + * + *---------------------------------------------------------------------- */ -static void CursorInit _ANSI_ARGS_((void)); +Tk_Cursor +Tk_AllocCursorFromObj(interp, tkwin, objPtr) + Tcl_Interp *interp; /* Interp for error results. */ + Tk_Window tkwin; /* Window in which the cursor will be used.*/ + Tcl_Obj *objPtr; /* Object describing cursor; see manual + * entry for description of legal + * syntax of this obj's string rep. */ +{ + TkCursor *cursorPtr; + + if (objPtr->typePtr != &cursorObjType) { + InitCursorObj(objPtr); + } + cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + + /* + * If the object currently points to a TkCursor, see if it's the + * one we want. If so, increment its reference count and return. + */ + + if (cursorPtr != NULL) { + if (cursorPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a TkCursor that's + * no longer in use. Clear the reference. + */ + FreeCursorObjProc(objPtr); + cursorPtr = NULL; + } else if (Tk_Display(tkwin) == cursorPtr->display) { + cursorPtr->resourceRefCount++; + return cursorPtr->cursor; + } + } + + /* + * The object didn't point to the TkCursor that we wanted. Search + * the list of TkCursors with the same name to see if one of the + * other TkCursors is the right one. + */ + + if (cursorPtr != NULL) { + TkCursor *firstCursorPtr = + (TkCursor *) Tcl_GetHashValue(cursorPtr->hashPtr); + FreeCursorObjProc(objPtr); + for (cursorPtr = firstCursorPtr; cursorPtr != NULL; + cursorPtr = cursorPtr->nextPtr) { + if (Tk_Display(tkwin) == cursorPtr->display) { + cursorPtr->resourceRefCount++; + cursorPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr; + return cursorPtr->cursor; + } + } + } + + /* + * Still no luck. Call GetCursor to allocate a new TkCursor object. + */ + + cursorPtr = GetCursor(interp, tkwin, Tcl_GetString(objPtr)); + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr; + if (cursorPtr == NULL) { + return None; + } else { + cursorPtr->objRefCount++; + return cursorPtr->cursor; + } +} /* *---------------------------------------------------------------------- @@ -83,7 +171,7 @@ static void CursorInit _ANSI_ARGS_((void)); * Results: * The return value is the X identifer for the desired cursor, * unless string couldn't be parsed correctly. In this case, - * None is returned and an error message is left in interp->result. + * None is returned and an error message is left in the interp's result. * The caller should never modify the cursor that is returned, and * should eventually call Tk_FreeCursor when the cursor is no longer * needed. @@ -101,52 +189,103 @@ Tk_Cursor Tk_GetCursor(interp, tkwin, string) Tcl_Interp *interp; /* Interpreter to use for error reporting. */ Tk_Window tkwin; /* Window in which cursor will be used. */ - Tk_Uid string; /* Description of cursor. See manual entry + char *string; /* Description of cursor. See manual entry + * for details on legal syntax. */ +{ + TkCursor *cursorPtr = GetCursor(interp, tkwin, string); + if (cursorPtr == NULL) { + return None; + } + return cursorPtr->cursor; +} + +/* + *---------------------------------------------------------------------- + * + * GetCursor -- + * + * Given a string describing a cursor, locate (or create if necessary) + * a cursor that fits the description. This routine returns the + * internal data structure for the cursor, which avoids extra + * hash table lookups in Tk_AllocCursorFromObj. + * + * Results: + * The return value is a pointer to the TkCursor for the desired + * cursor, unless string couldn't be parsed correctly. In this + * case, NULL is returned and an error message is left in the + * interp's result. The caller should never modify the cursor that + * is returned, and should eventually call Tk_FreeCursor when the + * cursor is no longer needed. + * + * Side effects: + * The cursor is added to an internal database with a reference count. + * For each call to this procedure, there should eventually be a call + * to Tk_FreeCursor, so that the database can be cleaned up when cursors + * aren't needed anymore. + * + *---------------------------------------------------------------------- + */ + +static TkCursor * +GetCursor(interp, tkwin, string) + Tcl_Interp *interp; /* Interpreter to use for error reporting. */ + Tk_Window tkwin; /* Window in which cursor will be used. */ + char *string; /* Description of cursor. See manual entry * for details on legal syntax. */ { - NameKey nameKey; - IdKey idKey; - Tcl_HashEntry *nameHashPtr, *idHashPtr; + Tcl_HashEntry *nameHashPtr; register TkCursor *cursorPtr; + TkCursor *existingCursorPtr = NULL; int new; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - CursorInit(); + if (!dispPtr->cursorInit) { + CursorInit(dispPtr); } - nameKey.name = string; - nameKey.display = Tk_Display(tkwin); - nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &nameKey, &new); + nameHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorNameTable, + string, &new); if (!new) { - cursorPtr = (TkCursor *) Tcl_GetHashValue(nameHashPtr); - cursorPtr->refCount++; - return cursorPtr->cursor; + existingCursorPtr = (TkCursor *) Tcl_GetHashValue(nameHashPtr); + for (cursorPtr = existingCursorPtr; cursorPtr != NULL; + cursorPtr = cursorPtr->nextPtr) { + if (Tk_Display(tkwin) == cursorPtr->display) { + cursorPtr->resourceRefCount++; + return cursorPtr; + } + } + } else { + existingCursorPtr = NULL; } cursorPtr = TkGetCursorByName(interp, tkwin, string); if (cursorPtr == NULL) { - Tcl_DeleteHashEntry(nameHashPtr); - return None; + if (new) { + Tcl_DeleteHashEntry(nameHashPtr); + } + return NULL; } /* * Add information about this cursor to our database. */ - cursorPtr->refCount = 1; - cursorPtr->otherTable = &nameTable; + cursorPtr->display = Tk_Display(tkwin); + cursorPtr->resourceRefCount = 1; + cursorPtr->objRefCount = 0; + cursorPtr->otherTable = &dispPtr->cursorNameTable; cursorPtr->hashPtr = nameHashPtr; - idKey.display = nameKey.display; - idKey.cursor = cursorPtr->cursor; - idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey, &new); + cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable, + (char *) cursorPtr->cursor, &new); if (!new) { panic("cursor already registered in Tk_GetCursor"); } + cursorPtr->nextPtr = existingCursorPtr; Tcl_SetHashValue(nameHashPtr, cursorPtr); - Tcl_SetHashValue(idHashPtr, cursorPtr); + Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr); - return cursorPtr->cursor; + return cursorPtr; } /* @@ -160,7 +299,7 @@ Tk_GetCursor(interp, tkwin, string) * Results: * The return value is the X identifer for the desired cursor, * unless it couldn't be created properly. In this case, None is - * returned and an error message is left in interp->result. The + * returned and an error message is left in the interp's result. The * caller should never modify the cursor that is returned, and * should eventually call Tk_FreeCursor when the cursor is no * longer needed. @@ -187,14 +326,15 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, Tk_Uid bg; /* Background color for cursor. */ { DataKey dataKey; - IdKey idKey; - Tcl_HashEntry *dataHashPtr, *idHashPtr; + Tcl_HashEntry *dataHashPtr; register TkCursor *cursorPtr; int new; XColor fgColor, bgColor; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - CursorInit(); + + if (!dispPtr->cursorInit) { + CursorInit(dispPtr); } dataKey.source = source; @@ -206,10 +346,11 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, dataKey.fg = fg; dataKey.bg = bg; dataKey.display = Tk_Display(tkwin); - dataHashPtr = Tcl_CreateHashEntry(&dataTable, (char *) &dataKey, &new); + dataHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorDataTable, + (char *) &dataKey, &new); if (!new) { cursorPtr = (TkCursor *) Tcl_GetHashValue(dataHashPtr); - cursorPtr->refCount++; + cursorPtr->resourceRefCount++; return cursorPtr->cursor; } @@ -236,17 +377,18 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, goto error; } - cursorPtr->refCount = 1; - cursorPtr->otherTable = &dataTable; + cursorPtr->resourceRefCount = 1; + cursorPtr->otherTable = &dispPtr->cursorDataTable; cursorPtr->hashPtr = dataHashPtr; - idKey.display = dataKey.display; - idKey.cursor = cursorPtr->cursor; - idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey, &new); + cursorPtr->objRefCount = 0; + cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable, + (char *) cursorPtr->cursor, &new); + if (!new) { panic("cursor already registered in Tk_GetCursorFromData"); } Tcl_SetHashValue(dataHashPtr, cursorPtr); - Tcl_SetHashValue(idHashPtr, cursorPtr); + Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr); return cursorPtr->cursor; error: @@ -281,27 +423,77 @@ Tk_NameOfCursor(display, cursor) Tk_Cursor cursor; /* Identifier for cursor whose name is * wanted. */ { - IdKey idKey; Tcl_HashEntry *idHashPtr; TkCursor *cursorPtr; - static char string[20]; + TkDisplay *dispPtr; - if (!initialized) { + dispPtr = TkGetDisplay(display); + + if (!dispPtr->cursorInit) { printid: - sprintf(string, "cursor id 0x%x", (unsigned int) cursor); - return string; + sprintf(dispPtr->cursorString, "cursor id 0x%x", + (unsigned int) cursor); + return dispPtr->cursorString; } - idKey.display = display; - idKey.cursor = cursor; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor); if (idHashPtr == NULL) { goto printid; } cursorPtr = (TkCursor *) Tcl_GetHashValue(idHashPtr); - if (cursorPtr->otherTable != &nameTable) { + if (cursorPtr->otherTable != &dispPtr->cursorNameTable) { goto printid; } - return ((NameKey *) cursorPtr->hashPtr->key.words)->name; + return cursorPtr->hashPtr->key.string; +} + +/* + *---------------------------------------------------------------------- + * + * FreeCursor -- + * + * This procedure is invoked by both Tk_FreeCursor and + * Tk_FreeCursorFromObj; it does all the real work of deallocating + * a cursor. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with cursor is decremented, and + * it is officially deallocated if no-one is using it anymore. + * + *---------------------------------------------------------------------- + */ + +static void +FreeCursor(cursorPtr) + TkCursor *cursorPtr; /* Cursor to be released. */ +{ + TkCursor *prevPtr; + + cursorPtr->resourceRefCount--; + if (cursorPtr->resourceRefCount > 0) { + return; + } + + Tcl_DeleteHashEntry(cursorPtr->idHashPtr); + prevPtr = (TkCursor *) Tcl_GetHashValue(cursorPtr->hashPtr); + if (prevPtr == cursorPtr) { + if (cursorPtr->nextPtr == NULL) { + Tcl_DeleteHashEntry(cursorPtr->hashPtr); + } else { + Tcl_SetHashValue(cursorPtr->hashPtr, cursorPtr->nextPtr); + } + } else { + while (prevPtr->nextPtr != cursorPtr) { + prevPtr = prevPtr->nextPtr; + } + prevPtr->nextPtr = cursorPtr->nextPtr; + } + TkpFreeCursor(cursorPtr); + if (cursorPtr->objRefCount == 0) { + ckfree((char *) cursorPtr); + } } /* @@ -327,32 +519,258 @@ Tk_FreeCursor(display, cursor) Display *display; /* Display for which cursor was allocated. */ Tk_Cursor cursor; /* Identifier for cursor to be released. */ { - IdKey idKey; Tcl_HashEntry *idHashPtr; - register TkCursor *cursorPtr; + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { + if (!dispPtr->cursorInit) { panic("Tk_FreeCursor called before Tk_GetCursor"); } - idKey.display = display; - idKey.cursor = cursor; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor); if (idHashPtr == NULL) { panic("Tk_FreeCursor received unknown cursor argument"); } - cursorPtr = (TkCursor *) Tcl_GetHashValue(idHashPtr); - cursorPtr->refCount--; - if (cursorPtr->refCount == 0) { - Tcl_DeleteHashEntry(cursorPtr->hashPtr); - Tcl_DeleteHashEntry(idHashPtr); - TkFreeCursor(cursorPtr); + FreeCursor((TkCursor *) Tcl_GetHashValue(idHashPtr)); +} + +/* + *---------------------------------------------------------------------- + * + * Tk_FreeCursorFromObj -- + * + * This procedure is called to release a cursor allocated by + * Tk_AllocCursorFromObj. It does not throw away the Tcl_Obj *; + * it only gets rid of the hash table entry for this cursor + * and clears the cached value that is normally stored in the object. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with the cursor represented by + * objPtr is decremented, and the cursor is released to X if there are + * no remaining uses for it. + * + *---------------------------------------------------------------------- + */ + +void +Tk_FreeCursorFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window this cursor lives in. Needed + * for the display value. */ + Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ +{ + FreeCursor(GetCursorFromObj(tkwin, objPtr)); +} + +/* + *--------------------------------------------------------------------------- + * + * FreeCursorFromObjProc -- + * + * This proc is called to release an object reference to a cursor. + * Called when the object's internal rep is released or when + * the cached tkColPtr needs to be changed. + * + * Results: + * None. + * + * Side effects: + * The object reference count is decremented. When both it + * and the hash ref count go to zero, the color's resources + * are released. + * + *--------------------------------------------------------------------------- + */ + +static void +FreeCursorObjProc(objPtr) + Tcl_Obj *objPtr; /* The object we are releasing. */ +{ + TkCursor *cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + + if (cursorPtr != NULL) { + cursorPtr->objRefCount--; + if ((cursorPtr->objRefCount == 0) + && (cursorPtr->resourceRefCount == 0)) { + ckfree((char *) cursorPtr); + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; + } +} + +/* + *--------------------------------------------------------------------------- + * + * DupCursorObjProc -- + * + * When a cached cursor object is duplicated, this is called to + * update the internal reps. + * + * Results: + * None. + * + * Side effects: + * The color's objRefCount is incremented and the internal rep + * of the copy is set to point to it. + * + *--------------------------------------------------------------------------- + */ + +static void +DupCursorObjProc(srcObjPtr, dupObjPtr) + Tcl_Obj *srcObjPtr; /* The object we are copying from. */ + Tcl_Obj *dupObjPtr; /* The object we are copying to. */ +{ + TkCursor *cursorPtr = (TkCursor *) srcObjPtr->internalRep.twoPtrValue.ptr1; + + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr; + + if (cursorPtr != NULL) { + cursorPtr->objRefCount++; } } /* *---------------------------------------------------------------------- * + * Tk_GetCursorFromObj -- + * + * Returns the cursor referred to buy a Tcl object. The cursor must + * already have been allocated via a call to Tk_AllocCursorFromObj or + * Tk_GetCursor. + * + * Results: + * Returns the Tk_Cursor that matches the tkwin and the string rep + * of the name of the cursor given in objPtr. + * + * Side effects: + * If the object is not already a cursor, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +Tk_Cursor +Tk_GetCursorFromObj(tkwin, objPtr) + Tk_Window tkwin; + Tcl_Obj *objPtr; /* The object from which to get pixels. */ +{ + TkCursor *cursorPtr = GetCursorFromObj(tkwin, objPtr); + return cursorPtr->cursor; +} + +/* + *---------------------------------------------------------------------- + * + * GetCursorFromObj -- + * + * Returns the cursor referred to by a Tcl object. The cursor must + * already have been allocated via a call to Tk_AllocCursorFromObj + * or Tk_GetCursor. + * + * Results: + * Returns the TkCursor * that matches the tkwin and the string rep + * of the name of the cursor given in objPtr. + * + * Side effects: + * If the object is not already a cursor, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +static TkCursor * +GetCursorFromObj(tkwin, objPtr) + Tk_Window tkwin; /* Window in which the cursor will be used. */ + Tcl_Obj *objPtr; /* The object that describes the desired + * cursor. */ +{ + TkCursor *cursorPtr; + Tcl_HashEntry *hashPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + if (objPtr->typePtr != &cursorObjType) { + InitCursorObj(objPtr); + } + + cursorPtr = (TkCursor *) objPtr->internalRep.twoPtrValue.ptr1; + if (cursorPtr != NULL) { + if (Tk_Display(tkwin) == cursorPtr->display) { + return cursorPtr; + } + hashPtr = cursorPtr->hashPtr; + } else { + hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable, + Tcl_GetString(objPtr)); + if (hashPtr == NULL) { + goto error; + } + } + + /* + * At this point we've got a hash table entry, off of which hang + * one or more TkCursor structures. See if any of them will work. + */ + + for (cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr); + cursorPtr != NULL; cursorPtr = cursorPtr->nextPtr) { + if (Tk_Display(tkwin) != cursorPtr->display) { + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) cursorPtr; + cursorPtr->objRefCount++; + return cursorPtr; + } + } + + error: + panic("GetCursorFromObj called with non-existent cursor!"); + /* + * The following code isn't reached; it's just there to please compilers. + */ + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * InitCursorObj -- + * + * Bookeeping procedure to change an objPtr to a cursor type. + * + * Results: + * None. + * + * Side effects: + * The old internal rep of the object is freed. The internal + * rep is cleared. The final form of the object is set + * by either Tk_AllocCursorFromObj or GetCursorFromObj. + * + *---------------------------------------------------------------------- + */ + +static void +InitCursorObj(objPtr) + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetString(objPtr); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &cursorObjType; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) NULL; +} + +/* + *---------------------------------------------------------------------- + * * CursorInit -- * * Initialize the structures used for cursor management. @@ -367,11 +785,11 @@ Tk_FreeCursor(display, cursor) */ static void -CursorInit() +CursorInit(dispPtr) + TkDisplay *dispPtr; /* Display used to store thread-specific data. */ { - initialized = 1; - Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); - Tcl_InitHashTable(&dataTable, sizeof(DataKey)/sizeof(int)); + Tcl_InitHashTable(&dispPtr->cursorNameTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&dispPtr->cursorDataTable, sizeof(DataKey)/sizeof(int)); /* * The call below is tricky: can't use sizeof(IdKey) because it @@ -379,6 +797,66 @@ CursorInit() * machines. */ - Tcl_InitHashTable(&idTable, (sizeof(Display *) + sizeof(Tk_Cursor)) - /sizeof(int)); + /* + * Old code.... + * Tcl_InitHashTable(&dispPtr->cursorIdTable, sizeof(Display *) + * /sizeof(int)); + * + * The comment above doesn't make sense. + * However, XIDs should only be 32 bits, by the definition of X, + * so the code above causes Tk to crash. Here is the real code: + */ + + Tcl_InitHashTable(&dispPtr->cursorIdTable, TCL_ONE_WORD_KEYS); + + dispPtr->cursorInit = 1; +} + +/* + *---------------------------------------------------------------------- + * + * TkDebugCursor -- + * + * This procedure returns debugging information about a cursor. + * + * Results: + * The return value is a list with one sublist for each TkCursor + * corresponding to "name". Each sublist has two elements that + * contain the resourceRefCount and objRefCount fields from the + * TkCursor structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkDebugCursor(tkwin, name) + Tk_Window tkwin; /* The window in which the cursor will be + * used (not currently used). */ + char *name; /* Name of the desired color. */ +{ + TkCursor *cursorPtr; + Tcl_HashEntry *hashPtr; + Tcl_Obj *resultPtr, *objPtr; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; + + resultPtr = Tcl_NewObj(); + hashPtr = Tcl_FindHashEntry(&dispPtr->cursorNameTable, name); + if (hashPtr != NULL) { + cursorPtr = (TkCursor *) Tcl_GetHashValue(hashPtr); + if (cursorPtr == NULL) { + panic("TkDebugCursor found empty hash table entry"); + } + for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) { + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(cursorPtr->resourceRefCount)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(cursorPtr->objRefCount)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return resultPtr; } diff --git a/generic/tkDecls.h b/generic/tkDecls.h index ba3512c..f0bf66f 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkDecls.h,v 1.2 1999/03/10 07:04:39 stanton Exp $ + * RCS: @(#) $Id: tkDecls.h,v 1.3 1999/04/16 01:51:13 stanton Exp $ */ #ifndef _TKDECLS @@ -66,7 +66,7 @@ EXTERN void Tk_CanvasEventuallyRedraw _ANSI_ARGS_(( int y2)); /* 9 */ EXTERN int Tk_CanvasGetCoord _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Canvas canvas, char * string, + Tk_Canvas canvas, char * str, double * doublePtr)); /* 10 */ EXTERN Tk_CanvasTextInfo * Tk_CanvasGetTextInfo _ANSI_ARGS_(( @@ -146,7 +146,7 @@ EXTERN void Tk_ConfigureWindow _ANSI_ARGS_((Tk_Window tkwin, XWindowChanges * valuePtr)); /* 31 */ EXTERN Tk_TextLayout Tk_ComputeTextLayout _ANSI_ARGS_((Tk_Font font, - CONST char * string, int numChars, + CONST char * str, int numChars, int wrapLength, Tk_Justify justify, int flags, int * widthPtr, int * heightPtr)); /* 32 */ @@ -155,7 +155,7 @@ EXTERN Tk_Window Tk_CoordsToWindow _ANSI_ARGS_((int rootX, int rootY, /* 33 */ EXTERN unsigned long Tk_CreateBinding _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, - ClientData object, char * eventString, + ClientData object, char * eventStr, char * command, int append)); /* 34 */ EXTERN Tk_BindingTable Tk_CreateBindingTable _ANSI_ARGS_(( @@ -195,7 +195,7 @@ EXTERN Tk_Window Tk_CreateWindowFromPath _ANSI_ARGS_(( char * pathName, char * screenName)); /* 44 */ EXTERN int Tk_DefineBitmap _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Uid name, char * source, int width, + CONST char * name, char * source, int width, int height)); /* 45 */ EXTERN void Tk_DefineCursor _ANSI_ARGS_((Tk_Window window, @@ -207,7 +207,7 @@ EXTERN void Tk_DeleteAllBindings _ANSI_ARGS_(( /* 47 */ EXTERN int Tk_DeleteBinding _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, - ClientData object, char * eventString)); + ClientData object, char * eventStr)); /* 48 */ EXTERN void Tk_DeleteBindingTable _ANSI_ARGS_(( Tk_BindingTable bindingTable)); @@ -247,7 +247,7 @@ EXTERN void Tk_Draw3DRectangle _ANSI_ARGS_((Tk_Window tkwin, /* 59 */ EXTERN void Tk_DrawChars _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, - CONST char * source, int numChars, int x, + CONST char * source, int numBytes, int x, int y)); /* 60 */ EXTERN void Tk_DrawFocusHighlight _ANSI_ARGS_((Tk_Window tkwin, @@ -318,24 +318,24 @@ EXTERN void Tk_GetAllBindings _ANSI_ARGS_((Tcl_Interp * interp, ClientData object)); /* 82 */ EXTERN int Tk_GetAnchor _ANSI_ARGS_((Tcl_Interp * interp, - char * string, Tk_Anchor * anchorPtr)); + char * str, Tk_Anchor * anchorPtr)); /* 83 */ EXTERN char * Tk_GetAtomName _ANSI_ARGS_((Tk_Window tkwin, Atom atom)); /* 84 */ EXTERN char * Tk_GetBinding _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, - ClientData object, char * eventString)); + ClientData object, char * eventStr)); /* 85 */ EXTERN Pixmap Tk_GetBitmap _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, Tk_Uid string)); + Tk_Window tkwin, CONST char * str)); /* 86 */ EXTERN Pixmap Tk_GetBitmapFromData _ANSI_ARGS_(( Tcl_Interp * interp, Tk_Window tkwin, char * source, int width, int height)); /* 87 */ EXTERN int Tk_GetCapStyle _ANSI_ARGS_((Tcl_Interp * interp, - char * string, int * capPtr)); + char * str, int * capPtr)); /* 88 */ EXTERN XColor * Tk_GetColor _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid name)); @@ -344,10 +344,10 @@ EXTERN XColor * Tk_GetColorByValue _ANSI_ARGS_((Tk_Window tkwin, XColor * colorPtr)); /* 90 */ EXTERN Colormap Tk_GetColormap _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, char * string)); + Tk_Window tkwin, char * str)); /* 91 */ EXTERN Tk_Cursor Tk_GetCursor _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, Tk_Uid string)); + Tk_Window tkwin, Tk_Uid str)); /* 92 */ EXTERN Tk_Cursor Tk_GetCursorFromData _ANSI_ARGS_(( Tcl_Interp * interp, Tk_Window tkwin, @@ -356,10 +356,10 @@ EXTERN Tk_Cursor Tk_GetCursorFromData _ANSI_ARGS_(( Tk_Uid bg)); /* 93 */ EXTERN Tk_Font Tk_GetFont _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, CONST char * string)); + Tk_Window tkwin, CONST char * str)); /* 94 */ -EXTERN Tk_Font Tk_GetFontFromObj _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, Tcl_Obj * objPtr)); +EXTERN Tk_Font Tk_GetFontFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); /* 95 */ EXTERN void Tk_GetFontMetrics _ANSI_ARGS_((Tk_Font font, Tk_FontMetrics * fmPtr)); @@ -380,10 +380,10 @@ EXTERN ClientData Tk_GetImageMasterData _ANSI_ARGS_(( EXTERN Tk_ItemType * Tk_GetItemTypes _ANSI_ARGS_((void)); /* 100 */ EXTERN int Tk_GetJoinStyle _ANSI_ARGS_((Tcl_Interp * interp, - char * string, int * joinPtr)); + char * str, int * joinPtr)); /* 101 */ EXTERN int Tk_GetJustify _ANSI_ARGS_((Tcl_Interp * interp, - char * string, Tk_Justify * justifyPtr)); + char * str, Tk_Justify * justifyPtr)); /* 102 */ EXTERN int Tk_GetNumMainWindows _ANSI_ARGS_((void)); /* 103 */ @@ -391,7 +391,7 @@ EXTERN Tk_Uid Tk_GetOption _ANSI_ARGS_((Tk_Window tkwin, char * name, char * className)); /* 104 */ EXTERN int Tk_GetPixels _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, char * string, int * intPtr)); + Tk_Window tkwin, char * str, int * intPtr)); /* 105 */ EXTERN Pixmap Tk_GetPixmap _ANSI_ARGS_((Display * display, Drawable d, int width, int height, int depth)); @@ -407,18 +407,18 @@ EXTERN int Tk_GetScrollInfo _ANSI_ARGS_((Tcl_Interp * interp, int * intPtr)); /* 109 */ EXTERN int Tk_GetScreenMM _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, char * string, + Tk_Window tkwin, char * str, double * doublePtr)); /* 110 */ EXTERN int Tk_GetSelection _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc * proc, ClientData clientData)); /* 111 */ -EXTERN Tk_Uid Tk_GetUid _ANSI_ARGS_((CONST char * string)); +EXTERN Tk_Uid Tk_GetUid _ANSI_ARGS_((CONST char * str)); /* 112 */ EXTERN Visual * Tk_GetVisual _ANSI_ARGS_((Tcl_Interp * interp, - Tk_Window tkwin, char * string, - int * depthPtr, Colormap * colormapPtr)); + Tk_Window tkwin, char * str, int * depthPtr, + Colormap * colormapPtr)); /* 113 */ EXTERN void Tk_GetVRootGeometry _ANSI_ARGS_((Tk_Window tkwin, int * xPtr, int * yPtr, int * widthPtr, @@ -459,7 +459,7 @@ EXTERN void Tk_ManageGeometry _ANSI_ARGS_((Tk_Window tkwin, EXTERN void Tk_MapWindow _ANSI_ARGS_((Tk_Window tkwin)); /* 126 */ EXTERN int Tk_MeasureChars _ANSI_ARGS_((Tk_Font tkfont, - CONST char * source, int maxChars, + CONST char * source, int numBytes, int maxPixels, int flags, int * lengthPtr)); /* 127 */ EXTERN void Tk_MoveResizeWindow _ANSI_ARGS_((Tk_Window tkwin, @@ -611,14 +611,14 @@ EXTERN void Tk_TextLayoutToPostscript _ANSI_ARGS_(( Tcl_Interp * interp, Tk_TextLayout layout)); /* 176 */ EXTERN int Tk_TextWidth _ANSI_ARGS_((Tk_Font font, - CONST char * string, int numChars)); + CONST char * str, int numBytes)); /* 177 */ EXTERN void Tk_UndefineCursor _ANSI_ARGS_((Tk_Window window)); /* 178 */ EXTERN void Tk_UnderlineChars _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char * source, int x, int y, - int firstChar, int lastChar)); + int firstByte, int lastByte)); /* 179 */ EXTERN void Tk_UnderlineTextLayout _ANSI_ARGS_(( Display * display, Drawable drawable, GC gc, @@ -636,6 +636,112 @@ EXTERN void Tk_UnsetGrid _ANSI_ARGS_((Tk_Window tkwin)); /* 184 */ EXTERN void Tk_UpdatePointer _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int state)); +/* 185 */ +EXTERN Pixmap Tk_AllocBitmapFromObj _ANSI_ARGS_(( + Tcl_Interp * interp, Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 186 */ +EXTERN Tk_3DBorder Tk_Alloc3DBorderFromObj _ANSI_ARGS_(( + Tcl_Interp * interp, Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 187 */ +EXTERN XColor * Tk_AllocColorFromObj _ANSI_ARGS_(( + Tcl_Interp * interp, Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 188 */ +EXTERN Tk_Cursor Tk_AllocCursorFromObj _ANSI_ARGS_(( + Tcl_Interp * interp, Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 189 */ +EXTERN Tk_Font Tk_AllocFontFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tk_Window tkwin, Tcl_Obj * objPtr)); +/* 190 */ +EXTERN Tk_OptionTable Tk_CreateOptionTable _ANSI_ARGS_(( + Tcl_Interp * interp, + CONST Tk_OptionSpec * templatePtr)); +/* 191 */ +EXTERN void Tk_DeleteOptionTable _ANSI_ARGS_(( + Tk_OptionTable optionTable)); +/* 192 */ +EXTERN void Tk_Free3DBorderFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 193 */ +EXTERN void Tk_FreeBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 194 */ +EXTERN void Tk_FreeColorFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 195 */ +EXTERN void Tk_FreeConfigOptions _ANSI_ARGS_((char * recordPtr, + Tk_OptionTable optionToken, Tk_Window tkwin)); +/* 196 */ +EXTERN void Tk_FreeSavedOptions _ANSI_ARGS_(( + Tk_SavedOptions * savePtr)); +/* 197 */ +EXTERN void Tk_FreeCursorFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 198 */ +EXTERN void Tk_FreeFontFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 199 */ +EXTERN Tk_3DBorder Tk_Get3DBorderFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 200 */ +EXTERN int Tk_GetAnchorFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_Obj * objPtr, Tk_Anchor * anchorPtr)); +/* 201 */ +EXTERN Pixmap Tk_GetBitmapFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 202 */ +EXTERN XColor * Tk_GetColorFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 203 */ +EXTERN Tk_Cursor Tk_GetCursorFromObj _ANSI_ARGS_((Tk_Window tkwin, + Tcl_Obj * objPtr)); +/* 204 */ +EXTERN Tcl_Obj * Tk_GetOptionInfo _ANSI_ARGS_((Tcl_Interp * interp, + char * recordPtr, Tk_OptionTable optionTable, + Tcl_Obj * namePtr, Tk_Window tkwin)); +/* 205 */ +EXTERN Tcl_Obj * Tk_GetOptionValue _ANSI_ARGS_((Tcl_Interp * interp, + char * recordPtr, Tk_OptionTable optionTable, + Tcl_Obj * namePtr, Tk_Window tkwin)); +/* 206 */ +EXTERN int Tk_GetJustifyFromObj _ANSI_ARGS_(( + Tcl_Interp * interp, Tcl_Obj * objPtr, + Tk_Justify * justifyPtr)); +/* 207 */ +EXTERN int Tk_GetMMFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tk_Window tkwin, Tcl_Obj * objPtr, + double * doublePtr)); +/* 208 */ +EXTERN int Tk_GetPixelsFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tk_Window tkwin, Tcl_Obj * objPtr, + int * intPtr)); +/* 209 */ +EXTERN int Tk_GetReliefFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_Obj * objPtr, int * resultPtr)); +/* 210 */ +EXTERN int Tk_GetScrollInfoObj _ANSI_ARGS_((Tcl_Interp * interp, + int objc, Tcl_Obj *CONST objv[], + double * dblPtr, int * intPtr)); +/* 211 */ +EXTERN int Tk_InitOptions _ANSI_ARGS_((Tcl_Interp * interp, + char * recordPtr, Tk_OptionTable optionToken, + Tk_Window tkwin)); +/* 212 */ +EXTERN void Tk_MainEx _ANSI_ARGS_((int argc, char ** argv, + Tcl_AppInitProc * appInitProc, + Tcl_Interp * interp)); +/* 213 */ +EXTERN void Tk_RestoreSavedOptions _ANSI_ARGS_(( + Tk_SavedOptions * savePtr)); +/* 214 */ +EXTERN int Tk_SetOptions _ANSI_ARGS_((Tcl_Interp * interp, + char * recordPtr, Tk_OptionTable optionTable, + int objc, Tcl_Obj *CONST objv[], + Tk_Window tkwin, Tk_SavedOptions * savePtr, + int * maskPtr)); typedef struct TkStubHooks { struct TkPlatStubs *tkPlatStubs; @@ -657,7 +763,7 @@ typedef struct TkStubs { void (*tk_BindEvent) _ANSI_ARGS_((Tk_BindingTable bindingTable, XEvent * eventPtr, Tk_Window tkwin, int numObjects, ClientData * objectPtr)); /* 6 */ void (*tk_CanvasDrawableCoords) _ANSI_ARGS_((Tk_Canvas canvas, double x, double y, short * drawableXPtr, short * drawableYPtr)); /* 7 */ void (*tk_CanvasEventuallyRedraw) _ANSI_ARGS_((Tk_Canvas canvas, int x1, int y1, int x2, int y2)); /* 8 */ - int (*tk_CanvasGetCoord) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Canvas canvas, char * string, double * doublePtr)); /* 9 */ + int (*tk_CanvasGetCoord) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Canvas canvas, char * str, double * doublePtr)); /* 9 */ Tk_CanvasTextInfo * (*tk_CanvasGetTextInfo) _ANSI_ARGS_((Tk_Canvas canvas)); /* 10 */ int (*tk_CanvasPsBitmap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Canvas canvas, Pixmap bitmap, int x, int y, int width, int height)); /* 11 */ int (*tk_CanvasPsColor) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Canvas canvas, XColor * colorPtr)); /* 12 */ @@ -679,9 +785,9 @@ typedef struct TkStubs { int (*tk_ConfigureValue) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_ConfigSpec * specs, char * widgRec, char * argvName, int flags)); /* 28 */ int (*tk_ConfigureWidget) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_ConfigSpec * specs, int argc, char ** argv, char * widgRec, int flags)); /* 29 */ void (*tk_ConfigureWindow) _ANSI_ARGS_((Tk_Window tkwin, unsigned int valueMask, XWindowChanges * valuePtr)); /* 30 */ - Tk_TextLayout (*tk_ComputeTextLayout) _ANSI_ARGS_((Tk_Font font, CONST char * string, int numChars, int wrapLength, Tk_Justify justify, int flags, int * widthPtr, int * heightPtr)); /* 31 */ + Tk_TextLayout (*tk_ComputeTextLayout) _ANSI_ARGS_((Tk_Font font, CONST char * str, int numChars, int wrapLength, Tk_Justify justify, int flags, int * widthPtr, int * heightPtr)); /* 31 */ Tk_Window (*tk_CoordsToWindow) _ANSI_ARGS_((int rootX, int rootY, Tk_Window tkwin)); /* 32 */ - unsigned long (*tk_CreateBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventString, char * command, int append)); /* 33 */ + unsigned long (*tk_CreateBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventStr, char * command, int append)); /* 33 */ Tk_BindingTable (*tk_CreateBindingTable) _ANSI_ARGS_((Tcl_Interp * interp)); /* 34 */ Tk_ErrorHandler (*tk_CreateErrorHandler) _ANSI_ARGS_((Display * display, int errNum, int request, int minorCode, Tk_ErrorProc * errorProc, ClientData clientData)); /* 35 */ void (*tk_CreateEventHandler) _ANSI_ARGS_((Tk_Window token, unsigned long mask, Tk_EventProc * proc, ClientData clientData)); /* 36 */ @@ -692,10 +798,10 @@ typedef struct TkStubs { void (*tk_CreateSelHandler) _ANSI_ARGS_((Tk_Window tkwin, Atom selection, Atom target, Tk_SelectionProc * proc, ClientData clientData, Atom format)); /* 41 */ Tk_Window (*tk_CreateWindow) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window parent, char * name, char * screenName)); /* 42 */ Tk_Window (*tk_CreateWindowFromPath) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * pathName, char * screenName)); /* 43 */ - int (*tk_DefineBitmap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Uid name, char * source, int width, int height)); /* 44 */ + int (*tk_DefineBitmap) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * name, char * source, int width, int height)); /* 44 */ void (*tk_DefineCursor) _ANSI_ARGS_((Tk_Window window, Tk_Cursor cursor)); /* 45 */ void (*tk_DeleteAllBindings) _ANSI_ARGS_((Tk_BindingTable bindingTable, ClientData object)); /* 46 */ - int (*tk_DeleteBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventString)); /* 47 */ + int (*tk_DeleteBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventStr)); /* 47 */ void (*tk_DeleteBindingTable) _ANSI_ARGS_((Tk_BindingTable bindingTable)); /* 48 */ void (*tk_DeleteErrorHandler) _ANSI_ARGS_((Tk_ErrorHandler handler)); /* 49 */ void (*tk_DeleteEventHandler) _ANSI_ARGS_((Tk_Window token, unsigned long mask, Tk_EventProc * proc, ClientData clientData)); /* 50 */ @@ -707,7 +813,7 @@ typedef struct TkStubs { int (*tk_DistanceToTextLayout) _ANSI_ARGS_((Tk_TextLayout layout, int x, int y)); /* 56 */ void (*tk_Draw3DPolygon) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint * pointPtr, int numPoints, int borderWidth, int leftRelief)); /* 57 */ void (*tk_Draw3DRectangle) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief)); /* 58 */ - void (*tk_DrawChars) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char * source, int numChars, int x, int y)); /* 59 */ + void (*tk_DrawChars) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char * source, int numBytes, int x, int y)); /* 59 */ void (*tk_DrawFocusHighlight) _ANSI_ARGS_((Tk_Window tkwin, GC gc, int width, Drawable drawable)); /* 60 */ void (*tk_DrawTextLayout) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar)); /* 61 */ void (*tk_Fill3DPolygon) _ANSI_ARGS_((Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint * pointPtr, int numPoints, int borderWidth, int leftRelief)); /* 62 */ @@ -730,37 +836,37 @@ typedef struct TkStubs { void (*tk_GeometryRequest) _ANSI_ARGS_((Tk_Window tkwin, int reqWidth, int reqHeight)); /* 79 */ Tk_3DBorder (*tk_Get3DBorder) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid colorName)); /* 80 */ void (*tk_GetAllBindings) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object)); /* 81 */ - int (*tk_GetAnchor) _ANSI_ARGS_((Tcl_Interp * interp, char * string, Tk_Anchor * anchorPtr)); /* 82 */ + int (*tk_GetAnchor) _ANSI_ARGS_((Tcl_Interp * interp, char * str, Tk_Anchor * anchorPtr)); /* 82 */ char * (*tk_GetAtomName) _ANSI_ARGS_((Tk_Window tkwin, Atom atom)); /* 83 */ - char * (*tk_GetBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventString)); /* 84 */ - Pixmap (*tk_GetBitmap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid string)); /* 85 */ + char * (*tk_GetBinding) _ANSI_ARGS_((Tcl_Interp * interp, Tk_BindingTable bindingTable, ClientData object, char * eventStr)); /* 84 */ + Pixmap (*tk_GetBitmap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, CONST char * str)); /* 85 */ Pixmap (*tk_GetBitmapFromData) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * source, int width, int height)); /* 86 */ - int (*tk_GetCapStyle) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int * capPtr)); /* 87 */ + int (*tk_GetCapStyle) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * capPtr)); /* 87 */ XColor * (*tk_GetColor) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid name)); /* 88 */ XColor * (*tk_GetColorByValue) _ANSI_ARGS_((Tk_Window tkwin, XColor * colorPtr)); /* 89 */ - Colormap (*tk_GetColormap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * string)); /* 90 */ - Tk_Cursor (*tk_GetCursor) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid string)); /* 91 */ + Colormap (*tk_GetColormap) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * str)); /* 90 */ + Tk_Cursor (*tk_GetCursor) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid str)); /* 91 */ Tk_Cursor (*tk_GetCursorFromData) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * source, char * mask, int width, int height, int xHot, int yHot, Tk_Uid fg, Tk_Uid bg)); /* 92 */ - Tk_Font (*tk_GetFont) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, CONST char * string)); /* 93 */ - Tk_Font (*tk_GetFontFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 94 */ + Tk_Font (*tk_GetFont) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, CONST char * str)); /* 93 */ + Tk_Font (*tk_GetFontFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 94 */ void (*tk_GetFontMetrics) _ANSI_ARGS_((Tk_Font font, Tk_FontMetrics * fmPtr)); /* 95 */ GC (*tk_GetGC) _ANSI_ARGS_((Tk_Window tkwin, unsigned long valueMask, XGCValues * valuePtr)); /* 96 */ Tk_Image (*tk_GetImage) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * name, Tk_ImageChangedProc * changeProc, ClientData clientData)); /* 97 */ ClientData (*tk_GetImageMasterData) _ANSI_ARGS_((Tcl_Interp * interp, char * name, Tk_ImageType ** typePtrPtr)); /* 98 */ Tk_ItemType * (*tk_GetItemTypes) _ANSI_ARGS_((void)); /* 99 */ - int (*tk_GetJoinStyle) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int * joinPtr)); /* 100 */ - int (*tk_GetJustify) _ANSI_ARGS_((Tcl_Interp * interp, char * string, Tk_Justify * justifyPtr)); /* 101 */ + int (*tk_GetJoinStyle) _ANSI_ARGS_((Tcl_Interp * interp, char * str, int * joinPtr)); /* 100 */ + int (*tk_GetJustify) _ANSI_ARGS_((Tcl_Interp * interp, char * str, Tk_Justify * justifyPtr)); /* 101 */ int (*tk_GetNumMainWindows) _ANSI_ARGS_((void)); /* 102 */ Tk_Uid (*tk_GetOption) _ANSI_ARGS_((Tk_Window tkwin, char * name, char * className)); /* 103 */ - int (*tk_GetPixels) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * string, int * intPtr)); /* 104 */ + int (*tk_GetPixels) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * str, int * intPtr)); /* 104 */ Pixmap (*tk_GetPixmap) _ANSI_ARGS_((Display * display, Drawable d, int width, int height, int depth)); /* 105 */ int (*tk_GetRelief) _ANSI_ARGS_((Tcl_Interp * interp, char * name, int * reliefPtr)); /* 106 */ void (*tk_GetRootCoords) _ANSI_ARGS_((Tk_Window tkwin, int * xPtr, int * yPtr)); /* 107 */ int (*tk_GetScrollInfo) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv, double * dblPtr, int * intPtr)); /* 108 */ - int (*tk_GetScreenMM) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * string, double * doublePtr)); /* 109 */ + int (*tk_GetScreenMM) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * str, double * doublePtr)); /* 109 */ int (*tk_GetSelection) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc * proc, ClientData clientData)); /* 110 */ - Tk_Uid (*tk_GetUid) _ANSI_ARGS_((CONST char * string)); /* 111 */ - Visual * (*tk_GetVisual) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * string, int * depthPtr, Colormap * colormapPtr)); /* 112 */ + Tk_Uid (*tk_GetUid) _ANSI_ARGS_((CONST char * str)); /* 111 */ + Visual * (*tk_GetVisual) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, char * str, int * depthPtr, Colormap * colormapPtr)); /* 112 */ void (*tk_GetVRootGeometry) _ANSI_ARGS_((Tk_Window tkwin, int * xPtr, int * yPtr, int * widthPtr, int * heightPtr)); /* 113 */ int (*tk_Grab) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, int grabGlobal)); /* 114 */ void (*tk_HandleEvent) _ANSI_ARGS_((XEvent * eventPtr)); /* 115 */ @@ -774,7 +880,7 @@ typedef struct TkStubs { void (*tk_MakeWindowExist) _ANSI_ARGS_((Tk_Window tkwin)); /* 123 */ void (*tk_ManageGeometry) _ANSI_ARGS_((Tk_Window tkwin, Tk_GeomMgr * mgrPtr, ClientData clientData)); /* 124 */ void (*tk_MapWindow) _ANSI_ARGS_((Tk_Window tkwin)); /* 125 */ - int (*tk_MeasureChars) _ANSI_ARGS_((Tk_Font tkfont, CONST char * source, int maxChars, int maxPixels, int flags, int * lengthPtr)); /* 126 */ + int (*tk_MeasureChars) _ANSI_ARGS_((Tk_Font tkfont, CONST char * source, int numBytes, int maxPixels, int flags, int * lengthPtr)); /* 126 */ void (*tk_MoveResizeWindow) _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int width, int height)); /* 127 */ void (*tk_MoveWindow) _ANSI_ARGS_((Tk_Window tkwin, int x, int y)); /* 128 */ void (*tk_MoveToplevelWindow) _ANSI_ARGS_((Tk_Window tkwin, int x, int y)); /* 129 */ @@ -824,15 +930,45 @@ typedef struct TkStubs { void (*tk_SizeOfImage) _ANSI_ARGS_((Tk_Image image, int * widthPtr, int * heightPtr)); /* 173 */ int (*tk_StrictMotif) _ANSI_ARGS_((Tk_Window tkwin)); /* 174 */ void (*tk_TextLayoutToPostscript) _ANSI_ARGS_((Tcl_Interp * interp, Tk_TextLayout layout)); /* 175 */ - int (*tk_TextWidth) _ANSI_ARGS_((Tk_Font font, CONST char * string, int numChars)); /* 176 */ + int (*tk_TextWidth) _ANSI_ARGS_((Tk_Font font, CONST char * str, int numBytes)); /* 176 */ void (*tk_UndefineCursor) _ANSI_ARGS_((Tk_Window window)); /* 177 */ - void (*tk_UnderlineChars) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char * source, int x, int y, int firstChar, int lastChar)); /* 178 */ + void (*tk_UnderlineChars) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_Font tkfont, CONST char * source, int x, int y, int firstByte, int lastByte)); /* 178 */ void (*tk_UnderlineTextLayout) _ANSI_ARGS_((Display * display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int underline)); /* 179 */ void (*tk_Ungrab) _ANSI_ARGS_((Tk_Window tkwin)); /* 180 */ void (*tk_UnmaintainGeometry) _ANSI_ARGS_((Tk_Window slave, Tk_Window master)); /* 181 */ void (*tk_UnmapWindow) _ANSI_ARGS_((Tk_Window tkwin)); /* 182 */ void (*tk_UnsetGrid) _ANSI_ARGS_((Tk_Window tkwin)); /* 183 */ void (*tk_UpdatePointer) _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int state)); /* 184 */ + Pixmap (*tk_AllocBitmapFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 185 */ + Tk_3DBorder (*tk_Alloc3DBorderFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 186 */ + XColor * (*tk_AllocColorFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 187 */ + Tk_Cursor (*tk_AllocCursorFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 188 */ + Tk_Font (*tk_AllocFontFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr)); /* 189 */ + Tk_OptionTable (*tk_CreateOptionTable) _ANSI_ARGS_((Tcl_Interp * interp, CONST Tk_OptionSpec * templatePtr)); /* 190 */ + void (*tk_DeleteOptionTable) _ANSI_ARGS_((Tk_OptionTable optionTable)); /* 191 */ + void (*tk_Free3DBorderFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 192 */ + void (*tk_FreeBitmapFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 193 */ + void (*tk_FreeColorFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 194 */ + void (*tk_FreeConfigOptions) _ANSI_ARGS_((char * recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin)); /* 195 */ + void (*tk_FreeSavedOptions) _ANSI_ARGS_((Tk_SavedOptions * savePtr)); /* 196 */ + void (*tk_FreeCursorFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 197 */ + void (*tk_FreeFontFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 198 */ + Tk_3DBorder (*tk_Get3DBorderFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 199 */ + int (*tk_GetAnchorFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, Tk_Anchor * anchorPtr)); /* 200 */ + Pixmap (*tk_GetBitmapFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 201 */ + XColor * (*tk_GetColorFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 202 */ + Tk_Cursor (*tk_GetCursorFromObj) _ANSI_ARGS_((Tk_Window tkwin, Tcl_Obj * objPtr)); /* 203 */ + Tcl_Obj * (*tk_GetOptionInfo) _ANSI_ARGS_((Tcl_Interp * interp, char * recordPtr, Tk_OptionTable optionTable, Tcl_Obj * namePtr, Tk_Window tkwin)); /* 204 */ + Tcl_Obj * (*tk_GetOptionValue) _ANSI_ARGS_((Tcl_Interp * interp, char * recordPtr, Tk_OptionTable optionTable, Tcl_Obj * namePtr, Tk_Window tkwin)); /* 205 */ + int (*tk_GetJustifyFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, Tk_Justify * justifyPtr)); /* 206 */ + int (*tk_GetMMFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr, double * doublePtr)); /* 207 */ + int (*tk_GetPixelsFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr, int * intPtr)); /* 208 */ + int (*tk_GetReliefFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * objPtr, int * resultPtr)); /* 209 */ + int (*tk_GetScrollInfoObj) _ANSI_ARGS_((Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[], double * dblPtr, int * intPtr)); /* 210 */ + int (*tk_InitOptions) _ANSI_ARGS_((Tcl_Interp * interp, char * recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin)); /* 211 */ + void (*tk_MainEx) _ANSI_ARGS_((int argc, char ** argv, Tcl_AppInitProc * appInitProc, Tcl_Interp * interp)); /* 212 */ + void (*tk_RestoreSavedOptions) _ANSI_ARGS_((Tk_SavedOptions * savePtr)); /* 213 */ + int (*tk_SetOptions) _ANSI_ARGS_((Tcl_Interp * interp, char * recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *CONST objv[], Tk_Window tkwin, Tk_SavedOptions * savePtr, int * maskPtr)); /* 214 */ } TkStubs; extern TkStubs *tkStubsPtr; @@ -844,744 +980,864 @@ extern TkStubs *tkStubsPtr; */ #ifndef Tk_MainLoop -#define Tk_MainLoop() \ - (tkStubsPtr->tk_MainLoop)() /* 0 */ +#define Tk_MainLoop \ + (tkStubsPtr->tk_MainLoop) /* 0 */ #endif #ifndef Tk_3DBorderColor -#define Tk_3DBorderColor(border) \ - (tkStubsPtr->tk_3DBorderColor)(border) /* 1 */ +#define Tk_3DBorderColor \ + (tkStubsPtr->tk_3DBorderColor) /* 1 */ #endif #ifndef Tk_3DBorderGC -#define Tk_3DBorderGC(tkwin, border, which) \ - (tkStubsPtr->tk_3DBorderGC)(tkwin, border, which) /* 2 */ +#define Tk_3DBorderGC \ + (tkStubsPtr->tk_3DBorderGC) /* 2 */ #endif #ifndef Tk_3DHorizontalBevel -#define Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief) \ - (tkStubsPtr->tk_3DHorizontalBevel)(tkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief) /* 3 */ +#define Tk_3DHorizontalBevel \ + (tkStubsPtr->tk_3DHorizontalBevel) /* 3 */ #endif #ifndef Tk_3DVerticalBevel -#define Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height, leftBevel, relief) \ - (tkStubsPtr->tk_3DVerticalBevel)(tkwin, drawable, border, x, y, width, height, leftBevel, relief) /* 4 */ +#define Tk_3DVerticalBevel \ + (tkStubsPtr->tk_3DVerticalBevel) /* 4 */ #endif #ifndef Tk_AddOption -#define Tk_AddOption(tkwin, name, value, priority) \ - (tkStubsPtr->tk_AddOption)(tkwin, name, value, priority) /* 5 */ +#define Tk_AddOption \ + (tkStubsPtr->tk_AddOption) /* 5 */ #endif #ifndef Tk_BindEvent -#define Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) \ - (tkStubsPtr->tk_BindEvent)(bindingTable, eventPtr, tkwin, numObjects, objectPtr) /* 6 */ +#define Tk_BindEvent \ + (tkStubsPtr->tk_BindEvent) /* 6 */ #endif #ifndef Tk_CanvasDrawableCoords -#define Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) \ - (tkStubsPtr->tk_CanvasDrawableCoords)(canvas, x, y, drawableXPtr, drawableYPtr) /* 7 */ +#define Tk_CanvasDrawableCoords \ + (tkStubsPtr->tk_CanvasDrawableCoords) /* 7 */ #endif #ifndef Tk_CanvasEventuallyRedraw -#define Tk_CanvasEventuallyRedraw(canvas, x1, y1, x2, y2) \ - (tkStubsPtr->tk_CanvasEventuallyRedraw)(canvas, x1, y1, x2, y2) /* 8 */ +#define Tk_CanvasEventuallyRedraw \ + (tkStubsPtr->tk_CanvasEventuallyRedraw) /* 8 */ #endif #ifndef Tk_CanvasGetCoord -#define Tk_CanvasGetCoord(interp, canvas, string, doublePtr) \ - (tkStubsPtr->tk_CanvasGetCoord)(interp, canvas, string, doublePtr) /* 9 */ +#define Tk_CanvasGetCoord \ + (tkStubsPtr->tk_CanvasGetCoord) /* 9 */ #endif #ifndef Tk_CanvasGetTextInfo -#define Tk_CanvasGetTextInfo(canvas) \ - (tkStubsPtr->tk_CanvasGetTextInfo)(canvas) /* 10 */ +#define Tk_CanvasGetTextInfo \ + (tkStubsPtr->tk_CanvasGetTextInfo) /* 10 */ #endif #ifndef Tk_CanvasPsBitmap -#define Tk_CanvasPsBitmap(interp, canvas, bitmap, x, y, width, height) \ - (tkStubsPtr->tk_CanvasPsBitmap)(interp, canvas, bitmap, x, y, width, height) /* 11 */ +#define Tk_CanvasPsBitmap \ + (tkStubsPtr->tk_CanvasPsBitmap) /* 11 */ #endif #ifndef Tk_CanvasPsColor -#define Tk_CanvasPsColor(interp, canvas, colorPtr) \ - (tkStubsPtr->tk_CanvasPsColor)(interp, canvas, colorPtr) /* 12 */ +#define Tk_CanvasPsColor \ + (tkStubsPtr->tk_CanvasPsColor) /* 12 */ #endif #ifndef Tk_CanvasPsFont -#define Tk_CanvasPsFont(interp, canvas, font) \ - (tkStubsPtr->tk_CanvasPsFont)(interp, canvas, font) /* 13 */ +#define Tk_CanvasPsFont \ + (tkStubsPtr->tk_CanvasPsFont) /* 13 */ #endif #ifndef Tk_CanvasPsPath -#define Tk_CanvasPsPath(interp, canvas, coordPtr, numPoints) \ - (tkStubsPtr->tk_CanvasPsPath)(interp, canvas, coordPtr, numPoints) /* 14 */ +#define Tk_CanvasPsPath \ + (tkStubsPtr->tk_CanvasPsPath) /* 14 */ #endif #ifndef Tk_CanvasPsStipple -#define Tk_CanvasPsStipple(interp, canvas, bitmap) \ - (tkStubsPtr->tk_CanvasPsStipple)(interp, canvas, bitmap) /* 15 */ +#define Tk_CanvasPsStipple \ + (tkStubsPtr->tk_CanvasPsStipple) /* 15 */ #endif #ifndef Tk_CanvasPsY -#define Tk_CanvasPsY(canvas, y) \ - (tkStubsPtr->tk_CanvasPsY)(canvas, y) /* 16 */ +#define Tk_CanvasPsY \ + (tkStubsPtr->tk_CanvasPsY) /* 16 */ #endif #ifndef Tk_CanvasSetStippleOrigin -#define Tk_CanvasSetStippleOrigin(canvas, gc) \ - (tkStubsPtr->tk_CanvasSetStippleOrigin)(canvas, gc) /* 17 */ +#define Tk_CanvasSetStippleOrigin \ + (tkStubsPtr->tk_CanvasSetStippleOrigin) /* 17 */ #endif #ifndef Tk_CanvasTagsParseProc -#define Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) \ - (tkStubsPtr->tk_CanvasTagsParseProc)(clientData, interp, tkwin, value, widgRec, offset) /* 18 */ +#define Tk_CanvasTagsParseProc \ + (tkStubsPtr->tk_CanvasTagsParseProc) /* 18 */ #endif #ifndef Tk_CanvasTagsPrintProc -#define Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) \ - (tkStubsPtr->tk_CanvasTagsPrintProc)(clientData, tkwin, widgRec, offset, freeProcPtr) /* 19 */ +#define Tk_CanvasTagsPrintProc \ + (tkStubsPtr->tk_CanvasTagsPrintProc) /* 19 */ #endif #ifndef Tk_CanvasTkwin -#define Tk_CanvasTkwin(canvas) \ - (tkStubsPtr->tk_CanvasTkwin)(canvas) /* 20 */ +#define Tk_CanvasTkwin \ + (tkStubsPtr->tk_CanvasTkwin) /* 20 */ #endif #ifndef Tk_CanvasWindowCoords -#define Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) \ - (tkStubsPtr->tk_CanvasWindowCoords)(canvas, x, y, screenXPtr, screenYPtr) /* 21 */ +#define Tk_CanvasWindowCoords \ + (tkStubsPtr->tk_CanvasWindowCoords) /* 21 */ #endif #ifndef Tk_ChangeWindowAttributes -#define Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr) \ - (tkStubsPtr->tk_ChangeWindowAttributes)(tkwin, valueMask, attsPtr) /* 22 */ +#define Tk_ChangeWindowAttributes \ + (tkStubsPtr->tk_ChangeWindowAttributes) /* 22 */ #endif #ifndef Tk_CharBbox -#define Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) \ - (tkStubsPtr->tk_CharBbox)(layout, index, xPtr, yPtr, widthPtr, heightPtr) /* 23 */ +#define Tk_CharBbox \ + (tkStubsPtr->tk_CharBbox) /* 23 */ #endif #ifndef Tk_ClearSelection -#define Tk_ClearSelection(tkwin, selection) \ - (tkStubsPtr->tk_ClearSelection)(tkwin, selection) /* 24 */ +#define Tk_ClearSelection \ + (tkStubsPtr->tk_ClearSelection) /* 24 */ #endif #ifndef Tk_ClipboardAppend -#define Tk_ClipboardAppend(interp, tkwin, target, format, buffer) \ - (tkStubsPtr->tk_ClipboardAppend)(interp, tkwin, target, format, buffer) /* 25 */ +#define Tk_ClipboardAppend \ + (tkStubsPtr->tk_ClipboardAppend) /* 25 */ #endif #ifndef Tk_ClipboardClear -#define Tk_ClipboardClear(interp, tkwin) \ - (tkStubsPtr->tk_ClipboardClear)(interp, tkwin) /* 26 */ +#define Tk_ClipboardClear \ + (tkStubsPtr->tk_ClipboardClear) /* 26 */ #endif #ifndef Tk_ConfigureInfo -#define Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) \ - (tkStubsPtr->tk_ConfigureInfo)(interp, tkwin, specs, widgRec, argvName, flags) /* 27 */ +#define Tk_ConfigureInfo \ + (tkStubsPtr->tk_ConfigureInfo) /* 27 */ #endif #ifndef Tk_ConfigureValue -#define Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags) \ - (tkStubsPtr->tk_ConfigureValue)(interp, tkwin, specs, widgRec, argvName, flags) /* 28 */ +#define Tk_ConfigureValue \ + (tkStubsPtr->tk_ConfigureValue) /* 28 */ #endif #ifndef Tk_ConfigureWidget -#define Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) \ - (tkStubsPtr->tk_ConfigureWidget)(interp, tkwin, specs, argc, argv, widgRec, flags) /* 29 */ +#define Tk_ConfigureWidget \ + (tkStubsPtr->tk_ConfigureWidget) /* 29 */ #endif #ifndef Tk_ConfigureWindow -#define Tk_ConfigureWindow(tkwin, valueMask, valuePtr) \ - (tkStubsPtr->tk_ConfigureWindow)(tkwin, valueMask, valuePtr) /* 30 */ +#define Tk_ConfigureWindow \ + (tkStubsPtr->tk_ConfigureWindow) /* 30 */ #endif #ifndef Tk_ComputeTextLayout -#define Tk_ComputeTextLayout(font, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr) \ - (tkStubsPtr->tk_ComputeTextLayout)(font, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr) /* 31 */ +#define Tk_ComputeTextLayout \ + (tkStubsPtr->tk_ComputeTextLayout) /* 31 */ #endif #ifndef Tk_CoordsToWindow -#define Tk_CoordsToWindow(rootX, rootY, tkwin) \ - (tkStubsPtr->tk_CoordsToWindow)(rootX, rootY, tkwin) /* 32 */ +#define Tk_CoordsToWindow \ + (tkStubsPtr->tk_CoordsToWindow) /* 32 */ #endif #ifndef Tk_CreateBinding -#define Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) \ - (tkStubsPtr->tk_CreateBinding)(interp, bindingTable, object, eventString, command, append) /* 33 */ +#define Tk_CreateBinding \ + (tkStubsPtr->tk_CreateBinding) /* 33 */ #endif #ifndef Tk_CreateBindingTable -#define Tk_CreateBindingTable(interp) \ - (tkStubsPtr->tk_CreateBindingTable)(interp) /* 34 */ +#define Tk_CreateBindingTable \ + (tkStubsPtr->tk_CreateBindingTable) /* 34 */ #endif #ifndef Tk_CreateErrorHandler -#define Tk_CreateErrorHandler(display, errNum, request, minorCode, errorProc, clientData) \ - (tkStubsPtr->tk_CreateErrorHandler)(display, errNum, request, minorCode, errorProc, clientData) /* 35 */ +#define Tk_CreateErrorHandler \ + (tkStubsPtr->tk_CreateErrorHandler) /* 35 */ #endif #ifndef Tk_CreateEventHandler -#define Tk_CreateEventHandler(token, mask, proc, clientData) \ - (tkStubsPtr->tk_CreateEventHandler)(token, mask, proc, clientData) /* 36 */ +#define Tk_CreateEventHandler \ + (tkStubsPtr->tk_CreateEventHandler) /* 36 */ #endif #ifndef Tk_CreateGenericHandler -#define Tk_CreateGenericHandler(proc, clientData) \ - (tkStubsPtr->tk_CreateGenericHandler)(proc, clientData) /* 37 */ +#define Tk_CreateGenericHandler \ + (tkStubsPtr->tk_CreateGenericHandler) /* 37 */ #endif #ifndef Tk_CreateImageType -#define Tk_CreateImageType(typePtr) \ - (tkStubsPtr->tk_CreateImageType)(typePtr) /* 38 */ +#define Tk_CreateImageType \ + (tkStubsPtr->tk_CreateImageType) /* 38 */ #endif #ifndef Tk_CreateItemType -#define Tk_CreateItemType(typePtr) \ - (tkStubsPtr->tk_CreateItemType)(typePtr) /* 39 */ +#define Tk_CreateItemType \ + (tkStubsPtr->tk_CreateItemType) /* 39 */ #endif #ifndef Tk_CreatePhotoImageFormat -#define Tk_CreatePhotoImageFormat(formatPtr) \ - (tkStubsPtr->tk_CreatePhotoImageFormat)(formatPtr) /* 40 */ +#define Tk_CreatePhotoImageFormat \ + (tkStubsPtr->tk_CreatePhotoImageFormat) /* 40 */ #endif #ifndef Tk_CreateSelHandler -#define Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format) \ - (tkStubsPtr->tk_CreateSelHandler)(tkwin, selection, target, proc, clientData, format) /* 41 */ +#define Tk_CreateSelHandler \ + (tkStubsPtr->tk_CreateSelHandler) /* 41 */ #endif #ifndef Tk_CreateWindow -#define Tk_CreateWindow(interp, parent, name, screenName) \ - (tkStubsPtr->tk_CreateWindow)(interp, parent, name, screenName) /* 42 */ +#define Tk_CreateWindow \ + (tkStubsPtr->tk_CreateWindow) /* 42 */ #endif #ifndef Tk_CreateWindowFromPath -#define Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName) \ - (tkStubsPtr->tk_CreateWindowFromPath)(interp, tkwin, pathName, screenName) /* 43 */ +#define Tk_CreateWindowFromPath \ + (tkStubsPtr->tk_CreateWindowFromPath) /* 43 */ #endif #ifndef Tk_DefineBitmap -#define Tk_DefineBitmap(interp, name, source, width, height) \ - (tkStubsPtr->tk_DefineBitmap)(interp, name, source, width, height) /* 44 */ +#define Tk_DefineBitmap \ + (tkStubsPtr->tk_DefineBitmap) /* 44 */ #endif #ifndef Tk_DefineCursor -#define Tk_DefineCursor(window, cursor) \ - (tkStubsPtr->tk_DefineCursor)(window, cursor) /* 45 */ +#define Tk_DefineCursor \ + (tkStubsPtr->tk_DefineCursor) /* 45 */ #endif #ifndef Tk_DeleteAllBindings -#define Tk_DeleteAllBindings(bindingTable, object) \ - (tkStubsPtr->tk_DeleteAllBindings)(bindingTable, object) /* 46 */ +#define Tk_DeleteAllBindings \ + (tkStubsPtr->tk_DeleteAllBindings) /* 46 */ #endif #ifndef Tk_DeleteBinding -#define Tk_DeleteBinding(interp, bindingTable, object, eventString) \ - (tkStubsPtr->tk_DeleteBinding)(interp, bindingTable, object, eventString) /* 47 */ +#define Tk_DeleteBinding \ + (tkStubsPtr->tk_DeleteBinding) /* 47 */ #endif #ifndef Tk_DeleteBindingTable -#define Tk_DeleteBindingTable(bindingTable) \ - (tkStubsPtr->tk_DeleteBindingTable)(bindingTable) /* 48 */ +#define Tk_DeleteBindingTable \ + (tkStubsPtr->tk_DeleteBindingTable) /* 48 */ #endif #ifndef Tk_DeleteErrorHandler -#define Tk_DeleteErrorHandler(handler) \ - (tkStubsPtr->tk_DeleteErrorHandler)(handler) /* 49 */ +#define Tk_DeleteErrorHandler \ + (tkStubsPtr->tk_DeleteErrorHandler) /* 49 */ #endif #ifndef Tk_DeleteEventHandler -#define Tk_DeleteEventHandler(token, mask, proc, clientData) \ - (tkStubsPtr->tk_DeleteEventHandler)(token, mask, proc, clientData) /* 50 */ +#define Tk_DeleteEventHandler \ + (tkStubsPtr->tk_DeleteEventHandler) /* 50 */ #endif #ifndef Tk_DeleteGenericHandler -#define Tk_DeleteGenericHandler(proc, clientData) \ - (tkStubsPtr->tk_DeleteGenericHandler)(proc, clientData) /* 51 */ +#define Tk_DeleteGenericHandler \ + (tkStubsPtr->tk_DeleteGenericHandler) /* 51 */ #endif #ifndef Tk_DeleteImage -#define Tk_DeleteImage(interp, name) \ - (tkStubsPtr->tk_DeleteImage)(interp, name) /* 52 */ +#define Tk_DeleteImage \ + (tkStubsPtr->tk_DeleteImage) /* 52 */ #endif #ifndef Tk_DeleteSelHandler -#define Tk_DeleteSelHandler(tkwin, selection, target) \ - (tkStubsPtr->tk_DeleteSelHandler)(tkwin, selection, target) /* 53 */ +#define Tk_DeleteSelHandler \ + (tkStubsPtr->tk_DeleteSelHandler) /* 53 */ #endif #ifndef Tk_DestroyWindow -#define Tk_DestroyWindow(tkwin) \ - (tkStubsPtr->tk_DestroyWindow)(tkwin) /* 54 */ +#define Tk_DestroyWindow \ + (tkStubsPtr->tk_DestroyWindow) /* 54 */ #endif #ifndef Tk_DisplayName -#define Tk_DisplayName(tkwin) \ - (tkStubsPtr->tk_DisplayName)(tkwin) /* 55 */ +#define Tk_DisplayName \ + (tkStubsPtr->tk_DisplayName) /* 55 */ #endif #ifndef Tk_DistanceToTextLayout -#define Tk_DistanceToTextLayout(layout, x, y) \ - (tkStubsPtr->tk_DistanceToTextLayout)(layout, x, y) /* 56 */ +#define Tk_DistanceToTextLayout \ + (tkStubsPtr->tk_DistanceToTextLayout) /* 56 */ #endif #ifndef Tk_Draw3DPolygon -#define Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) \ - (tkStubsPtr->tk_Draw3DPolygon)(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) /* 57 */ +#define Tk_Draw3DPolygon \ + (tkStubsPtr->tk_Draw3DPolygon) /* 57 */ #endif #ifndef Tk_Draw3DRectangle -#define Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) \ - (tkStubsPtr->tk_Draw3DRectangle)(tkwin, drawable, border, x, y, width, height, borderWidth, relief) /* 58 */ +#define Tk_Draw3DRectangle \ + (tkStubsPtr->tk_Draw3DRectangle) /* 58 */ #endif #ifndef Tk_DrawChars -#define Tk_DrawChars(display, drawable, gc, tkfont, source, numChars, x, y) \ - (tkStubsPtr->tk_DrawChars)(display, drawable, gc, tkfont, source, numChars, x, y) /* 59 */ +#define Tk_DrawChars \ + (tkStubsPtr->tk_DrawChars) /* 59 */ #endif #ifndef Tk_DrawFocusHighlight -#define Tk_DrawFocusHighlight(tkwin, gc, width, drawable) \ - (tkStubsPtr->tk_DrawFocusHighlight)(tkwin, gc, width, drawable) /* 60 */ +#define Tk_DrawFocusHighlight \ + (tkStubsPtr->tk_DrawFocusHighlight) /* 60 */ #endif #ifndef Tk_DrawTextLayout -#define Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) \ - (tkStubsPtr->tk_DrawTextLayout)(display, drawable, gc, layout, x, y, firstChar, lastChar) /* 61 */ +#define Tk_DrawTextLayout \ + (tkStubsPtr->tk_DrawTextLayout) /* 61 */ #endif #ifndef Tk_Fill3DPolygon -#define Tk_Fill3DPolygon(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) \ - (tkStubsPtr->tk_Fill3DPolygon)(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) /* 62 */ +#define Tk_Fill3DPolygon \ + (tkStubsPtr->tk_Fill3DPolygon) /* 62 */ #endif #ifndef Tk_Fill3DRectangle -#define Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) \ - (tkStubsPtr->tk_Fill3DRectangle)(tkwin, drawable, border, x, y, width, height, borderWidth, relief) /* 63 */ +#define Tk_Fill3DRectangle \ + (tkStubsPtr->tk_Fill3DRectangle) /* 63 */ #endif #ifndef Tk_FindPhoto -#define Tk_FindPhoto(interp, imageName) \ - (tkStubsPtr->tk_FindPhoto)(interp, imageName) /* 64 */ +#define Tk_FindPhoto \ + (tkStubsPtr->tk_FindPhoto) /* 64 */ #endif #ifndef Tk_FontId -#define Tk_FontId(font) \ - (tkStubsPtr->tk_FontId)(font) /* 65 */ +#define Tk_FontId \ + (tkStubsPtr->tk_FontId) /* 65 */ #endif #ifndef Tk_Free3DBorder -#define Tk_Free3DBorder(border) \ - (tkStubsPtr->tk_Free3DBorder)(border) /* 66 */ +#define Tk_Free3DBorder \ + (tkStubsPtr->tk_Free3DBorder) /* 66 */ #endif #ifndef Tk_FreeBitmap -#define Tk_FreeBitmap(display, bitmap) \ - (tkStubsPtr->tk_FreeBitmap)(display, bitmap) /* 67 */ +#define Tk_FreeBitmap \ + (tkStubsPtr->tk_FreeBitmap) /* 67 */ #endif #ifndef Tk_FreeColor -#define Tk_FreeColor(colorPtr) \ - (tkStubsPtr->tk_FreeColor)(colorPtr) /* 68 */ +#define Tk_FreeColor \ + (tkStubsPtr->tk_FreeColor) /* 68 */ #endif #ifndef Tk_FreeColormap -#define Tk_FreeColormap(display, colormap) \ - (tkStubsPtr->tk_FreeColormap)(display, colormap) /* 69 */ +#define Tk_FreeColormap \ + (tkStubsPtr->tk_FreeColormap) /* 69 */ #endif #ifndef Tk_FreeCursor -#define Tk_FreeCursor(display, cursor) \ - (tkStubsPtr->tk_FreeCursor)(display, cursor) /* 70 */ +#define Tk_FreeCursor \ + (tkStubsPtr->tk_FreeCursor) /* 70 */ #endif #ifndef Tk_FreeFont -#define Tk_FreeFont(f) \ - (tkStubsPtr->tk_FreeFont)(f) /* 71 */ +#define Tk_FreeFont \ + (tkStubsPtr->tk_FreeFont) /* 71 */ #endif #ifndef Tk_FreeGC -#define Tk_FreeGC(display, gc) \ - (tkStubsPtr->tk_FreeGC)(display, gc) /* 72 */ +#define Tk_FreeGC \ + (tkStubsPtr->tk_FreeGC) /* 72 */ #endif #ifndef Tk_FreeImage -#define Tk_FreeImage(image) \ - (tkStubsPtr->tk_FreeImage)(image) /* 73 */ +#define Tk_FreeImage \ + (tkStubsPtr->tk_FreeImage) /* 73 */ #endif #ifndef Tk_FreeOptions -#define Tk_FreeOptions(specs, widgRec, display, needFlags) \ - (tkStubsPtr->tk_FreeOptions)(specs, widgRec, display, needFlags) /* 74 */ +#define Tk_FreeOptions \ + (tkStubsPtr->tk_FreeOptions) /* 74 */ #endif #ifndef Tk_FreePixmap -#define Tk_FreePixmap(display, pixmap) \ - (tkStubsPtr->tk_FreePixmap)(display, pixmap) /* 75 */ +#define Tk_FreePixmap \ + (tkStubsPtr->tk_FreePixmap) /* 75 */ #endif #ifndef Tk_FreeTextLayout -#define Tk_FreeTextLayout(textLayout) \ - (tkStubsPtr->tk_FreeTextLayout)(textLayout) /* 76 */ +#define Tk_FreeTextLayout \ + (tkStubsPtr->tk_FreeTextLayout) /* 76 */ #endif #ifndef Tk_FreeXId -#define Tk_FreeXId(display, xid) \ - (tkStubsPtr->tk_FreeXId)(display, xid) /* 77 */ +#define Tk_FreeXId \ + (tkStubsPtr->tk_FreeXId) /* 77 */ #endif #ifndef Tk_GCForColor -#define Tk_GCForColor(colorPtr, drawable) \ - (tkStubsPtr->tk_GCForColor)(colorPtr, drawable) /* 78 */ +#define Tk_GCForColor \ + (tkStubsPtr->tk_GCForColor) /* 78 */ #endif #ifndef Tk_GeometryRequest -#define Tk_GeometryRequest(tkwin, reqWidth, reqHeight) \ - (tkStubsPtr->tk_GeometryRequest)(tkwin, reqWidth, reqHeight) /* 79 */ +#define Tk_GeometryRequest \ + (tkStubsPtr->tk_GeometryRequest) /* 79 */ #endif #ifndef Tk_Get3DBorder -#define Tk_Get3DBorder(interp, tkwin, colorName) \ - (tkStubsPtr->tk_Get3DBorder)(interp, tkwin, colorName) /* 80 */ +#define Tk_Get3DBorder \ + (tkStubsPtr->tk_Get3DBorder) /* 80 */ #endif #ifndef Tk_GetAllBindings -#define Tk_GetAllBindings(interp, bindingTable, object) \ - (tkStubsPtr->tk_GetAllBindings)(interp, bindingTable, object) /* 81 */ +#define Tk_GetAllBindings \ + (tkStubsPtr->tk_GetAllBindings) /* 81 */ #endif #ifndef Tk_GetAnchor -#define Tk_GetAnchor(interp, string, anchorPtr) \ - (tkStubsPtr->tk_GetAnchor)(interp, string, anchorPtr) /* 82 */ +#define Tk_GetAnchor \ + (tkStubsPtr->tk_GetAnchor) /* 82 */ #endif #ifndef Tk_GetAtomName -#define Tk_GetAtomName(tkwin, atom) \ - (tkStubsPtr->tk_GetAtomName)(tkwin, atom) /* 83 */ +#define Tk_GetAtomName \ + (tkStubsPtr->tk_GetAtomName) /* 83 */ #endif #ifndef Tk_GetBinding -#define Tk_GetBinding(interp, bindingTable, object, eventString) \ - (tkStubsPtr->tk_GetBinding)(interp, bindingTable, object, eventString) /* 84 */ +#define Tk_GetBinding \ + (tkStubsPtr->tk_GetBinding) /* 84 */ #endif #ifndef Tk_GetBitmap -#define Tk_GetBitmap(interp, tkwin, string) \ - (tkStubsPtr->tk_GetBitmap)(interp, tkwin, string) /* 85 */ +#define Tk_GetBitmap \ + (tkStubsPtr->tk_GetBitmap) /* 85 */ #endif #ifndef Tk_GetBitmapFromData -#define Tk_GetBitmapFromData(interp, tkwin, source, width, height) \ - (tkStubsPtr->tk_GetBitmapFromData)(interp, tkwin, source, width, height) /* 86 */ +#define Tk_GetBitmapFromData \ + (tkStubsPtr->tk_GetBitmapFromData) /* 86 */ #endif #ifndef Tk_GetCapStyle -#define Tk_GetCapStyle(interp, string, capPtr) \ - (tkStubsPtr->tk_GetCapStyle)(interp, string, capPtr) /* 87 */ +#define Tk_GetCapStyle \ + (tkStubsPtr->tk_GetCapStyle) /* 87 */ #endif #ifndef Tk_GetColor -#define Tk_GetColor(interp, tkwin, name) \ - (tkStubsPtr->tk_GetColor)(interp, tkwin, name) /* 88 */ +#define Tk_GetColor \ + (tkStubsPtr->tk_GetColor) /* 88 */ #endif #ifndef Tk_GetColorByValue -#define Tk_GetColorByValue(tkwin, colorPtr) \ - (tkStubsPtr->tk_GetColorByValue)(tkwin, colorPtr) /* 89 */ +#define Tk_GetColorByValue \ + (tkStubsPtr->tk_GetColorByValue) /* 89 */ #endif #ifndef Tk_GetColormap -#define Tk_GetColormap(interp, tkwin, string) \ - (tkStubsPtr->tk_GetColormap)(interp, tkwin, string) /* 90 */ +#define Tk_GetColormap \ + (tkStubsPtr->tk_GetColormap) /* 90 */ #endif #ifndef Tk_GetCursor -#define Tk_GetCursor(interp, tkwin, string) \ - (tkStubsPtr->tk_GetCursor)(interp, tkwin, string) /* 91 */ +#define Tk_GetCursor \ + (tkStubsPtr->tk_GetCursor) /* 91 */ #endif #ifndef Tk_GetCursorFromData -#define Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, xHot, yHot, fg, bg) \ - (tkStubsPtr->tk_GetCursorFromData)(interp, tkwin, source, mask, width, height, xHot, yHot, fg, bg) /* 92 */ +#define Tk_GetCursorFromData \ + (tkStubsPtr->tk_GetCursorFromData) /* 92 */ #endif #ifndef Tk_GetFont -#define Tk_GetFont(interp, tkwin, string) \ - (tkStubsPtr->tk_GetFont)(interp, tkwin, string) /* 93 */ +#define Tk_GetFont \ + (tkStubsPtr->tk_GetFont) /* 93 */ #endif #ifndef Tk_GetFontFromObj -#define Tk_GetFontFromObj(interp, tkwin, objPtr) \ - (tkStubsPtr->tk_GetFontFromObj)(interp, tkwin, objPtr) /* 94 */ +#define Tk_GetFontFromObj \ + (tkStubsPtr->tk_GetFontFromObj) /* 94 */ #endif #ifndef Tk_GetFontMetrics -#define Tk_GetFontMetrics(font, fmPtr) \ - (tkStubsPtr->tk_GetFontMetrics)(font, fmPtr) /* 95 */ +#define Tk_GetFontMetrics \ + (tkStubsPtr->tk_GetFontMetrics) /* 95 */ #endif #ifndef Tk_GetGC -#define Tk_GetGC(tkwin, valueMask, valuePtr) \ - (tkStubsPtr->tk_GetGC)(tkwin, valueMask, valuePtr) /* 96 */ +#define Tk_GetGC \ + (tkStubsPtr->tk_GetGC) /* 96 */ #endif #ifndef Tk_GetImage -#define Tk_GetImage(interp, tkwin, name, changeProc, clientData) \ - (tkStubsPtr->tk_GetImage)(interp, tkwin, name, changeProc, clientData) /* 97 */ +#define Tk_GetImage \ + (tkStubsPtr->tk_GetImage) /* 97 */ #endif #ifndef Tk_GetImageMasterData -#define Tk_GetImageMasterData(interp, name, typePtrPtr) \ - (tkStubsPtr->tk_GetImageMasterData)(interp, name, typePtrPtr) /* 98 */ +#define Tk_GetImageMasterData \ + (tkStubsPtr->tk_GetImageMasterData) /* 98 */ #endif #ifndef Tk_GetItemTypes -#define Tk_GetItemTypes() \ - (tkStubsPtr->tk_GetItemTypes)() /* 99 */ +#define Tk_GetItemTypes \ + (tkStubsPtr->tk_GetItemTypes) /* 99 */ #endif #ifndef Tk_GetJoinStyle -#define Tk_GetJoinStyle(interp, string, joinPtr) \ - (tkStubsPtr->tk_GetJoinStyle)(interp, string, joinPtr) /* 100 */ +#define Tk_GetJoinStyle \ + (tkStubsPtr->tk_GetJoinStyle) /* 100 */ #endif #ifndef Tk_GetJustify -#define Tk_GetJustify(interp, string, justifyPtr) \ - (tkStubsPtr->tk_GetJustify)(interp, string, justifyPtr) /* 101 */ +#define Tk_GetJustify \ + (tkStubsPtr->tk_GetJustify) /* 101 */ #endif #ifndef Tk_GetNumMainWindows -#define Tk_GetNumMainWindows() \ - (tkStubsPtr->tk_GetNumMainWindows)() /* 102 */ +#define Tk_GetNumMainWindows \ + (tkStubsPtr->tk_GetNumMainWindows) /* 102 */ #endif #ifndef Tk_GetOption -#define Tk_GetOption(tkwin, name, className) \ - (tkStubsPtr->tk_GetOption)(tkwin, name, className) /* 103 */ +#define Tk_GetOption \ + (tkStubsPtr->tk_GetOption) /* 103 */ #endif #ifndef Tk_GetPixels -#define Tk_GetPixels(interp, tkwin, string, intPtr) \ - (tkStubsPtr->tk_GetPixels)(interp, tkwin, string, intPtr) /* 104 */ +#define Tk_GetPixels \ + (tkStubsPtr->tk_GetPixels) /* 104 */ #endif #ifndef Tk_GetPixmap -#define Tk_GetPixmap(display, d, width, height, depth) \ - (tkStubsPtr->tk_GetPixmap)(display, d, width, height, depth) /* 105 */ +#define Tk_GetPixmap \ + (tkStubsPtr->tk_GetPixmap) /* 105 */ #endif #ifndef Tk_GetRelief -#define Tk_GetRelief(interp, name, reliefPtr) \ - (tkStubsPtr->tk_GetRelief)(interp, name, reliefPtr) /* 106 */ +#define Tk_GetRelief \ + (tkStubsPtr->tk_GetRelief) /* 106 */ #endif #ifndef Tk_GetRootCoords -#define Tk_GetRootCoords(tkwin, xPtr, yPtr) \ - (tkStubsPtr->tk_GetRootCoords)(tkwin, xPtr, yPtr) /* 107 */ +#define Tk_GetRootCoords \ + (tkStubsPtr->tk_GetRootCoords) /* 107 */ #endif #ifndef Tk_GetScrollInfo -#define Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr) \ - (tkStubsPtr->tk_GetScrollInfo)(interp, argc, argv, dblPtr, intPtr) /* 108 */ +#define Tk_GetScrollInfo \ + (tkStubsPtr->tk_GetScrollInfo) /* 108 */ #endif #ifndef Tk_GetScreenMM -#define Tk_GetScreenMM(interp, tkwin, string, doublePtr) \ - (tkStubsPtr->tk_GetScreenMM)(interp, tkwin, string, doublePtr) /* 109 */ +#define Tk_GetScreenMM \ + (tkStubsPtr->tk_GetScreenMM) /* 109 */ #endif #ifndef Tk_GetSelection -#define Tk_GetSelection(interp, tkwin, selection, target, proc, clientData) \ - (tkStubsPtr->tk_GetSelection)(interp, tkwin, selection, target, proc, clientData) /* 110 */ +#define Tk_GetSelection \ + (tkStubsPtr->tk_GetSelection) /* 110 */ #endif #ifndef Tk_GetUid -#define Tk_GetUid(string) \ - (tkStubsPtr->tk_GetUid)(string) /* 111 */ +#define Tk_GetUid \ + (tkStubsPtr->tk_GetUid) /* 111 */ #endif #ifndef Tk_GetVisual -#define Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr) \ - (tkStubsPtr->tk_GetVisual)(interp, tkwin, string, depthPtr, colormapPtr) /* 112 */ +#define Tk_GetVisual \ + (tkStubsPtr->tk_GetVisual) /* 112 */ #endif #ifndef Tk_GetVRootGeometry -#define Tk_GetVRootGeometry(tkwin, xPtr, yPtr, widthPtr, heightPtr) \ - (tkStubsPtr->tk_GetVRootGeometry)(tkwin, xPtr, yPtr, widthPtr, heightPtr) /* 113 */ +#define Tk_GetVRootGeometry \ + (tkStubsPtr->tk_GetVRootGeometry) /* 113 */ #endif #ifndef Tk_Grab -#define Tk_Grab(interp, tkwin, grabGlobal) \ - (tkStubsPtr->tk_Grab)(interp, tkwin, grabGlobal) /* 114 */ +#define Tk_Grab \ + (tkStubsPtr->tk_Grab) /* 114 */ #endif #ifndef Tk_HandleEvent -#define Tk_HandleEvent(eventPtr) \ - (tkStubsPtr->tk_HandleEvent)(eventPtr) /* 115 */ +#define Tk_HandleEvent \ + (tkStubsPtr->tk_HandleEvent) /* 115 */ #endif #ifndef Tk_IdToWindow -#define Tk_IdToWindow(display, window) \ - (tkStubsPtr->tk_IdToWindow)(display, window) /* 116 */ +#define Tk_IdToWindow \ + (tkStubsPtr->tk_IdToWindow) /* 116 */ #endif #ifndef Tk_ImageChanged -#define Tk_ImageChanged(master, x, y, width, height, imageWidth, imageHeight) \ - (tkStubsPtr->tk_ImageChanged)(master, x, y, width, height, imageWidth, imageHeight) /* 117 */ +#define Tk_ImageChanged \ + (tkStubsPtr->tk_ImageChanged) /* 117 */ #endif #ifndef Tk_Init -#define Tk_Init(interp) \ - (tkStubsPtr->tk_Init)(interp) /* 118 */ +#define Tk_Init \ + (tkStubsPtr->tk_Init) /* 118 */ #endif #ifndef Tk_InternAtom -#define Tk_InternAtom(tkwin, name) \ - (tkStubsPtr->tk_InternAtom)(tkwin, name) /* 119 */ +#define Tk_InternAtom \ + (tkStubsPtr->tk_InternAtom) /* 119 */ #endif #ifndef Tk_IntersectTextLayout -#define Tk_IntersectTextLayout(layout, x, y, width, height) \ - (tkStubsPtr->tk_IntersectTextLayout)(layout, x, y, width, height) /* 120 */ +#define Tk_IntersectTextLayout \ + (tkStubsPtr->tk_IntersectTextLayout) /* 120 */ #endif #ifndef Tk_MaintainGeometry -#define Tk_MaintainGeometry(slave, master, x, y, width, height) \ - (tkStubsPtr->tk_MaintainGeometry)(slave, master, x, y, width, height) /* 121 */ +#define Tk_MaintainGeometry \ + (tkStubsPtr->tk_MaintainGeometry) /* 121 */ #endif #ifndef Tk_MainWindow -#define Tk_MainWindow(interp) \ - (tkStubsPtr->tk_MainWindow)(interp) /* 122 */ +#define Tk_MainWindow \ + (tkStubsPtr->tk_MainWindow) /* 122 */ #endif #ifndef Tk_MakeWindowExist -#define Tk_MakeWindowExist(tkwin) \ - (tkStubsPtr->tk_MakeWindowExist)(tkwin) /* 123 */ +#define Tk_MakeWindowExist \ + (tkStubsPtr->tk_MakeWindowExist) /* 123 */ #endif #ifndef Tk_ManageGeometry -#define Tk_ManageGeometry(tkwin, mgrPtr, clientData) \ - (tkStubsPtr->tk_ManageGeometry)(tkwin, mgrPtr, clientData) /* 124 */ +#define Tk_ManageGeometry \ + (tkStubsPtr->tk_ManageGeometry) /* 124 */ #endif #ifndef Tk_MapWindow -#define Tk_MapWindow(tkwin) \ - (tkStubsPtr->tk_MapWindow)(tkwin) /* 125 */ +#define Tk_MapWindow \ + (tkStubsPtr->tk_MapWindow) /* 125 */ #endif #ifndef Tk_MeasureChars -#define Tk_MeasureChars(tkfont, source, maxChars, maxPixels, flags, lengthPtr) \ - (tkStubsPtr->tk_MeasureChars)(tkfont, source, maxChars, maxPixels, flags, lengthPtr) /* 126 */ +#define Tk_MeasureChars \ + (tkStubsPtr->tk_MeasureChars) /* 126 */ #endif #ifndef Tk_MoveResizeWindow -#define Tk_MoveResizeWindow(tkwin, x, y, width, height) \ - (tkStubsPtr->tk_MoveResizeWindow)(tkwin, x, y, width, height) /* 127 */ +#define Tk_MoveResizeWindow \ + (tkStubsPtr->tk_MoveResizeWindow) /* 127 */ #endif #ifndef Tk_MoveWindow -#define Tk_MoveWindow(tkwin, x, y) \ - (tkStubsPtr->tk_MoveWindow)(tkwin, x, y) /* 128 */ +#define Tk_MoveWindow \ + (tkStubsPtr->tk_MoveWindow) /* 128 */ #endif #ifndef Tk_MoveToplevelWindow -#define Tk_MoveToplevelWindow(tkwin, x, y) \ - (tkStubsPtr->tk_MoveToplevelWindow)(tkwin, x, y) /* 129 */ +#define Tk_MoveToplevelWindow \ + (tkStubsPtr->tk_MoveToplevelWindow) /* 129 */ #endif #ifndef Tk_NameOf3DBorder -#define Tk_NameOf3DBorder(border) \ - (tkStubsPtr->tk_NameOf3DBorder)(border) /* 130 */ +#define Tk_NameOf3DBorder \ + (tkStubsPtr->tk_NameOf3DBorder) /* 130 */ #endif #ifndef Tk_NameOfAnchor -#define Tk_NameOfAnchor(anchor) \ - (tkStubsPtr->tk_NameOfAnchor)(anchor) /* 131 */ +#define Tk_NameOfAnchor \ + (tkStubsPtr->tk_NameOfAnchor) /* 131 */ #endif #ifndef Tk_NameOfBitmap -#define Tk_NameOfBitmap(display, bitmap) \ - (tkStubsPtr->tk_NameOfBitmap)(display, bitmap) /* 132 */ +#define Tk_NameOfBitmap \ + (tkStubsPtr->tk_NameOfBitmap) /* 132 */ #endif #ifndef Tk_NameOfCapStyle -#define Tk_NameOfCapStyle(cap) \ - (tkStubsPtr->tk_NameOfCapStyle)(cap) /* 133 */ +#define Tk_NameOfCapStyle \ + (tkStubsPtr->tk_NameOfCapStyle) /* 133 */ #endif #ifndef Tk_NameOfColor -#define Tk_NameOfColor(colorPtr) \ - (tkStubsPtr->tk_NameOfColor)(colorPtr) /* 134 */ +#define Tk_NameOfColor \ + (tkStubsPtr->tk_NameOfColor) /* 134 */ #endif #ifndef Tk_NameOfCursor -#define Tk_NameOfCursor(display, cursor) \ - (tkStubsPtr->tk_NameOfCursor)(display, cursor) /* 135 */ +#define Tk_NameOfCursor \ + (tkStubsPtr->tk_NameOfCursor) /* 135 */ #endif #ifndef Tk_NameOfFont -#define Tk_NameOfFont(font) \ - (tkStubsPtr->tk_NameOfFont)(font) /* 136 */ +#define Tk_NameOfFont \ + (tkStubsPtr->tk_NameOfFont) /* 136 */ #endif #ifndef Tk_NameOfImage -#define Tk_NameOfImage(imageMaster) \ - (tkStubsPtr->tk_NameOfImage)(imageMaster) /* 137 */ +#define Tk_NameOfImage \ + (tkStubsPtr->tk_NameOfImage) /* 137 */ #endif #ifndef Tk_NameOfJoinStyle -#define Tk_NameOfJoinStyle(join) \ - (tkStubsPtr->tk_NameOfJoinStyle)(join) /* 138 */ +#define Tk_NameOfJoinStyle \ + (tkStubsPtr->tk_NameOfJoinStyle) /* 138 */ #endif #ifndef Tk_NameOfJustify -#define Tk_NameOfJustify(justify) \ - (tkStubsPtr->tk_NameOfJustify)(justify) /* 139 */ +#define Tk_NameOfJustify \ + (tkStubsPtr->tk_NameOfJustify) /* 139 */ #endif #ifndef Tk_NameOfRelief -#define Tk_NameOfRelief(relief) \ - (tkStubsPtr->tk_NameOfRelief)(relief) /* 140 */ +#define Tk_NameOfRelief \ + (tkStubsPtr->tk_NameOfRelief) /* 140 */ #endif #ifndef Tk_NameToWindow -#define Tk_NameToWindow(interp, pathName, tkwin) \ - (tkStubsPtr->tk_NameToWindow)(interp, pathName, tkwin) /* 141 */ +#define Tk_NameToWindow \ + (tkStubsPtr->tk_NameToWindow) /* 141 */ #endif #ifndef Tk_OwnSelection -#define Tk_OwnSelection(tkwin, selection, proc, clientData) \ - (tkStubsPtr->tk_OwnSelection)(tkwin, selection, proc, clientData) /* 142 */ +#define Tk_OwnSelection \ + (tkStubsPtr->tk_OwnSelection) /* 142 */ #endif #ifndef Tk_ParseArgv -#define Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) \ - (tkStubsPtr->tk_ParseArgv)(interp, tkwin, argcPtr, argv, argTable, flags) /* 143 */ +#define Tk_ParseArgv \ + (tkStubsPtr->tk_ParseArgv) /* 143 */ #endif #ifndef Tk_PhotoPutBlock -#define Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height) \ - (tkStubsPtr->tk_PhotoPutBlock)(handle, blockPtr, x, y, width, height) /* 144 */ +#define Tk_PhotoPutBlock \ + (tkStubsPtr->tk_PhotoPutBlock) /* 144 */ #endif #ifndef Tk_PhotoPutZoomedBlock -#define Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY) \ - (tkStubsPtr->tk_PhotoPutZoomedBlock)(handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY) /* 145 */ +#define Tk_PhotoPutZoomedBlock \ + (tkStubsPtr->tk_PhotoPutZoomedBlock) /* 145 */ #endif #ifndef Tk_PhotoGetImage -#define Tk_PhotoGetImage(handle, blockPtr) \ - (tkStubsPtr->tk_PhotoGetImage)(handle, blockPtr) /* 146 */ +#define Tk_PhotoGetImage \ + (tkStubsPtr->tk_PhotoGetImage) /* 146 */ #endif #ifndef Tk_PhotoBlank -#define Tk_PhotoBlank(handle) \ - (tkStubsPtr->tk_PhotoBlank)(handle) /* 147 */ +#define Tk_PhotoBlank \ + (tkStubsPtr->tk_PhotoBlank) /* 147 */ #endif #ifndef Tk_PhotoExpand -#define Tk_PhotoExpand(handle, width, height) \ - (tkStubsPtr->tk_PhotoExpand)(handle, width, height) /* 148 */ +#define Tk_PhotoExpand \ + (tkStubsPtr->tk_PhotoExpand) /* 148 */ #endif #ifndef Tk_PhotoGetSize -#define Tk_PhotoGetSize(handle, widthPtr, heightPtr) \ - (tkStubsPtr->tk_PhotoGetSize)(handle, widthPtr, heightPtr) /* 149 */ +#define Tk_PhotoGetSize \ + (tkStubsPtr->tk_PhotoGetSize) /* 149 */ #endif #ifndef Tk_PhotoSetSize -#define Tk_PhotoSetSize(handle, width, height) \ - (tkStubsPtr->tk_PhotoSetSize)(handle, width, height) /* 150 */ +#define Tk_PhotoSetSize \ + (tkStubsPtr->tk_PhotoSetSize) /* 150 */ #endif #ifndef Tk_PointToChar -#define Tk_PointToChar(layout, x, y) \ - (tkStubsPtr->tk_PointToChar)(layout, x, y) /* 151 */ +#define Tk_PointToChar \ + (tkStubsPtr->tk_PointToChar) /* 151 */ #endif #ifndef Tk_PostscriptFontName -#define Tk_PostscriptFontName(tkfont, dsPtr) \ - (tkStubsPtr->tk_PostscriptFontName)(tkfont, dsPtr) /* 152 */ +#define Tk_PostscriptFontName \ + (tkStubsPtr->tk_PostscriptFontName) /* 152 */ #endif #ifndef Tk_PreserveColormap -#define Tk_PreserveColormap(display, colormap) \ - (tkStubsPtr->tk_PreserveColormap)(display, colormap) /* 153 */ +#define Tk_PreserveColormap \ + (tkStubsPtr->tk_PreserveColormap) /* 153 */ #endif #ifndef Tk_QueueWindowEvent -#define Tk_QueueWindowEvent(eventPtr, position) \ - (tkStubsPtr->tk_QueueWindowEvent)(eventPtr, position) /* 154 */ +#define Tk_QueueWindowEvent \ + (tkStubsPtr->tk_QueueWindowEvent) /* 154 */ #endif #ifndef Tk_RedrawImage -#define Tk_RedrawImage(image, imageX, imageY, width, height, drawable, drawableX, drawableY) \ - (tkStubsPtr->tk_RedrawImage)(image, imageX, imageY, width, height, drawable, drawableX, drawableY) /* 155 */ +#define Tk_RedrawImage \ + (tkStubsPtr->tk_RedrawImage) /* 155 */ #endif #ifndef Tk_ResizeWindow -#define Tk_ResizeWindow(tkwin, width, height) \ - (tkStubsPtr->tk_ResizeWindow)(tkwin, width, height) /* 156 */ +#define Tk_ResizeWindow \ + (tkStubsPtr->tk_ResizeWindow) /* 156 */ #endif #ifndef Tk_RestackWindow -#define Tk_RestackWindow(tkwin, aboveBelow, other) \ - (tkStubsPtr->tk_RestackWindow)(tkwin, aboveBelow, other) /* 157 */ +#define Tk_RestackWindow \ + (tkStubsPtr->tk_RestackWindow) /* 157 */ #endif #ifndef Tk_RestrictEvents -#define Tk_RestrictEvents(proc, arg, prevArgPtr) \ - (tkStubsPtr->tk_RestrictEvents)(proc, arg, prevArgPtr) /* 158 */ +#define Tk_RestrictEvents \ + (tkStubsPtr->tk_RestrictEvents) /* 158 */ #endif #ifndef Tk_SafeInit -#define Tk_SafeInit(interp) \ - (tkStubsPtr->tk_SafeInit)(interp) /* 159 */ +#define Tk_SafeInit \ + (tkStubsPtr->tk_SafeInit) /* 159 */ #endif #ifndef Tk_SetAppName -#define Tk_SetAppName(tkwin, name) \ - (tkStubsPtr->tk_SetAppName)(tkwin, name) /* 160 */ +#define Tk_SetAppName \ + (tkStubsPtr->tk_SetAppName) /* 160 */ #endif #ifndef Tk_SetBackgroundFromBorder -#define Tk_SetBackgroundFromBorder(tkwin, border) \ - (tkStubsPtr->tk_SetBackgroundFromBorder)(tkwin, border) /* 161 */ +#define Tk_SetBackgroundFromBorder \ + (tkStubsPtr->tk_SetBackgroundFromBorder) /* 161 */ #endif #ifndef Tk_SetClass -#define Tk_SetClass(tkwin, className) \ - (tkStubsPtr->tk_SetClass)(tkwin, className) /* 162 */ +#define Tk_SetClass \ + (tkStubsPtr->tk_SetClass) /* 162 */ #endif #ifndef Tk_SetGrid -#define Tk_SetGrid(tkwin, reqWidth, reqHeight, gridWidth, gridHeight) \ - (tkStubsPtr->tk_SetGrid)(tkwin, reqWidth, reqHeight, gridWidth, gridHeight) /* 163 */ +#define Tk_SetGrid \ + (tkStubsPtr->tk_SetGrid) /* 163 */ #endif #ifndef Tk_SetInternalBorder -#define Tk_SetInternalBorder(tkwin, width) \ - (tkStubsPtr->tk_SetInternalBorder)(tkwin, width) /* 164 */ +#define Tk_SetInternalBorder \ + (tkStubsPtr->tk_SetInternalBorder) /* 164 */ #endif #ifndef Tk_SetWindowBackground -#define Tk_SetWindowBackground(tkwin, pixel) \ - (tkStubsPtr->tk_SetWindowBackground)(tkwin, pixel) /* 165 */ +#define Tk_SetWindowBackground \ + (tkStubsPtr->tk_SetWindowBackground) /* 165 */ #endif #ifndef Tk_SetWindowBackgroundPixmap -#define Tk_SetWindowBackgroundPixmap(tkwin, pixmap) \ - (tkStubsPtr->tk_SetWindowBackgroundPixmap)(tkwin, pixmap) /* 166 */ +#define Tk_SetWindowBackgroundPixmap \ + (tkStubsPtr->tk_SetWindowBackgroundPixmap) /* 166 */ #endif #ifndef Tk_SetWindowBorder -#define Tk_SetWindowBorder(tkwin, pixel) \ - (tkStubsPtr->tk_SetWindowBorder)(tkwin, pixel) /* 167 */ +#define Tk_SetWindowBorder \ + (tkStubsPtr->tk_SetWindowBorder) /* 167 */ #endif #ifndef Tk_SetWindowBorderWidth -#define Tk_SetWindowBorderWidth(tkwin, width) \ - (tkStubsPtr->tk_SetWindowBorderWidth)(tkwin, width) /* 168 */ +#define Tk_SetWindowBorderWidth \ + (tkStubsPtr->tk_SetWindowBorderWidth) /* 168 */ #endif #ifndef Tk_SetWindowBorderPixmap -#define Tk_SetWindowBorderPixmap(tkwin, pixmap) \ - (tkStubsPtr->tk_SetWindowBorderPixmap)(tkwin, pixmap) /* 169 */ +#define Tk_SetWindowBorderPixmap \ + (tkStubsPtr->tk_SetWindowBorderPixmap) /* 169 */ #endif #ifndef Tk_SetWindowColormap -#define Tk_SetWindowColormap(tkwin, colormap) \ - (tkStubsPtr->tk_SetWindowColormap)(tkwin, colormap) /* 170 */ +#define Tk_SetWindowColormap \ + (tkStubsPtr->tk_SetWindowColormap) /* 170 */ #endif #ifndef Tk_SetWindowVisual -#define Tk_SetWindowVisual(tkwin, visual, depth, colormap) \ - (tkStubsPtr->tk_SetWindowVisual)(tkwin, visual, depth, colormap) /* 171 */ +#define Tk_SetWindowVisual \ + (tkStubsPtr->tk_SetWindowVisual) /* 171 */ #endif #ifndef Tk_SizeOfBitmap -#define Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr) \ - (tkStubsPtr->tk_SizeOfBitmap)(display, bitmap, widthPtr, heightPtr) /* 172 */ +#define Tk_SizeOfBitmap \ + (tkStubsPtr->tk_SizeOfBitmap) /* 172 */ #endif #ifndef Tk_SizeOfImage -#define Tk_SizeOfImage(image, widthPtr, heightPtr) \ - (tkStubsPtr->tk_SizeOfImage)(image, widthPtr, heightPtr) /* 173 */ +#define Tk_SizeOfImage \ + (tkStubsPtr->tk_SizeOfImage) /* 173 */ #endif #ifndef Tk_StrictMotif -#define Tk_StrictMotif(tkwin) \ - (tkStubsPtr->tk_StrictMotif)(tkwin) /* 174 */ +#define Tk_StrictMotif \ + (tkStubsPtr->tk_StrictMotif) /* 174 */ #endif #ifndef Tk_TextLayoutToPostscript -#define Tk_TextLayoutToPostscript(interp, layout) \ - (tkStubsPtr->tk_TextLayoutToPostscript)(interp, layout) /* 175 */ +#define Tk_TextLayoutToPostscript \ + (tkStubsPtr->tk_TextLayoutToPostscript) /* 175 */ #endif #ifndef Tk_TextWidth -#define Tk_TextWidth(font, string, numChars) \ - (tkStubsPtr->tk_TextWidth)(font, string, numChars) /* 176 */ +#define Tk_TextWidth \ + (tkStubsPtr->tk_TextWidth) /* 176 */ #endif #ifndef Tk_UndefineCursor -#define Tk_UndefineCursor(window) \ - (tkStubsPtr->tk_UndefineCursor)(window) /* 177 */ +#define Tk_UndefineCursor \ + (tkStubsPtr->tk_UndefineCursor) /* 177 */ #endif #ifndef Tk_UnderlineChars -#define Tk_UnderlineChars(display, drawable, gc, tkfont, source, x, y, firstChar, lastChar) \ - (tkStubsPtr->tk_UnderlineChars)(display, drawable, gc, tkfont, source, x, y, firstChar, lastChar) /* 178 */ +#define Tk_UnderlineChars \ + (tkStubsPtr->tk_UnderlineChars) /* 178 */ #endif #ifndef Tk_UnderlineTextLayout -#define Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) \ - (tkStubsPtr->tk_UnderlineTextLayout)(display, drawable, gc, layout, x, y, underline) /* 179 */ +#define Tk_UnderlineTextLayout \ + (tkStubsPtr->tk_UnderlineTextLayout) /* 179 */ #endif #ifndef Tk_Ungrab -#define Tk_Ungrab(tkwin) \ - (tkStubsPtr->tk_Ungrab)(tkwin) /* 180 */ +#define Tk_Ungrab \ + (tkStubsPtr->tk_Ungrab) /* 180 */ #endif #ifndef Tk_UnmaintainGeometry -#define Tk_UnmaintainGeometry(slave, master) \ - (tkStubsPtr->tk_UnmaintainGeometry)(slave, master) /* 181 */ +#define Tk_UnmaintainGeometry \ + (tkStubsPtr->tk_UnmaintainGeometry) /* 181 */ #endif #ifndef Tk_UnmapWindow -#define Tk_UnmapWindow(tkwin) \ - (tkStubsPtr->tk_UnmapWindow)(tkwin) /* 182 */ +#define Tk_UnmapWindow \ + (tkStubsPtr->tk_UnmapWindow) /* 182 */ #endif #ifndef Tk_UnsetGrid -#define Tk_UnsetGrid(tkwin) \ - (tkStubsPtr->tk_UnsetGrid)(tkwin) /* 183 */ +#define Tk_UnsetGrid \ + (tkStubsPtr->tk_UnsetGrid) /* 183 */ #endif #ifndef Tk_UpdatePointer -#define Tk_UpdatePointer(tkwin, x, y, state) \ - (tkStubsPtr->tk_UpdatePointer)(tkwin, x, y, state) /* 184 */ +#define Tk_UpdatePointer \ + (tkStubsPtr->tk_UpdatePointer) /* 184 */ +#endif +#ifndef Tk_AllocBitmapFromObj +#define Tk_AllocBitmapFromObj \ + (tkStubsPtr->tk_AllocBitmapFromObj) /* 185 */ +#endif +#ifndef Tk_Alloc3DBorderFromObj +#define Tk_Alloc3DBorderFromObj \ + (tkStubsPtr->tk_Alloc3DBorderFromObj) /* 186 */ +#endif +#ifndef Tk_AllocColorFromObj +#define Tk_AllocColorFromObj \ + (tkStubsPtr->tk_AllocColorFromObj) /* 187 */ +#endif +#ifndef Tk_AllocCursorFromObj +#define Tk_AllocCursorFromObj \ + (tkStubsPtr->tk_AllocCursorFromObj) /* 188 */ +#endif +#ifndef Tk_AllocFontFromObj +#define Tk_AllocFontFromObj \ + (tkStubsPtr->tk_AllocFontFromObj) /* 189 */ +#endif +#ifndef Tk_CreateOptionTable +#define Tk_CreateOptionTable \ + (tkStubsPtr->tk_CreateOptionTable) /* 190 */ +#endif +#ifndef Tk_DeleteOptionTable +#define Tk_DeleteOptionTable \ + (tkStubsPtr->tk_DeleteOptionTable) /* 191 */ +#endif +#ifndef Tk_Free3DBorderFromObj +#define Tk_Free3DBorderFromObj \ + (tkStubsPtr->tk_Free3DBorderFromObj) /* 192 */ +#endif +#ifndef Tk_FreeBitmapFromObj +#define Tk_FreeBitmapFromObj \ + (tkStubsPtr->tk_FreeBitmapFromObj) /* 193 */ +#endif +#ifndef Tk_FreeColorFromObj +#define Tk_FreeColorFromObj \ + (tkStubsPtr->tk_FreeColorFromObj) /* 194 */ +#endif +#ifndef Tk_FreeConfigOptions +#define Tk_FreeConfigOptions \ + (tkStubsPtr->tk_FreeConfigOptions) /* 195 */ +#endif +#ifndef Tk_FreeSavedOptions +#define Tk_FreeSavedOptions \ + (tkStubsPtr->tk_FreeSavedOptions) /* 196 */ +#endif +#ifndef Tk_FreeCursorFromObj +#define Tk_FreeCursorFromObj \ + (tkStubsPtr->tk_FreeCursorFromObj) /* 197 */ +#endif +#ifndef Tk_FreeFontFromObj +#define Tk_FreeFontFromObj \ + (tkStubsPtr->tk_FreeFontFromObj) /* 198 */ +#endif +#ifndef Tk_Get3DBorderFromObj +#define Tk_Get3DBorderFromObj \ + (tkStubsPtr->tk_Get3DBorderFromObj) /* 199 */ +#endif +#ifndef Tk_GetAnchorFromObj +#define Tk_GetAnchorFromObj \ + (tkStubsPtr->tk_GetAnchorFromObj) /* 200 */ +#endif +#ifndef Tk_GetBitmapFromObj +#define Tk_GetBitmapFromObj \ + (tkStubsPtr->tk_GetBitmapFromObj) /* 201 */ +#endif +#ifndef Tk_GetColorFromObj +#define Tk_GetColorFromObj \ + (tkStubsPtr->tk_GetColorFromObj) /* 202 */ +#endif +#ifndef Tk_GetCursorFromObj +#define Tk_GetCursorFromObj \ + (tkStubsPtr->tk_GetCursorFromObj) /* 203 */ +#endif +#ifndef Tk_GetOptionInfo +#define Tk_GetOptionInfo \ + (tkStubsPtr->tk_GetOptionInfo) /* 204 */ +#endif +#ifndef Tk_GetOptionValue +#define Tk_GetOptionValue \ + (tkStubsPtr->tk_GetOptionValue) /* 205 */ +#endif +#ifndef Tk_GetJustifyFromObj +#define Tk_GetJustifyFromObj \ + (tkStubsPtr->tk_GetJustifyFromObj) /* 206 */ +#endif +#ifndef Tk_GetMMFromObj +#define Tk_GetMMFromObj \ + (tkStubsPtr->tk_GetMMFromObj) /* 207 */ +#endif +#ifndef Tk_GetPixelsFromObj +#define Tk_GetPixelsFromObj \ + (tkStubsPtr->tk_GetPixelsFromObj) /* 208 */ +#endif +#ifndef Tk_GetReliefFromObj +#define Tk_GetReliefFromObj \ + (tkStubsPtr->tk_GetReliefFromObj) /* 209 */ +#endif +#ifndef Tk_GetScrollInfoObj +#define Tk_GetScrollInfoObj \ + (tkStubsPtr->tk_GetScrollInfoObj) /* 210 */ +#endif +#ifndef Tk_InitOptions +#define Tk_InitOptions \ + (tkStubsPtr->tk_InitOptions) /* 211 */ +#endif +#ifndef Tk_MainEx +#define Tk_MainEx \ + (tkStubsPtr->tk_MainEx) /* 212 */ +#endif +#ifndef Tk_RestoreSavedOptions +#define Tk_RestoreSavedOptions \ + (tkStubsPtr->tk_RestoreSavedOptions) /* 213 */ +#endif +#ifndef Tk_SetOptions +#define Tk_SetOptions \ + (tkStubsPtr->tk_SetOptions) /* 214 */ #endif #endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 9dc65ee..855d22d 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -6,12 +6,12 @@ * the string to be edited. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkEntry.c,v 1.2 1998/09/14 18:23:09 stanton Exp $ + * RCS: @(#) $Id: tkEntry.c,v 1.3 1999/04/16 01:51:13 stanton Exp $ */ #include "tkInt.h" @@ -32,6 +32,9 @@ typedef struct { * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with entry. */ Tcl_Command widgetCmd; /* Token for entry's widget command. */ + Tk_OptionTable optionTable; /* Table that defines configuration options + * available for this widget. */ + /* * Fields that are set by widget commands other than "configure". @@ -39,17 +42,17 @@ typedef struct { char *string; /* Pointer to storage for string; * NULL-terminated; malloc-ed. */ - int insertPos; /* Index of character before which next - * typed character will be inserted. */ + int insertPos; /* Character index before which next typed + * character will be inserted. */ /* * Information about what's selected, if any. */ - int selectFirst; /* Index of first selected character (-1 means - * nothing selected. */ - int selectLast; /* Index of last selected character (-1 means - * nothing selected. */ + int selectFirst; /* Character index of first selected + * character (-1 means nothing selected. */ + int selectLast; /* Character index just after last selected + * character (-1 means nothing selected. */ int selectAnchor; /* Fixed end of selection (i.e. "select to" * operation will use this as one end of the * selection). */ @@ -60,8 +63,8 @@ typedef struct { int scanMarkX; /* X-position at which scan started (e.g. * button was pressed here). */ - int scanMarkIndex; /* Index of character that was at left of - * window when scan started. */ + int scanMarkIndex; /* Character index of character that was at + * left of window when scan started. */ /* * Configuration settings that are updated by Tk_ConfigureWidget. @@ -99,7 +102,7 @@ typedef struct { char *showChar; /* Value of -show option. If non-NULL, first * character is used for displaying all * characters in entry. Malloc'ed. */ - Tk_Uid state; /* Normal or disabled. Entry is read-only + int state; /* Normal or disabled. Entry is read-only * when disabled. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. * If non-NULL, entry's string tracks the @@ -118,20 +121,27 @@ typedef struct { * configuration settings above. */ - int numChars; /* Number of non-NULL characters in - * string (may be 0). */ - char *displayString; /* If non-NULL, points to string with same + int numBytes; /* Length of string in bytes. */ + int numChars; /* Length of string in characters. Both + * string and displayString have the same + * character length, but may have different + * byte lengths due to being made from + * different UTF-8 characters. */ + char *displayString; /* String to use when displaying. This may + * be a pointer to string, or a pointer to + * malloced memory with the same character * length as string but whose characters - * are all equal to showChar. Malloc'ed. */ + * are all equal to showChar. */ + int numDisplayBytes; /* Length of displayString in bytes. */ int inset; /* Number of pixels on the left and right * sides that are taken up by XPAD, borderWidth * (if any), and highlightWidth (if any). */ Tk_TextLayout textLayout; /* Cached text layout information. */ int layoutX, layoutY; /* Origin for layout. */ - int leftIndex; /* Index of left-most character visible in - * window. */ int leftX; /* X position at which character at leftIndex * is drawn (varies depending on justify). */ + int leftIndex; /* Character index of left-most character + * visible in window. */ Tcl_TimerToken insertBlinkHandler; /* Timer handler used to blink cursor on and * off. */ @@ -167,6 +177,7 @@ typedef struct { #define GOT_FOCUS 8 #define UPDATE_SCROLLBAR 0x10 #define GOT_SELECTION 0x20 +#define ENTRY_DELETED 0x40 /* * The following macro defines how many extra pixels to leave on each @@ -177,93 +188,108 @@ typedef struct { #define YPAD 1 /* + * The following enum is used to define a type for the -state option + * of the Entry widget. These values are used as indices into the + * string table below. + */ + +enum state { + STATE_DISABLED, STATE_NORMAL +}; + +static char *stateStrings[] = { + "disabled", "normal", (char *) NULL +}; + +/* * Information used for argv parsing. */ -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_ENTRY_BG_COLOR, Tk_Offset(Entry, normalBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_ENTRY_BG_MONO, Tk_Offset(Entry, normalBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_ENTRY_BORDER_WIDTH, Tk_Offset(Entry, borderWidth), 0}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_ENTRY_CURSOR, Tk_Offset(Entry, cursor), TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-exportselection", "exportSelection", - "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, - Tk_Offset(Entry, exportSelection), 0}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_FONT, "-font", "font", "Font", - DEF_ENTRY_FONT, Tk_Offset(Entry, tkfont), 0}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_ENTRY_FG, Tk_Offset(Entry, fgColorPtr), 0}, - {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder), + 0, (ClientData) DEF_ENTRY_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), + 0, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", + "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, + Tk_Offset(Entry, exportSelection), 0, 0, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, + 0, 0}, + {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG, - Tk_Offset(Entry, highlightBgColorPtr), 0}, - {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_ENTRY_HIGHLIGHT, Tk_Offset(Entry, highlightColorPtr), 0}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", - DEF_ENTRY_HIGHLIGHT_WIDTH, Tk_Offset(Entry, highlightWidth), 0}, - {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground", - DEF_ENTRY_INSERT_BG, Tk_Offset(Entry, insertBorder), 0}, - {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", - DEF_ENTRY_INSERT_BD_COLOR, Tk_Offset(Entry, insertBorderWidth), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth", - DEF_ENTRY_INSERT_BD_MONO, Tk_Offset(Entry, insertBorderWidth), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime", - DEF_ENTRY_INSERT_OFF_TIME, Tk_Offset(Entry, insertOffTime), 0}, - {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime", - DEF_ENTRY_INSERT_ON_TIME, Tk_Offset(Entry, insertOnTime), 0}, - {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", - DEF_ENTRY_INSERT_WIDTH, Tk_Offset(Entry, insertWidth), 0}, - {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", - DEF_ENTRY_JUSTIFY, Tk_Offset(Entry, justify), 0}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_ENTRY_RELIEF, Tk_Offset(Entry, relief), 0}, - {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", - DEF_ENTRY_SELECT_COLOR, Tk_Offset(Entry, selBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground", - DEF_ENTRY_SELECT_MONO, Tk_Offset(Entry, selBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", - DEF_ENTRY_SELECT_BD_COLOR, Tk_Offset(Entry, selBorderWidth), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth", - DEF_ENTRY_SELECT_BD_MONO, Tk_Offset(Entry, selBorderWidth), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", - DEF_ENTRY_SELECT_FG_COLOR, Tk_Offset(Entry, selFgColorPtr), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", - DEF_ENTRY_SELECT_FG_MONO, Tk_Offset(Entry, selFgColorPtr), - TK_CONFIG_MONO_ONLY}, + -1, Tk_Offset(Entry, highlightBgColorPtr), + 0, 0, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1, + Tk_Offset(Entry, highlightWidth), 0, 0, 0}, + {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", + DEF_ENTRY_INSERT_BG, + -1, Tk_Offset(Entry, insertBorder), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", + "BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1, + Tk_Offset(Entry, insertBorderWidth), 0, + (ClientData) DEF_ENTRY_INSERT_BD_MONO, 0}, + {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", + DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime), + 0, 0, 0}, + {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", + DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", + DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), + 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), + 0, 0, 0}, + {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", + DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), + 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, + {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", + "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, + Tk_Offset(Entry, selBorderWidth), + 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, + {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", + DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr), + 0, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0}, {TK_CONFIG_STRING, "-show", "show", "Show", - DEF_ENTRY_SHOW, Tk_Offset(Entry, showChar), TK_CONFIG_NULL_OK}, - {TK_CONFIG_UID, "-state", "state", "State", - DEF_ENTRY_STATE, Tk_Offset(Entry, state), 0}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_ENTRY_TAKE_FOCUS, Tk_Offset(Entry, takeFocus), TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", - DEF_ENTRY_TEXT_VARIABLE, Tk_Offset(Entry, textVarName), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_INT, "-width", "width", "Width", - DEF_ENTRY_WIDTH, Tk_Offset(Entry, prefWidth), 0}, - {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", - DEF_ENTRY_SCROLL_COMMAND, Tk_Offset(Entry, scrollCmd), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} + DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), + TK_CONFIG_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName), + TK_CONFIG_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-width", "width", "Width", + DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", + DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd), + TK_CONFIG_NULL_OK, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} }; /* @@ -274,12 +300,38 @@ static Tk_ConfigSpec configSpecs[] = { #define LAST_PLUS_ONE_OK 2 /* + * The following tables define the entry widget commands (and sub- + * commands) and map the indexes into the string tables into + * enumerated types used to dispatch the entry widget command. + */ + +static char *commandNames[] = { + "bbox", "cget", "configure", "delete", "get", "icursor", "index", + "insert", "scan", "selection", "xview", (char *) NULL +}; + +enum command { + COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE, + COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT, + COMMAND_SCAN, COMMAND_SELECTION, COMMAND_XVIEW +}; + +static char *selCommandNames[] = { + "adjust", "clear", "from", "present", "range", "to", (char *) NULL +}; + +enum selcommand { + SELECTION_ADJUST, SELECTION_CLEAR, SELECTION_FROM, + SELECTION_PRESENT, SELECTION_RANGE, SELECTION_TO +}; + +/* * Forward declarations for procedures defined later in this file: */ static int ConfigureEntry _ANSI_ARGS_((Tcl_Interp *interp, - Entry *entryPtr, int argc, char **argv, - int flags)); + Entry *entryPtr, int objc, + Tcl_Obj *CONST objv[], int flags)); static void DeleteChars _ANSI_ARGS_((Entry *entryPtr, int index, int count)); static void DestroyEntry _ANSI_ARGS_((char *memPtr)); @@ -309,8 +361,9 @@ static void EntryUpdateScrollbar _ANSI_ARGS_((Entry *entryPtr)); static void EntryValueChanged _ANSI_ARGS_((Entry *entryPtr)); static void EntryVisibleRange _ANSI_ARGS_((Entry *entryPtr, double *firstPtr, double *lastPtr)); -static int EntryWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +static int EntryWidgetObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static void EntryWorldChanged _ANSI_ARGS_(( ClientData instanceData)); static int GetEntryIndex _ANSI_ARGS_((Tcl_Interp *interp, @@ -333,7 +386,7 @@ static TkClassProcs entryClass = { /* *-------------------------------------------------------------- * - * Tk_EntryCmd -- + * Tk_EntryObjCmd -- * * This procedure is invoked to process the "entry" Tcl * command. See the user documentation for details on what @@ -349,25 +402,43 @@ static TkClassProcs entryClass = { */ int -Tk_EntryCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_EntryObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; register Entry *entryPtr; - Tk_Window new; + Tk_OptionTable optionTable; + Tk_Window tkwin; + + optionTable = (Tk_OptionTable) clientData; + if (optionTable == NULL) { + Tcl_CmdInfo info; + char *name; + + /* + * We haven't created the option table for this widget class + * yet. Do it now and save the table as the clientData for + * the command, so we'll have access to it in future + * invocations of the command. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + name = Tcl_GetString(objv[0]); + Tcl_GetCommandInfo(interp, name, &info); + info.objClientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, name, &info); + } - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } - new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); - if (new == NULL) { + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetString(objv[1]), (char *) NULL); + if (tkwin == NULL) { return TCL_ERROR; } @@ -378,12 +449,13 @@ Tk_EntryCmd(clientData, interp, argc, argv) */ entryPtr = (Entry *) ckalloc(sizeof(Entry)); - entryPtr->tkwin = new; - entryPtr->display = Tk_Display(new); + entryPtr->tkwin = tkwin; + entryPtr->display = Tk_Display(tkwin); entryPtr->interp = interp; - entryPtr->widgetCmd = Tcl_CreateCommand(interp, - Tk_PathName(entryPtr->tkwin), EntryWidgetCmd, + entryPtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, (ClientData) entryPtr, EntryCmdDeletedProc); + entryPtr->optionTable = optionTable; entryPtr->string = (char *) ckalloc(1); entryPtr->string[0] = '\0'; entryPtr->insertPos = 0; @@ -413,20 +485,21 @@ Tk_EntryCmd(clientData, interp, argc, argv) entryPtr->selBorderWidth = 0; entryPtr->selFgColorPtr = NULL; entryPtr->showChar = NULL; - entryPtr->state = tkNormalUid; + entryPtr->state = STATE_NORMAL; entryPtr->textVarName = NULL; entryPtr->takeFocus = NULL; entryPtr->prefWidth = 0; entryPtr->scrollCmd = NULL; - + entryPtr->numBytes = 0; entryPtr->numChars = 0; - entryPtr->displayString = NULL; + entryPtr->displayString = entryPtr->string; + entryPtr->numDisplayBytes = 0; entryPtr->inset = XPAD; entryPtr->textLayout = NULL; entryPtr->layoutX = 0; entryPtr->layoutY = 0; - entryPtr->leftIndex = 0; entryPtr->leftX = 0; + entryPtr->leftIndex = 0; entryPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; entryPtr->textGC = None; entryPtr->selTextGC = None; @@ -441,11 +514,17 @@ Tk_EntryCmd(clientData, interp, argc, argv) EntryEventProc, (ClientData) entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, EntryFetchSelection, (ClientData) entryPtr, XA_STRING); - if (ConfigureEntry(interp, entryPtr, argc-2, argv+2, 0) != TCL_OK) { + + if (Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin) + != TCL_OK) { + Tk_DestroyWindow(entryPtr->tkwin); + return TCL_ERROR; + } + if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) { goto error; } - - interp->result = Tk_PathName(entryPtr->tkwin); + + Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC); return TCL_OK; error: @@ -456,7 +535,7 @@ Tk_EntryCmd(clientData, interp, argc, argv) /* *-------------------------------------------------------------- * - * EntryWidgetCmd -- + * EntryWidgetObjCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. @@ -472,321 +551,405 @@ Tk_EntryCmd(clientData, interp, argc, argv) */ static int -EntryWidgetCmd(clientData, interp, argc, argv) - ClientData clientData; /* Information about entry widget. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +EntryWidgetObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Information about entry widget. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { - register Entry *entryPtr = (Entry *) clientData; - int result = TCL_OK; - size_t length; - int c; + Entry *entryPtr = (Entry *) clientData; + int cmdIndex, selIndex, result; + Tcl_Obj *objPtr; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } Tcl_Preserve((ClientData) entryPtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'b') && (strncmp(argv[1], "bbox", length) == 0)) { - int index; - int x, y, width, height; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " bbox index\"", - (char *) NULL); - goto error; - } - if (GetEntryIndex(interp, entryPtr, argv[2], &index) != TCL_OK) { - goto error; - } - if ((index == entryPtr->numChars) && (index > 0)) { - index--; - } - Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height); - sprintf(interp->result, "%d %d %d %d", - x + entryPtr->layoutX, y + entryPtr->layoutY, width, height); - } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - goto error; - } - result = Tk_ConfigureValue(interp, entryPtr->tkwin, configSpecs, - (char *) entryPtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, entryPtr->tkwin, configSpecs, - (char *) entryPtr, (char *) NULL, 0); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, entryPtr->tkwin, configSpecs, - (char *) entryPtr, argv[2], 0); - } else { - result = ConfigureEntry(interp, entryPtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); - } - } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) { - int first, last; - - if ((argc < 3) || (argc > 4)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " delete firstIndex ?lastIndex?\"", - (char *) NULL); - goto error; - } - if (GetEntryIndex(interp, entryPtr, argv[2], &first) != TCL_OK) { - goto error; - } - if (argc == 3) { - last = first+1; - } else { - if (GetEntryIndex(interp, entryPtr, argv[3], &last) != TCL_OK) { + + /* + * Parse the widget command by looking up the second token in + * the list of valid command names. + */ + + result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, + "option", 0, &cmdIndex); + if (result != TCL_OK) { + return result; + } + + switch (cmdIndex) { + case COMMAND_BBOX: { + int index, x, y, width, height; + char *string; + char buf[TCL_INTEGER_SPACE * 4]; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "bbox index"); goto error; } - } - if ((last >= first) && (entryPtr->state == tkNormalUid)) { - DeleteChars(entryPtr, first, last-first); - } - } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " get\"", (char *) NULL); - goto error; - } - interp->result = entryPtr->string; - } else if ((c == 'i') && (strncmp(argv[1], "icursor", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " icursor pos\"", - (char *) NULL); - goto error; - } - if (GetEntryIndex(interp, entryPtr, argv[2], &entryPtr->insertPos) - != TCL_OK) { - goto error; - } - EventuallyRedraw(entryPtr); - } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) - && (length >= 3)) { - int index; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " index string\"", (char *) NULL); - goto error; - } - if (GetEntryIndex(interp, entryPtr, argv[2], &index) != TCL_OK) { - goto error; - } - sprintf(interp->result, "%d", index); - } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) - && (length >= 3)) { - int index; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " insert index text\"", - (char *) NULL); - goto error; - } - if (GetEntryIndex(interp, entryPtr, argv[2], &index) != TCL_OK) { - goto error; - } - if (entryPtr->state == tkNormalUid) { - InsertChars(entryPtr, index, argv[3]); - } - } else if ((c == 's') && (length >= 2) - && (strncmp(argv[1], "scan", length) == 0)) { - int x; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " scan mark|dragto x\"", (char *) NULL); - goto error; - } - if (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) { - goto error; - } - if ((argv[2][0] == 'm') - && (strncmp(argv[2], "mark", strlen(argv[2])) == 0)) { - entryPtr->scanMarkX = x; - entryPtr->scanMarkIndex = entryPtr->leftIndex; - } else if ((argv[2][0] == 'd') - && (strncmp(argv[2], "dragto", strlen(argv[2])) == 0)) { - EntryScanTo(entryPtr, x); - } else { - Tcl_AppendResult(interp, "bad scan option \"", argv[2], - "\": must be mark or dragto", (char *) NULL); - goto error; - } - } else if ((c == 's') && (length >= 2) - && (strncmp(argv[1], "selection", length) == 0)) { - int index, index2; - - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " select option ?index?\"", (char *) NULL); - goto error; - } - length = strlen(argv[2]); - c = argv[2][0]; - if ((c == 'c') && (strncmp(argv[2], "clear", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection clear\"", (char *) NULL); - goto error; + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; } - if (entryPtr->selectFirst != -1) { - entryPtr->selectFirst = entryPtr->selectLast = -1; - EventuallyRedraw(entryPtr); + if ((index == entryPtr->numChars) && (index > 0)) { + index--; } - goto done; - } else if ((c == 'p') && (strncmp(argv[2], "present", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection present\"", (char *) NULL); + string = entryPtr->displayString; + Tk_CharBbox(entryPtr->textLayout, index, &x, &y, + &width, &height); + sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, + y + entryPtr->layoutY, width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } + + case COMMAND_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } - if (entryPtr->selectFirst == -1) { - interp->result = "0"; + + objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, + entryPtr->optionTable, objv[2], entryPtr->tkwin); + if (objPtr == NULL) { + goto error; } else { - interp->result = "1"; + Tcl_SetObjResult(interp, objPtr); } - goto done; + break; } - if (argc >= 4) { - if (GetEntryIndex(interp, entryPtr, argv[3], &index) != TCL_OK) { - goto error; + + case COMMAND_CONFIGURE: { + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, + entryPtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + entryPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + } else { + result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); } + break; } - if ((c == 'a') && (strncmp(argv[2], "adjust", length) == 0)) { - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection adjust index\"", - (char *) NULL); + + case COMMAND_DELETE: { + int first, last; + + if ((objc < 3) || (objc > 4)) { + Tcl_WrongNumArgs(interp, 1, objv, + "delete firstIndex ?lastIndex?"); goto error; } - if (entryPtr->selectFirst >= 0) { - int half1, half2; - - half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2; - half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2; - if (index < half1) { - entryPtr->selectAnchor = entryPtr->selectLast; - } else if (index > half2) { - entryPtr->selectAnchor = entryPtr->selectFirst; - } else { - /* - * We're at about the halfway point in the selection; - * just keep the existing anchor. - */ + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &first) != TCL_OK) { + goto error; + } + if (objc == 3) { + last = first + 1; + } else { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), + &last) != TCL_OK) { + goto error; } } - EntrySelectTo(entryPtr, index); - } else if ((c == 'f') && (strncmp(argv[2], "from", length) == 0)) { - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection from index\"", - (char *) NULL); + if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { + DeleteChars(entryPtr, first, last - first); + } + break; + } + + case COMMAND_GET: { + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "get"); goto error; } - entryPtr->selectAnchor = index; - } else if ((c == 'r') && (strncmp(argv[2], "range", length) == 0)) { - if (argc != 5) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection range start end\"", - (char *) NULL); + Tcl_SetResult(interp, entryPtr->string, TCL_STATIC); + break; + } + + case COMMAND_ICURSOR: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "icursor pos"); goto error; } - if (GetEntryIndex(interp, entryPtr, argv[4], &index2) != TCL_OK) { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &entryPtr->insertPos) != TCL_OK) { + goto error; + } + EventuallyRedraw(entryPtr); + break; + } + + case COMMAND_INDEX: { + int index; + char buf[TCL_INTEGER_SPACE]; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "index string"); goto error; } - if (index >= index2) { - entryPtr->selectFirst = entryPtr->selectLast = -1; - } else { - entryPtr->selectFirst = index; - entryPtr->selectLast = index2; + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; } - if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { - Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, - EntryLostSelection, (ClientData) entryPtr); - entryPtr->flags |= GOT_SELECTION; + sprintf(buf, "%d", index); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } + + case COMMAND_INSERT: { + int index; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "insert index text"); + goto error; } - EventuallyRedraw(entryPtr); - } else if ((c == 't') && (strncmp(argv[2], "to", length) == 0)) { - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " selection to index\"", - (char *) NULL); + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + if (entryPtr->state == STATE_NORMAL) { + InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + } + break; + } + + case COMMAND_SCAN: { + int x; + char *minorCmd; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "scan mark|dragto x"); goto error; } - EntrySelectTo(entryPtr, index); - } else { - Tcl_AppendResult(interp, "bad selection option \"", argv[2], - "\": must be adjust, clear, from, present, range, or to", - (char *) NULL); - goto error; + if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { + goto error; + } + + minorCmd = Tcl_GetString(objv[2]); + if (minorCmd[0] == 'm' + && (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) { + entryPtr->scanMarkX = x; + entryPtr->scanMarkIndex = entryPtr->leftIndex; + } else if ((minorCmd[0] == 'd') + && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { + EntryScanTo(entryPtr, x); + } else { + Tcl_AppendResult(interp, "bad scan option \"", + Tcl_GetString(objv[2]), "\": must be mark or dragto", + (char *) NULL); + goto error; + } + break; } - } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { - int index, type, count, charsPerPage; - double fraction, first, last; - - if (argc == 2) { - EntryVisibleRange(entryPtr, &first, &last); - sprintf(interp->result, "%g %g", first, last); - goto done; - } else if (argc == 3) { - if (GetEntryIndex(interp, entryPtr, argv[2], &index) != TCL_OK) { + + case COMMAND_SELECTION: { + int index, index2; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "select option ?index?"); goto error; } - } else { - type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); - index = entryPtr->leftIndex; - switch (type) { - case TK_SCROLL_ERROR: - goto error; - case TK_SCROLL_MOVETO: - index = (int) ((fraction * entryPtr->numChars) + 0.5); + + /* + * Parse the selection sub-command, using the command + * table "selCommandNames" defined above. + */ + + result = Tcl_GetIndexFromObj(interp, objv[2], selCommandNames, + "selection option", 0, &selIndex); + if (result != TCL_OK) { + goto error; + } + + switch(selIndex) { + case SELECTION_ADJUST: { + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "selection adjust index"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; + } + if (entryPtr->selectFirst >= 0) { + int half1, half2; + + half1 = (entryPtr->selectFirst + + entryPtr->selectLast)/2; + half2 = (entryPtr->selectFirst + + entryPtr->selectLast + 1)/2; + if (index < half1) { + entryPtr->selectAnchor = entryPtr->selectLast; + } else if (index > half2) { + entryPtr->selectAnchor = entryPtr->selectFirst; + } else { + /* + * We're at about the halfway point in the + * selection; just keep the existing anchor. + */ + } + } + EntrySelectTo(entryPtr, index); break; - case TK_SCROLL_PAGES: - charsPerPage = ((Tk_Width(entryPtr->tkwin) - - 2*entryPtr->inset) / entryPtr->avgWidth) - 2; - if (charsPerPage < 1) { - charsPerPage = 1; + } + + case SELECTION_CLEAR: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "selection clear"); + goto error; + } + if (entryPtr->selectFirst >= 0) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; + EventuallyRedraw(entryPtr); + } + goto done; + } + + case SELECTION_FROM: { + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "selection from index"); + goto error; } - index += charsPerPage*count; + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; + } + entryPtr->selectAnchor = index; break; - case TK_SCROLL_UNITS: - index += count; + } + + case SELECTION_PRESENT: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "selection present"); + goto error; + } + if (entryPtr->selectFirst < 0) { + Tcl_SetResult(interp, "0", TCL_STATIC); + } else { + Tcl_SetResult(interp, "1", TCL_STATIC); + } + goto done; + } + + case SELECTION_RANGE: { + if (objc != 5) { + Tcl_WrongNumArgs(interp, 1, objv, + "selection range start end"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; + } + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[4]),& index2) != TCL_OK) { + goto error; + } + if (index >= index2) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; + } else { + entryPtr->selectFirst = index; + entryPtr->selectLast = index2; + } + if (!(entryPtr->flags & GOT_SELECTION) + && (entryPtr->exportSelection)) { + Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, + EntryLostSelection, (ClientData) entryPtr); + entryPtr->flags |= GOT_SELECTION; + } + EventuallyRedraw(entryPtr); + break; + } + + case SELECTION_TO: { + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "selection to index"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; + } + EntrySelectTo(entryPtr, index); break; + } } + break; + } + + case COMMAND_XVIEW: { + int index; + + if (objc == 2) { + double first, last; + char buf[TCL_DOUBLE_SPACE * 2]; + + EntryVisibleRange(entryPtr, &first, &last); + sprintf(buf, "%g %g", first, last); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + goto done; + } else if (objc == 3) { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + } else { + double fraction; + int count; + + index = entryPtr->leftIndex; + switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, + &count)) { + case TK_SCROLL_ERROR: { + goto error; + } + case TK_SCROLL_MOVETO: { + index = (int) ((fraction * entryPtr->numChars) + 0.5); + break; + } + case TK_SCROLL_PAGES: { + int charsPerPage; + + charsPerPage = ((Tk_Width(entryPtr->tkwin) + - 2 * entryPtr->inset) + / entryPtr->avgWidth) - 2; + if (charsPerPage < 1) { + charsPerPage = 1; + } + index += count * charsPerPage; + break; + } + case TK_SCROLL_UNITS: { + index += count; + break; + } + } + } + if (index >= entryPtr->numChars) { + index = entryPtr->numChars - 1; + } + if (index < 0) { + index = 0; + } + entryPtr->leftIndex = index; + entryPtr->flags |= UPDATE_SCROLLBAR; + EntryComputeGeometry(entryPtr); + EventuallyRedraw(entryPtr); + break; } - if (index >= entryPtr->numChars) { - index = entryPtr->numChars-1; - } - if (index < 0) { - index = 0; - } - entryPtr->leftIndex = index; - entryPtr->flags |= UPDATE_SCROLLBAR; - EntryComputeGeometry(entryPtr); - EventuallyRedraw(entryPtr); - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be bbox, cget, configure, delete, get, ", - "icursor, index, insert, scan, selection, or xview", - (char *) NULL); - goto error; } + done: Tcl_Release((ClientData) entryPtr); return result; @@ -818,7 +981,13 @@ static void DestroyEntry(memPtr) char *memPtr; /* Info about entry widget. */ { - register Entry *entryPtr = (Entry *) memPtr; + Entry *entryPtr = (Entry *) memPtr; + entryPtr->flags |= ENTRY_DELETED; + + Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd); + if (entryPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(DisplayEntry, (ClientData) entryPtr); + } /* * Free up all the stuff that requires special handling, then @@ -839,11 +1008,13 @@ DestroyEntry(memPtr) Tk_FreeGC(entryPtr->display, entryPtr->selTextGC); } Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler); - if (entryPtr->displayString != NULL) { + if (entryPtr->displayString != entryPtr->string) { ckfree(entryPtr->displayString); } Tk_FreeTextLayout(entryPtr->textLayout); - Tk_FreeOptions(configSpecs, (char *) entryPtr, entryPtr->display, 0); + Tk_FreeConfigOptions((char *) entryPtr, entryPtr->optionTable, + entryPtr->tkwin); + entryPtr->tkwin = NULL; ckfree((char *) entryPtr); } @@ -858,7 +1029,7 @@ DestroyEntry(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, @@ -869,14 +1040,17 @@ DestroyEntry(memPtr) */ static int -ConfigureEntry(interp, entryPtr, argc, argv, flags) +ConfigureEntry(interp, entryPtr, objc, objv, flags) Tcl_Interp *interp; /* Used for error reporting. */ - register Entry *entryPtr; /* Information about widget; may or may - * not already have values for some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ + Entry *entryPtr; /* Information about widget; may or may not + * already have values for some fields. */ + int objc; /* Number of valid entries in argv. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */ { + Tk_SavedOptions savedOptions; + Tcl_Obj *errorResult = NULL; + int error; int oldExport; /* @@ -890,9 +1064,79 @@ ConfigureEntry(interp, entryPtr, argc, argv, flags) } oldExport = entryPtr->exportSelection; - if (Tk_ConfigureWidget(interp, entryPtr->tkwin, configSpecs, - argc, argv, (char *) entryPtr, flags) != TCL_OK) { - return TCL_ERROR; + + for (error = 0; error <= 1; error++) { + if (!error) { + /* + * First pass: set options to new values. + */ + + if (Tk_SetOptions(interp, (char *) entryPtr, + entryPtr->optionTable, objc, objv, + entryPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) { + continue; + } + } else { + /* + * Second pass: restore options to old values. + */ + + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); + } + + /* + * A few other options also need special processing, such as parsing + * the geometry and setting the background from a 3-D border. + */ + + Tk_SetBackgroundFromBorder(entryPtr->tkwin, entryPtr->normalBorder); + + if (entryPtr->insertWidth <= 0) { + entryPtr->insertWidth = 2; + } + if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) { + entryPtr->insertBorderWidth = entryPtr->insertWidth/2; + } + + /* + * Restart the cursor timing sequence in case the on-time or + * off-time just changed. + */ + + if (entryPtr->flags & GOT_FOCUS) { + EntryFocusProc(entryPtr, 1); + } + + /* + * Claim the selection if we've suddenly started exporting it. + */ + + if (entryPtr->exportSelection && (!oldExport) + && (entryPtr->selectFirst != -1) + && !(entryPtr->flags & GOT_SELECTION)) { + Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, + (ClientData) entryPtr); + entryPtr->flags |= GOT_SELECTION; + } + + /* + * Recompute the window's geometry and arrange for it to be + * redisplayed. + */ + + Tk_SetInternalBorder(entryPtr->tkwin, + entryPtr->borderWidth + entryPtr->highlightWidth); + if (entryPtr->highlightWidth <= 0) { + entryPtr->highlightWidth = 0; + } + entryPtr->inset = entryPtr->highlightWidth + + entryPtr->borderWidth + XPAD; + break; + } + if (!error) { + Tk_FreeSavedOptions(&savedOptions); } /* @@ -915,63 +1159,14 @@ ConfigureEntry(interp, entryPtr, argc, argv, flags) EntryTextVarProc, (ClientData) entryPtr); } - /* - * A few other options also need special processing, such as parsing - * the geometry and setting the background from a 3-D border. - */ - - if ((entryPtr->state != tkNormalUid) - && (entryPtr->state != tkDisabledUid)) { - Tcl_AppendResult(interp, "bad state value \"", entryPtr->state, - "\": must be normal or disabled", (char *) NULL); - entryPtr->state = tkNormalUid; + EntryWorldChanged((ClientData) entryPtr); + if (error) { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); return TCL_ERROR; + } else { + return TCL_OK; } - - Tk_SetBackgroundFromBorder(entryPtr->tkwin, entryPtr->normalBorder); - - if (entryPtr->insertWidth <= 0) { - entryPtr->insertWidth = 2; - } - if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) { - entryPtr->insertBorderWidth = entryPtr->insertWidth/2; - } - - /* - * Restart the cursor timing sequence in case the on-time or off-time - * just changed. - */ - - if (entryPtr->flags & GOT_FOCUS) { - EntryFocusProc(entryPtr, 1); - } - - /* - * Claim the selection if we've suddenly started exporting it. - */ - - if (entryPtr->exportSelection && (!oldExport) - && (entryPtr->selectFirst != -1) - && !(entryPtr->flags & GOT_SELECTION)) { - Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, - (ClientData) entryPtr); - entryPtr->flags |= GOT_SELECTION; - } - - /* - * Recompute the window's geometry and arrange for it to be - * redisplayed. - */ - - Tk_SetInternalBorder(entryPtr->tkwin, - entryPtr->borderWidth + entryPtr->highlightWidth); - if (entryPtr->highlightWidth <= 0) { - entryPtr->highlightWidth = 0; - } - entryPtr->inset = entryPtr->highlightWidth + entryPtr->borderWidth + XPAD; - - EntryWorldChanged((ClientData) entryPtr); - return TCL_OK; } /* @@ -1057,13 +1252,14 @@ static void DisplayEntry(clientData) ClientData clientData; /* Information about window. */ { - register Entry *entryPtr = (Entry *) clientData; - register Tk_Window tkwin = entryPtr->tkwin; - int baseY, selStartX, selEndX, cursorX, x, w; + Entry *entryPtr = (Entry *) clientData; + Tk_Window tkwin = entryPtr->tkwin; + int baseY, selStartX, selEndX, cursorX; int xBound; Tk_FontMetrics fm; Pixmap pixmap; int showSelection; + char *string; entryPtr->flags &= ~REDRAW_PENDING; if ((entryPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { @@ -1118,18 +1314,21 @@ DisplayEntry(clientData) Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->normalBorder, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); - if (showSelection && (entryPtr->selectLast > entryPtr->leftIndex)) { + + string = entryPtr->displayString; + if (showSelection + && (entryPtr->selectLast > entryPtr->leftIndex)) { if (entryPtr->selectFirst <= entryPtr->leftIndex) { selStartX = entryPtr->leftX; } else { Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst, - &x, NULL, NULL, NULL); - selStartX = x + entryPtr->layoutX; + &selStartX, NULL, NULL, NULL); + selStartX += entryPtr->layoutX; } if ((selStartX - entryPtr->selBorderWidth) < xBound) { - Tk_CharBbox(entryPtr->textLayout, entryPtr->selectLast - 1, - &x, NULL, &w, NULL); - selEndX = x + w + entryPtr->layoutX; + Tk_CharBbox(entryPtr->textLayout, entryPtr->selectLast, + &selEndX, NULL, NULL, NULL); + selEndX += entryPtr->layoutX; Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->selBorder, selStartX - entryPtr->selBorderWidth, baseY - fm.ascent - entryPtr->selBorderWidth, @@ -1149,32 +1348,22 @@ DisplayEntry(clientData) */ if ((entryPtr->insertPos >= entryPtr->leftIndex) - && (entryPtr->state == tkNormalUid) + && (entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) { - if (entryPtr->insertPos == 0) { - cursorX = 0; - } else if (entryPtr->insertPos >= entryPtr->numChars) { - Tk_CharBbox(entryPtr->textLayout, entryPtr->numChars - 1, - &x, NULL, &w, NULL); - cursorX = x + w; - } else { - Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, - &x, NULL, NULL, NULL); - cursorX = x; - } + Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL, + NULL, NULL); cursorX += entryPtr->layoutX; cursorX -= (entryPtr->insertWidth)/2; if (cursorX < xBound) { if (entryPtr->flags & CURSOR_ON) { Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder, - cursorX, baseY - fm.ascent, - entryPtr->insertWidth, fm.ascent + fm.descent, - entryPtr->insertBorderWidth, TK_RELIEF_RAISED); + cursorX, baseY - fm.ascent, entryPtr->insertWidth, + fm.ascent + fm.descent, entryPtr->insertBorderWidth, + TK_RELIEF_RAISED); } else if (entryPtr->insertBorder == entryPtr->selBorder) { Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->normalBorder, - cursorX, baseY - fm.ascent, - entryPtr->insertWidth, fm.ascent + fm.descent, - 0, TK_RELIEF_FLAT); + cursorX, baseY - fm.ascent, entryPtr->insertWidth, + fm.ascent + fm.descent, 0, TK_RELIEF_FLAT); } } } @@ -1188,18 +1377,19 @@ DisplayEntry(clientData) entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY, entryPtr->leftIndex, entryPtr->numChars); - if (showSelection && (entryPtr->selTextGC != entryPtr->textGC) && - (entryPtr->selectFirst < entryPtr->selectLast)) { - int first; + if (showSelection + && (entryPtr->selTextGC != entryPtr->textGC) + && (entryPtr->selectFirst < entryPtr->selectLast)) { + int selFirst; - if (entryPtr->selectFirst - entryPtr->leftIndex < 0) { - first = entryPtr->leftIndex; + if (entryPtr->selectFirst < entryPtr->leftIndex) { + selFirst = entryPtr->leftIndex; } else { - first = entryPtr->selectFirst; + selFirst = entryPtr->selectFirst; } Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC, entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY, - first, entryPtr->selectLast); + selFirst, entryPtr->selectLast); } /* @@ -1210,8 +1400,8 @@ DisplayEntry(clientData) if (entryPtr->relief != TK_RELIEF_FLAT) { Tk_Draw3DRectangle(tkwin, pixmap, entryPtr->normalBorder, entryPtr->highlightWidth, entryPtr->highlightWidth, - Tk_Width(tkwin) - 2*entryPtr->highlightWidth, - Tk_Height(tkwin) - 2*entryPtr->highlightWidth, + Tk_Width(tkwin) - 2 * entryPtr->highlightWidth, + Tk_Height(tkwin) - 2 * entryPtr->highlightWidth, entryPtr->borderWidth, entryPtr->relief); } if (entryPtr->highlightWidth != 0) { @@ -1259,38 +1449,53 @@ DisplayEntry(clientData) static void EntryComputeGeometry(entryPtr) - Entry *entryPtr; /* Widget record for entry. */ + Entry *entryPtr; /* Widget record for entry. */ { int totalLength, overflow, maxOffScreen, rightX; int height, width, i; Tk_FontMetrics fm; - char *p, *displayString; + char *p; + + if (entryPtr->displayString != entryPtr->string) { + ckfree(entryPtr->displayString); + entryPtr->displayString = entryPtr->string; + entryPtr->numDisplayBytes = entryPtr->numBytes; + } /* * If we're displaying a special character instead of the value of * the entry, recompute the displayString. */ - if (entryPtr->displayString != NULL) { - ckfree(entryPtr->displayString); - entryPtr->displayString = NULL; - } if (entryPtr->showChar != NULL) { - entryPtr->displayString = (char *) ckalloc((unsigned) - (entryPtr->numChars + 1)); - for (p = entryPtr->displayString, i = entryPtr->numChars; i > 0; - i--, p++) { - *p = entryPtr->showChar[0]; + Tcl_UniChar ch; + char buf[TCL_UTF_MAX]; + int size; + + /* + * Normalize the special character so we can safely duplicate it + * in the display string. If we didn't do this, then two malformed + * characters might end up looking like one valid UTF character in + * the resulting string. + */ + + Tcl_UtfToUniChar(entryPtr->showChar, &ch); + size = Tcl_UniCharToUtf(ch, buf); + + entryPtr->numDisplayBytes = entryPtr->numChars * size; + entryPtr->displayString = + (char *) ckalloc((unsigned) (entryPtr->numDisplayBytes + 1)); + + p = entryPtr->displayString; + for (i = entryPtr->numChars; --i >= 0; ) { + p += Tcl_UniCharToUtf(ch, p); } - *p = 0; - displayString = entryPtr->displayString; - } else { - displayString = entryPtr->string; + *p = '\0'; } Tk_FreeTextLayout(entryPtr->textLayout); entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont, - displayString, entryPtr->numChars, 0, entryPtr->justify, - TK_IGNORE_NEWLINES, &totalLength, &height); + entryPtr->displayString, entryPtr->numChars, 0, + entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height); entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2; @@ -1325,13 +1530,13 @@ EntryComputeGeometry(entryPtr) Tk_CharBbox(entryPtr->textLayout, maxOffScreen, &rightX, NULL, NULL, NULL); if (rightX < overflow) { - maxOffScreen += 1; + maxOffScreen++; } if (entryPtr->leftIndex > maxOffScreen) { entryPtr->leftIndex = maxOffScreen; } - Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, - &rightX, NULL, NULL, NULL); + Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX, + NULL, NULL, NULL); entryPtr->leftX = entryPtr->inset; entryPtr->layoutX = entryPtr->leftX - rightX; } @@ -1368,28 +1573,51 @@ EntryComputeGeometry(entryPtr) */ static void -InsertChars(entryPtr, index, string) - register Entry *entryPtr; /* Entry that is to get the new - * elements. */ +InsertChars(entryPtr, index, value) + Entry *entryPtr; /* Entry that is to get the new elements. */ int index; /* Add the new elements before this - * element. */ - char *string; /* New characters to add (NULL-terminated + * character index. */ + char *value; /* New characters to add (NULL-terminated * string). */ { - int length; - char *new; + int byteIndex, byteCount, oldChars, charsAdded, newByteCount; + char *new, *string; - length = strlen(string); - if (length == 0) { + string = entryPtr->string; + byteIndex = Tcl_UtfAtIndex(string, index) - string; + byteCount = strlen(value); + if (byteCount == 0) { return; } - new = (char *) ckalloc((unsigned) (entryPtr->numChars + length + 1)); - strncpy(new, entryPtr->string, (size_t) index); - strcpy(new+index, string); - strcpy(new+index+length, entryPtr->string+index); - ckfree(entryPtr->string); + + newByteCount = entryPtr->numBytes + byteCount + 1; + new = (char *) ckalloc((unsigned) newByteCount); + memcpy(new, string, (size_t) byteIndex); + strcpy(new + byteIndex, value); + strcpy(new + byteIndex + byteCount, string + byteIndex); + + ckfree(string); entryPtr->string = new; - entryPtr->numChars += length; + + /* + * The following construction is used because inserting improperly + * formed UTF-8 sequences between other improperly formed UTF-8 + * sequences could result in actually forming valid UTF-8 sequences; + * the number of characters added may not be Tcl_NumUtfChars(string, -1), + * because of context. The actual number of characters added is how + * many characters are in the string now minus the number that + * used to be there. + */ + + oldChars = entryPtr->numChars; + entryPtr->numChars = Tcl_NumUtfChars(new, -1); + charsAdded = entryPtr->numChars - oldChars; + entryPtr->numBytes += byteCount; + + if (entryPtr->displayString == string) { + entryPtr->displayString = new; + entryPtr->numDisplayBytes = entryPtr->numBytes; + } /* * Inserting characters invalidates all indexes into the string. @@ -1400,19 +1628,20 @@ InsertChars(entryPtr, index, string) */ if (entryPtr->selectFirst >= index) { - entryPtr->selectFirst += length; + entryPtr->selectFirst += charsAdded; } if (entryPtr->selectLast > index) { - entryPtr->selectLast += length; + entryPtr->selectLast += charsAdded; } - if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) { - entryPtr->selectAnchor += length; + if ((entryPtr->selectAnchor > index) + || (entryPtr->selectFirst >= index)) { + entryPtr->selectAnchor += charsAdded; } if (entryPtr->leftIndex > index) { - entryPtr->leftIndex += length; + entryPtr->leftIndex += charsAdded; } if (entryPtr->insertPos >= index) { - entryPtr->insertPos += length; + entryPtr->insertPos += charsAdded; } EntryValueChanged(entryPtr); } @@ -1436,11 +1665,12 @@ InsertChars(entryPtr, index, string) static void DeleteChars(entryPtr, index, count) - register Entry *entryPtr; /* Entry widget to modify. */ + Entry *entryPtr; /* Entry widget to modify. */ int index; /* Index of first character to delete. */ int count; /* How many characters to delete. */ { - char *new; + int byteIndex, byteCount, newByteCount; + char *new, *string; if ((index + count) > entryPtr->numChars) { count = entryPtr->numChars - index; @@ -1449,12 +1679,24 @@ DeleteChars(entryPtr, index, count) return; } - new = (char *) ckalloc((unsigned) (entryPtr->numChars + 1 - count)); - strncpy(new, entryPtr->string, (size_t) index); - strcpy(new+index, entryPtr->string+index+count); + string = entryPtr->string; + byteIndex = Tcl_UtfAtIndex(string, index) - string; + byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex); + + newByteCount = entryPtr->numBytes + 1 - byteCount; + new = (char *) ckalloc((unsigned) newByteCount); + memcpy(new, string, (size_t) byteIndex); + strcpy(new + byteIndex, string + byteIndex + byteCount); + ckfree(entryPtr->string); entryPtr->string = new; entryPtr->numChars -= count; + entryPtr->numBytes -= byteCount; + + if (entryPtr->displayString == string) { + entryPtr->displayString = new; + entryPtr->numDisplayBytes = entryPtr->numBytes; + } /* * Deleting characters results in the remaining characters being @@ -1463,21 +1705,22 @@ DeleteChars(entryPtr, index, count) */ if (entryPtr->selectFirst >= index) { - if (entryPtr->selectFirst >= (index+count)) { + if (entryPtr->selectFirst >= (index + count)) { entryPtr->selectFirst -= count; } else { entryPtr->selectFirst = index; } } if (entryPtr->selectLast >= index) { - if (entryPtr->selectLast >= (index+count)) { + if (entryPtr->selectLast >= (index + count)) { entryPtr->selectLast -= count; } else { entryPtr->selectLast = index; } } if (entryPtr->selectLast <= entryPtr->selectFirst) { - entryPtr->selectFirst = entryPtr->selectLast = -1; + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; } if (entryPtr->selectAnchor >= index) { if (entryPtr->selectAnchor >= (index+count)) { @@ -1487,14 +1730,14 @@ DeleteChars(entryPtr, index, count) } } if (entryPtr->leftIndex > index) { - if (entryPtr->leftIndex >= (index+count)) { + if (entryPtr->leftIndex >= (index + count)) { entryPtr->leftIndex -= count; } else { entryPtr->leftIndex = index; } } if (entryPtr->insertPos >= index) { - if (entryPtr->insertPos >= (index+count)) { + if (entryPtr->insertPos >= (index + count)) { entryPtr->insertPos -= count; } else { entryPtr->insertPos = index; @@ -1580,24 +1823,37 @@ EntryValueChanged(entryPtr) static void EntrySetValue(entryPtr, value) - register Entry *entryPtr; /* Entry whose value is to be - * changed. */ - char *value; /* New text to display in entry. */ + Entry *entryPtr; /* Entry whose value is to be changed. */ + char *value; /* New text to display in entry. */ { + char *oldSource; + + oldSource = entryPtr->string; + ckfree(entryPtr->string); - entryPtr->numChars = strlen(value); - entryPtr->string = (char *) ckalloc((unsigned) (entryPtr->numChars + 1)); + entryPtr->numBytes = strlen(value); + entryPtr->numChars = Tcl_NumUtfChars(value, entryPtr->numBytes); + entryPtr->string = + (char *) ckalloc((unsigned) (entryPtr->numBytes + 1)); strcpy(entryPtr->string, value); - if (entryPtr->selectFirst != -1) { + + if (entryPtr->displayString == oldSource) { + entryPtr->displayString = entryPtr->string; + entryPtr->numDisplayBytes = entryPtr->numBytes; + } + + if (entryPtr->selectFirst >= 0) { if (entryPtr->selectFirst >= entryPtr->numChars) { - entryPtr->selectFirst = entryPtr->selectLast = -1; + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; } else if (entryPtr->selectLast > entryPtr->numChars) { entryPtr->selectLast = entryPtr->numChars; } } if (entryPtr->leftIndex >= entryPtr->numChars) { - entryPtr->leftIndex = entryPtr->numChars-1; - if (entryPtr->leftIndex < 0) { + if (entryPtr->numChars > 0) { + entryPtr->leftIndex = entryPtr->numChars - 1; + } else { entryPtr->leftIndex = 0; } } @@ -1638,14 +1894,7 @@ EntryEventProc(clientData, eventPtr) EventuallyRedraw(entryPtr); entryPtr->flags |= BORDER_NEEDED; } else if (eventPtr->type == DestroyNotify) { - if (entryPtr->tkwin != NULL) { - entryPtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd); - } - if (entryPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayEntry, (ClientData) entryPtr); - } - Tcl_EventuallyFree((ClientData) entryPtr, DestroyEntry); + DestroyEntry((char *) clientData); } else if (eventPtr->type == ConfigureNotify) { Tcl_Preserve((ClientData) entryPtr); entryPtr->flags |= UPDATE_SCROLLBAR; @@ -1686,7 +1935,6 @@ EntryCmdDeletedProc(clientData) ClientData clientData; /* Pointer to widget record for widget. */ { Entry *entryPtr = (Entry *) clientData; - Tk_Window tkwin = entryPtr->tkwin; /* * This procedure could be invoked either because the window was @@ -1695,14 +1943,13 @@ EntryCmdDeletedProc(clientData) * destroys the widget. */ - if (tkwin != NULL) { - entryPtr->tkwin = NULL; - Tk_DestroyWindow(tkwin); + if (! entryPtr->flags & ENTRY_DELETED) { + Tk_DestroyWindow(entryPtr->tkwin); } } /* - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- * * GetEntryIndex -- * @@ -1711,15 +1958,15 @@ EntryCmdDeletedProc(clientData) * * Results: * A standard Tcl result. If all went well, then *indexPtr is - * filled in with the index (into entryPtr) corresponding to + * filled in with the character index (into entryPtr) corresponding to * string. The index value is guaranteed to lie between 0 and * the number of characters in the string, inclusive. If an - * error occurs then an error message is left in interp->result. + * error occurs then an error message is left in the interp's result. * * Side effects: * None. * - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- */ static int @@ -1728,7 +1975,8 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) Entry *entryPtr; /* Entry for which the index is being * specified. */ char *string; /* Specifies character in entryPtr. */ - int *indexPtr; /* Where to store converted index. */ + int *indexPtr; /* Where to store converted character + * index. */ { size_t length; @@ -1741,7 +1989,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) badIndex: /* - * Some of the paths here leave messages in interp->result, + * Some of the paths here leave messages in the interp's result, * so we have to clear it out before storing our own message. */ @@ -1763,8 +2011,8 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) goto badIndex; } } else if (string[0] == 's') { - if (entryPtr->selectFirst == -1) { - interp->result = "selection isn't in entry"; + if (entryPtr->selectFirst < 0) { + Tcl_SetResult(interp, "selection isn't in entry", TCL_STATIC); return TCL_ERROR; } if (length < 5) { @@ -1780,7 +2028,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) } else if (string[0] == '@') { int x, roundUp; - if (Tcl_GetInt(interp, string+1, &x) != TCL_OK) { + if (Tcl_GetInt(interp, string + 1, &x) != TCL_OK) { goto badIndex; } if (x < entryPtr->inset) { @@ -1812,7 +2060,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) *indexPtr = 0; } else if (*indexPtr > entryPtr->numChars) { *indexPtr = entryPtr->numChars; - } + } } return TCL_OK; } @@ -1836,9 +2084,8 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) static void EntryScanTo(entryPtr, x) - register Entry *entryPtr; /* Information about widget. */ - int x; /* X-coordinate to use for scan - * operation. */ + Entry *entryPtr; /* Information about widget. */ + int x; /* X-coordinate to use for scan operation. */ { int newLeftIndex; @@ -1854,19 +2101,24 @@ EntryScanTo(entryPtr, x) */ newLeftIndex = entryPtr->scanMarkIndex - - (10*(x - entryPtr->scanMarkX))/entryPtr->avgWidth; + - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth; if (newLeftIndex >= entryPtr->numChars) { - newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars-1; + newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1; entryPtr->scanMarkX = x; } if (newLeftIndex < 0) { newLeftIndex = entryPtr->scanMarkIndex = 0; entryPtr->scanMarkX = x; } + if (newLeftIndex != entryPtr->leftIndex) { entryPtr->leftIndex = newLeftIndex; entryPtr->flags |= UPDATE_SCROLLBAR; EntryComputeGeometry(entryPtr); + if (newLeftIndex != entryPtr->leftIndex) { + entryPtr->scanMarkIndex = entryPtr->leftIndex; + entryPtr->scanMarkX = x; + } EventuallyRedraw(entryPtr); } } @@ -1890,10 +2142,9 @@ EntryScanTo(entryPtr, x) static void EntrySelectTo(entryPtr, index) - register Entry *entryPtr; /* Information about widget. */ - int index; /* Index of element that is to - * become the "other" end of the - * selection. */ + Entry *entryPtr; /* Information about widget. */ + int index; /* Character index of element that is to + * become the "other" end of the selection. */ { int newFirst, newLast; @@ -1956,38 +2207,35 @@ EntrySelectTo(entryPtr, index) static int EntryFetchSelection(clientData, offset, buffer, maxBytes) - ClientData clientData; /* Information about entry widget. */ - int offset; /* Offset within selection of first - * character to be returned. */ - char *buffer; /* Location in which to place - * selection. */ - int maxBytes; /* Maximum number of bytes to place - * at buffer, not including terminating - * NULL character. */ + ClientData clientData; /* Information about entry widget. */ + int offset; /* Byte offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place selection. */ + int maxBytes; /* Maximum number of bytes to place at + * buffer, not including terminating NULL + * character. */ { Entry *entryPtr = (Entry *) clientData; - int count; - char *displayString; + int byteCount; + char *string, *selStart, *selEnd; if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { return -1; } - count = entryPtr->selectLast - entryPtr->selectFirst - offset; - if (count > maxBytes) { - count = maxBytes; + string = entryPtr->displayString; + selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst); + selEnd = Tcl_UtfAtIndex(selStart, + entryPtr->selectLast - entryPtr->selectFirst); + byteCount = selEnd - selStart - offset; + if (byteCount > maxBytes) { + byteCount = maxBytes; } - if (count <= 0) { + if (byteCount <= 0) { return 0; } - if (entryPtr->displayString == NULL) { - displayString = entryPtr->string; - } else { - displayString = entryPtr->displayString; - } - strncpy(buffer, displayString + entryPtr->selectFirst + offset, - (size_t) count); - buffer[count] = '\0'; - return count; + memcpy(buffer, selStart + offset, (size_t) byteCount); + buffer[byteCount] = '\0'; + return byteCount; } /* @@ -2010,7 +2258,7 @@ EntryFetchSelection(clientData, offset, buffer, maxBytes) static void EntryLostSelection(clientData) - ClientData clientData; /* Information about entry widget. */ + ClientData clientData; /* Information about entry widget. */ { Entry *entryPtr = (Entry *) clientData; @@ -2023,7 +2271,7 @@ EntryLostSelection(clientData) */ #ifdef ALWAYS_SHOW_SELECTION - if ((entryPtr->selectFirst != -1) && entryPtr->exportSelection) { + if ((entryPtr->selectFirst >= 0) && entryPtr->exportSelection) { entryPtr->selectFirst = -1; entryPtr->selectLast = -1; EventuallyRedraw(entryPtr); @@ -2052,7 +2300,7 @@ EntryLostSelection(clientData) static void EventuallyRedraw(entryPtr) - register Entry *entryPtr; /* Information about widget. */ + Entry *entryPtr; /* Information about widget. */ { if ((entryPtr->tkwin == NULL) || !Tk_IsMapped(entryPtr->tkwin)) { return; @@ -2091,11 +2339,11 @@ EventuallyRedraw(entryPtr) static void EntryVisibleRange(entryPtr, firstPtr, lastPtr) - Entry *entryPtr; /* Information about widget. */ - double *firstPtr; /* Return position of first visible - * character in widget. */ - double *lastPtr; /* Return position of char just after - * last visible one. */ + Entry *entryPtr; /* Information about widget. */ + double *firstPtr; /* Return position of first visible + * character in widget. */ + double *lastPtr; /* Return position of char just after last + * visible one. */ { int charsInWindow; @@ -2105,22 +2353,18 @@ EntryVisibleRange(entryPtr, firstPtr, lastPtr) } else { charsInWindow = Tk_PointToChar(entryPtr->textLayout, Tk_Width(entryPtr->tkwin) - entryPtr->inset - - entryPtr->layoutX - 1, 0) + 1; - if (charsInWindow > entryPtr->numChars) { - /* - * If all chars were visible, then charsInWindow will be - * the index just after the last char that was visible. - */ - - charsInWindow = entryPtr->numChars; + - entryPtr->layoutX - 1, 0); + if (charsInWindow < entryPtr->numChars) { + charsInWindow++; } charsInWindow -= entryPtr->leftIndex; if (charsInWindow == 0) { charsInWindow = 1; } - *firstPtr = ((double) entryPtr->leftIndex)/entryPtr->numChars; - *lastPtr = ((double) (entryPtr->leftIndex + charsInWindow)) - /entryPtr->numChars; + + *firstPtr = (double) entryPtr->leftIndex / entryPtr->numChars; + *lastPtr = (double) (entryPtr->leftIndex + charsInWindow) + / entryPtr->numChars; } } @@ -2148,7 +2392,7 @@ static void EntryUpdateScrollbar(entryPtr) Entry *entryPtr; /* Information about widget. */ { - char args[100]; + char args[TCL_DOUBLE_SPACE * 2]; int code; double first, last; Tcl_Interp *interp; @@ -2193,7 +2437,7 @@ static void EntryBlinkProc(clientData) ClientData clientData; /* Pointer to record describing entry. */ { - register Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = (Entry *) clientData; if (!(entryPtr->flags & GOT_FOCUS) || (entryPtr->insertOffTime == 0)) { return; @@ -2230,7 +2474,7 @@ EntryBlinkProc(clientData) static void EntryFocusProc(entryPtr, gotFocus) - register Entry *entryPtr; /* Entry that got or lost focus. */ + Entry *entryPtr; /* Entry that got or lost focus. */ int gotFocus; /* 1 means window is getting focus, 0 means * it's losing it. */ { @@ -2276,7 +2520,7 @@ EntryTextVarProc(clientData, interp, name1, name2, flags) char *name2; /* Not used. */ int flags; /* Information about what happened. */ { - register Entry *entryPtr = (Entry *) clientData; + Entry *entryPtr = (Entry *) clientData; char *value; /* diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 6403001..a72be72 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.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: tkEvent.c,v 1.3 1998/10/10 00:30:36 rjohnson Exp $ + * RCS: @(#) $Id: tkEvent.c,v 1.4 1999/04/16 01:51:13 stanton Exp $ */ #include "tkPort.h" @@ -39,10 +39,6 @@ typedef struct InProgress { struct InProgress *nextPtr; /* Next higher nested search. */ } InProgress; -static InProgress *pendingPtr = NULL; - /* Topmost search in progress, or - * NULL if none. */ - /* * For each call to Tk_CreateGenericHandler, an instance of the following * structure will be created. All of the active handlers are linked into a @@ -58,11 +54,6 @@ typedef struct GenericHandler { * handlers, or NULL for end of list. */ } GenericHandler; -static GenericHandler *genericList = NULL; - /* First handler in the list, or NULL. */ -static GenericHandler *lastGenericPtr = NULL; - /* Last handler in list. */ - /* * There's a potential problem if Tk_HandleEvent is entered recursively. * A handler cannot be deleted physically until we have returned from @@ -70,11 +61,8 @@ static GenericHandler *lastGenericPtr = NULL; * its `next' entry. We deal with the problem by using the `delete flag' and * deleting handlers only when it's known that there's no handler active. * - * The following variable has a non-zero value when a handler is active. */ -static int genericHandlersActive = 0; - /* * The following structure is used for queueing X-style events on the * Tcl event queue. @@ -134,15 +122,37 @@ static unsigned long eventMasks[TK_LASTEVENT] = { MouseWheelMask /* MouseWheelEvent */ }; + /* - * If someone has called Tk_RestrictEvents, the information below - * keeps track of it. + * The structure below is used to store Data for the Event module that + * must be kept thread-local. The "dataKey" is used to fetch the + * thread-specific storage for the current thread. */ -static Tk_RestrictProc *restrictProc; +typedef struct ThreadSpecificData { + + int genericHandlersActive; + /* The following variable has a non-zero + * value when a handler is active. */ + InProgress *pendingPtr; + /* Topmost search in progress, or + * NULL if none. */ + GenericHandler *genericList; + /* First handler in the list, or NULL. */ + GenericHandler *lastGenericPtr; + /* Last handler in list. */ + + /* + * If someone has called Tk_RestrictEvents, the information below + * keeps track of it. + */ + + Tk_RestrictProc *restrictProc; /* Procedure to call. NULL means no * restrictProc is currently in effect. */ -static ClientData restrictArg; /* Argument to pass to restrictProc. */ + ClientData restrictArg; /* Argument to pass to restrictProc. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Prototypes for procedures that are only referenced locally within @@ -266,6 +276,8 @@ Tk_DeleteEventHandler(token, mask, proc, clientData) register InProgress *ipPtr; TkEventHandler *prevPtr; register TkWindow *winPtr = (TkWindow *) token; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the event handler to be deleted, or return @@ -288,7 +300,7 @@ Tk_DeleteEventHandler(token, mask, proc, clientData) * process the next one instead. */ - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->nextHandler == handlerPtr) { ipPtr->nextHandler = handlerPtr->nextPtr; } @@ -337,6 +349,8 @@ Tk_CreateGenericHandler(proc, clientData) ClientData clientData; /* One-word value to pass to proc. */ { GenericHandler *handlerPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); handlerPtr = (GenericHandler *) ckalloc (sizeof (GenericHandler)); @@ -344,12 +358,12 @@ Tk_CreateGenericHandler(proc, clientData) handlerPtr->clientData = clientData; handlerPtr->deleteFlag = 0; handlerPtr->nextPtr = NULL; - if (genericList == NULL) { - genericList = handlerPtr; + if (tsdPtr->genericList == NULL) { + tsdPtr->genericList = handlerPtr; } else { - lastGenericPtr->nextPtr = handlerPtr; + tsdPtr->lastGenericPtr->nextPtr = handlerPtr; } - lastGenericPtr = handlerPtr; + tsdPtr->lastGenericPtr = handlerPtr; } /* @@ -377,8 +391,10 @@ Tk_DeleteGenericHandler(proc, clientData) ClientData clientData; { GenericHandler * handler; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - for (handler = genericList; handler; handler = handler->nextPtr) { + for (handler = tsdPtr->genericList; handler; handler = handler->nextPtr) { if ((handler->proc == proc) && (handler->clientData == clientData)) { handler->deleteFlag = 1; } @@ -388,6 +404,39 @@ Tk_DeleteGenericHandler(proc, clientData) /* *-------------------------------------------------------------- * + * TkEventInit -- + * + * This procedures initializes all the event module + * structures used by the current thread. It must be + * called before any other procedure in this file is + * called. + * + * Results: + * None. + * + * Side Effects: + * None. + * + *-------------------------------------------------------------- + */ + +void +TkEventInit(void) +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + tsdPtr->genericHandlersActive = 0; + tsdPtr->pendingPtr = NULL; + tsdPtr->genericList = NULL; + tsdPtr->lastGenericPtr = NULL; + tsdPtr->restrictProc = NULL; + tsdPtr->restrictArg = NULL; +} + +/* + *-------------------------------------------------------------- + * * Tk_HandleEvent -- * * Given an event, invoke all the handlers that have @@ -415,6 +464,8 @@ Tk_HandleEvent(eventPtr) Window handlerWindow; TkDisplay *dispPtr; Tcl_Interp *interp = (Tcl_Interp *) NULL; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Next, invoke all the generic event handlers (those that are @@ -422,9 +473,10 @@ Tk_HandleEvent(eventPtr) * an event is fully processed, go no further. */ - for (genPrevPtr = NULL, genericPtr = genericList; genericPtr != NULL; ) { + for (genPrevPtr = NULL, genericPtr = tsdPtr->genericList; + genericPtr != NULL; ) { if (genericPtr->deleteFlag) { - if (!genericHandlersActive) { + if (!tsdPtr->genericHandlersActive) { GenericHandler *tmpPtr; /* @@ -435,12 +487,12 @@ Tk_HandleEvent(eventPtr) tmpPtr = genericPtr->nextPtr; if (genPrevPtr == NULL) { - genericList = tmpPtr; + tsdPtr->genericList = tmpPtr; } else { genPrevPtr->nextPtr = tmpPtr; } if (tmpPtr == NULL) { - lastGenericPtr = genPrevPtr; + tsdPtr->lastGenericPtr = genPrevPtr; } (void) ckfree((char *) genericPtr); genericPtr = tmpPtr; @@ -449,9 +501,9 @@ Tk_HandleEvent(eventPtr) } else { int done; - genericHandlersActive++; + tsdPtr->genericHandlersActive++; done = (*genericPtr->proc)(genericPtr->clientData, eventPtr); - genericHandlersActive--; + tsdPtr->genericHandlersActive--; if (done) { return; } @@ -623,8 +675,8 @@ Tk_HandleEvent(eventPtr) ip.eventPtr = eventPtr; ip.winPtr = winPtr; ip.nextHandler = NULL; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = tsdPtr->pendingPtr; + tsdPtr->pendingPtr = &ip; if (mask == 0) { if ((eventPtr->type == SelectionClear) || (eventPtr->type == SelectionRequest) @@ -657,7 +709,7 @@ Tk_HandleEvent(eventPtr) TkBindEventProc(winPtr, eventPtr); } } - pendingPtr = ip.nextPtr; + tsdPtr->pendingPtr = ip.nextPtr; done: /* @@ -695,6 +747,8 @@ TkEventDeadWindow(winPtr) { register TkEventHandler *handlerPtr; register InProgress *ipPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * While deleting all the handlers, be careful to check for @@ -706,7 +760,8 @@ TkEventDeadWindow(winPtr) while (winPtr->handlerList != NULL) { handlerPtr = winPtr->handlerList; winPtr->handlerList = handlerPtr->nextPtr; - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; + ipPtr = ipPtr->nextPtr) { if (ipPtr->nextHandler == handlerPtr) { ipPtr->nextHandler = NULL; } @@ -744,11 +799,13 @@ TkCurrentTime(dispPtr) TkDisplay *dispPtr; /* Display for which the time is desired. */ { register XEvent *eventPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (pendingPtr == NULL) { + if (tsdPtr->pendingPtr == NULL) { return dispPtr->lastEventTime; } - eventPtr = pendingPtr->eventPtr; + eventPtr = tsdPtr->pendingPtr->eventPtr; switch (eventPtr->type) { case ButtonPress: case ButtonRelease: @@ -798,11 +855,13 @@ Tk_RestrictEvents(proc, arg, prevArgPtr) * argument. */ { Tk_RestrictProc *prev; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - prev = restrictProc; - *prevArgPtr = restrictArg; - restrictProc = proc; - restrictArg = arg; + prev = tsdPtr->restrictProc; + *prevArgPtr = tsdPtr->restrictArg; + tsdPtr->restrictProc = proc; + tsdPtr->restrictArg = arg; return prev; } @@ -841,7 +900,7 @@ Tk_QueueWindowEvent(eventPtr, position) * Find our display structure for the event's display. */ - for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) { + for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { if (dispPtr == NULL) { return; } @@ -962,12 +1021,14 @@ WindowEventProc(evPtr, flags) { TkWindowEvent *wevPtr = (TkWindowEvent *) evPtr; Tk_RestrictAction result; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!(flags & TCL_WINDOW_EVENTS)) { return 0; } - if (restrictProc != NULL) { - result = (*restrictProc)(restrictArg, &wevPtr->event); + if (tsdPtr->restrictProc != NULL) { + result = (*tsdPtr->restrictProc)(tsdPtr->restrictArg, &wevPtr->event); if (result != TK_PROCESS_EVENT) { if (result == TK_DEFER_EVENT) { return 0; diff --git a/generic/tkFileFilter.c b/generic/tkFileFilter.c index 6a8c54a..0528351 100644 --- a/generic/tkFileFilter.c +++ b/generic/tkFileFilter.c @@ -9,8 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFileFilter.c,v 1.2 1998/09/14 18:23:10 stanton Exp $ - * + * RCS: @(#) $Id: tkFileFilter.c,v 1.3 1999/04/16 01:51:13 stanton Exp $ */ #include "tkInt.h" diff --git a/generic/tkFocus.c b/generic/tkFocus.c index 0db24ff..31ca652 100644 --- a/generic/tkFocus.c +++ b/generic/tkFocus.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFocus.c,v 1.3 1999/02/04 20:53:53 stanton Exp $ + * RCS: @(#) $Id: tkFocus.c,v 1.4 1999/04/16 01:51:14 stanton Exp $ */ #include "tkInt.h" @@ -76,12 +76,6 @@ typedef struct TkDisplayFocusInfo { } DisplayFocusInfo; /* - * Global used for debugging. - */ - -int tclFocusDebug = 0; - -/* * The following magic value is stored in the "send_event" field of * FocusIn and FocusOut events that are generated in this file. This * allows us to separate "real" events coming from the server from @@ -106,7 +100,7 @@ static void SetFocus _ANSI_ARGS_((TkWindow *winPtr, int force)); /* *-------------------------------------------------------------- * - * Tk_FocusCmd -- + * Tk_FocusObjCmd -- * * This procedure is invoked to process the "focus" Tcl command. * See the user documentation for details on what it does. @@ -121,28 +115,30 @@ static void SetFocus _ANSI_ARGS_((TkWindow *winPtr, int force)); */ int -Tk_FocusCmd(clientData, interp, argc, argv) +Tk_FocusObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { + static char *focusOptions[] = {"-displayof", "-force", "-lastfor", + (char *) NULL}; Tk_Window tkwin = (Tk_Window) clientData; TkWindow *winPtr = (TkWindow *) clientData; TkWindow *newPtr, *focusWinPtr, *topLevelPtr; ToplevelFocusInfo *tlFocusPtr; - char c; - size_t length; + char *windowName; + int index; /* * If invoked with no arguments, just return the current focus window. */ - if (argc == 1) { + if (objc == 1) { focusWinPtr = TkGetFocusWin(winPtr); if (focusWinPtr != NULL) { - interp->result = focusWinPtr->pathName; + Tcl_SetResult(interp, focusWinPtr->pathName, TCL_STATIC); } return TCL_OK; } @@ -152,12 +148,18 @@ Tk_FocusCmd(clientData, interp, argc, argv) * on that window. */ - if (argc == 2) { - if (argv[1][0] == 0) { + if (objc == 2) { + windowName = Tcl_GetStringFromObj(objv[1], (int *) NULL); + + /* + * The empty string case exists for backwards compatibility. + */ + + if (windowName[0] == '\0') { return TCL_OK; } - if (argv[1][0] == '.') { - newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin); + if (windowName[0] == '.') { + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); if (newPtr == NULL) { return TCL_ERROR; } @@ -168,65 +170,72 @@ Tk_FocusCmd(clientData, interp, argc, argv) } } - length = strlen(argv[1]); - c = argv[1][1]; - if ((c == 'd') && (strncmp(argv[1], "-displayof", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " -displayof window\"", (char *) NULL); - return TCL_ERROR; - } - newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin); - if (newPtr == NULL) { - return TCL_ERROR; - } - newPtr = TkGetFocusWin(newPtr); - if (newPtr != NULL) { - interp->result = newPtr->pathName; - } - } else if ((c == 'f') && (strncmp(argv[1], "-force", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " -force window\"", (char *) NULL); - return TCL_ERROR; - } - if (argv[2][0] == 0) { - return TCL_OK; - } - newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin); - if (newPtr == NULL) { - return TCL_ERROR; - } - SetFocus(newPtr, 1); - } else if ((c == 'l') && (strncmp(argv[1], "-lastfor", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " -lastfor window\"", (char *) NULL); - return TCL_ERROR; + if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; + } + switch (index) { + case 0: { /* -displayof */ + windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; + } + newPtr = TkGetFocusWin(newPtr); + if (newPtr != NULL) { + Tcl_SetResult(interp, newPtr->pathName, TCL_STATIC); + } + break; } - newPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin); - if (newPtr == NULL) { - return TCL_ERROR; + case 1: { /* -force */ + windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); + + /* + * The empty string case exists for backwards compatibility. + */ + + if (windowName[0] == '\0') { + return TCL_OK; + } + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; + } + SetFocus(newPtr, 1); + break; } - for (topLevelPtr = newPtr; topLevelPtr != NULL; - topLevelPtr = topLevelPtr->parentPtr) { - if (topLevelPtr->flags & TK_TOP_LEVEL) { - for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; - tlFocusPtr != NULL; - tlFocusPtr = tlFocusPtr->nextPtr) { - if (tlFocusPtr->topLevelPtr == topLevelPtr) { - interp->result = tlFocusPtr->focusWinPtr->pathName; - return TCL_OK; + case 2: { /* -lastfor */ + windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; + } + for (topLevelPtr = newPtr; topLevelPtr != NULL; + topLevelPtr = topLevelPtr->parentPtr) { + if (topLevelPtr->flags & TK_TOP_LEVEL) { + for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; + tlFocusPtr != NULL; + tlFocusPtr = tlFocusPtr->nextPtr) { + if (tlFocusPtr->topLevelPtr == topLevelPtr) { + Tcl_SetResult(interp, + tlFocusPtr->focusWinPtr->pathName, + TCL_STATIC); + return TCL_OK; + } } + Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC); + return TCL_OK; } - interp->result = topLevelPtr->pathName; - return TCL_OK; } + break; + } + default: { + panic("bad const entries to focusOptions in focus command"); } - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be -displayof, -force, or -lastfor", (char *) NULL); - return TCL_ERROR; } return TCL_OK; } @@ -479,7 +488,7 @@ TkFocusFilterEvent(winPtr, eventPtr) if (eventPtr->xcrossing.focus && (displayFocusPtr->focusWinPtr == NULL) && !(winPtr->flags & TK_EMBEDDED)) { - if (tclFocusDebug) { + if (dispPtr->focusDebug) { printf("Focussed implicitly on %s\n", newFocusPtr->pathName); } @@ -504,7 +513,7 @@ TkFocusFilterEvent(winPtr, eventPtr) if ((dispPtr->implicitWinPtr != NULL) && !(winPtr->flags & TK_EMBEDDED)) { - if (tclFocusDebug) { + if (dispPtr->focusDebug) { printf("Defocussed implicit Async\n"); } GenerateFocusEvents(displayFocusPtr->focusWinPtr, @@ -820,7 +829,7 @@ TkFocusDeadWindow(winPtr) */ if (dispPtr->implicitWinPtr == winPtr) { - if (tclFocusDebug) { + if (dispPtr->focusDebug) { printf("releasing focus to root after %s died\n", tlFocusPtr->topLevelPtr->pathName); } @@ -848,7 +857,7 @@ TkFocusDeadWindow(winPtr) tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr; if ((displayFocusPtr->focusWinPtr == winPtr) && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) { - if (tclFocusDebug) { + if (dispPtr->focusDebug) { printf("forwarding focus to %s after %s died\n", tlFocusPtr->topLevelPtr->pathName, winPtr->pathName); @@ -943,7 +952,7 @@ FocusMapProc(clientData, eventPtr) if (eventPtr->type == VisibilityNotify) { displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); - if (tclFocusDebug) { + if (winPtr->dispPtr->focusDebug) { printf("auto-focussing on %s, force %d\n", winPtr->pathName, displayFocusPtr->forceFocus); } diff --git a/generic/tkFont.c b/generic/tkFont.c index 4c0ebb9..995fb01 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -6,14 +6,15 @@ * displaying text. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFont.c,v 1.2 1998/09/14 18:23:10 stanton Exp $ + * RCS: @(#) $Id: tkFont.c,v 1.3 1999/04/16 01:51:14 stanton Exp $ */ +#include "tkPort.h" #include "tkInt.h" #include "tkFont.h" @@ -25,26 +26,19 @@ typedef struct TkFontInfo { Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font. - * Keys are CachedFontKey structs, values are - * TkFont structs. */ + * Keys are string font names, values are + * TkFont pointers. */ Tcl_HashTable namedTable; /* Map a name to a set of attributes for a * font, used when constructing a Tk_Font from * a named font description. Keys are - * Tk_Uids, values are NamedFont structs. */ + * strings, values are NamedFont pointers. */ TkMainInfo *mainPtr; /* Application that owns this structure. */ - int updatePending; + int updatePending; /* Non-zero when a World Changed event has + * already been queued to handle a change to + * a named font. */ } TkFontInfo; /* - * The following structure is used as a key in the fontCache. - */ - -typedef struct CachedFontKey { - Display *display; /* Display for which font was constructed. */ - Tk_Uid string; /* String that describes font. */ -} CachedFontKey; - -/* * The following data structure is used to keep track of the font attributes * for each named font that has been defined. The named font is only deleted * when the last reference to it goes away. @@ -77,6 +71,7 @@ typedef struct LayoutChunk { CONST char *start; /* Pointer to simple string to be displayed. * This is a pointer into the TkTextLayout's * string. */ + int numBytes; /* The number of bytes in this chunk. */ int numChars; /* The number of characters in this chunk. */ int numDisplayChars; /* The number of characters to display when * this chunk is displayed. Can be less than @@ -168,13 +163,6 @@ static TkStateMap xlfdSetwidthMap[] = { {TK_SW_UNKNOWN, NULL} }; -static TkStateMap xlfdCharsetMap[] = { - {TK_CS_NORMAL, "iso8859"}, - {TK_CS_SYMBOL, "adobe"}, - {TK_CS_SYMBOL, "sun"}, - {TK_CS_OTHER, NULL} -}; - /* * The following structure and defines specify the valid builtin options * when configuring a set of font attributes. @@ -196,7 +184,135 @@ static char *fontOpt[] = { #define FONT_SLANT 3 #define FONT_UNDERLINE 4 #define FONT_OVERSTRIKE 5 -#define FONT_NUMFIELDS 6 /* Length of fontOpt array. */ +#define FONT_NUMFIELDS 6 + +/* + * Hardcoded font aliases. These are used to describe (mostly) identical + * fonts whose names differ from platform to platform. If the + * user-supplied font name matches any of the names in one of the alias + * lists, the other names in the alias list are also automatically tried. + */ + +static char *timesAliases[] = { + "Times", /* Unix. */ + "Times New Roman", /* Windows. */ + "New York", /* Mac. */ + NULL +}; + +static char *helveticaAliases[] = { + "Helvetica", /* Unix. */ + "Arial", /* Windows. */ + "Geneva", /* Mac. */ + NULL +}; + +static char *courierAliases[] = { + "Courier", /* Unix and Mac. */ + "Courier New", /* Windows. */ + NULL +}; + +static char *minchoAliases[] = { + "mincho", /* Unix. */ + "\357\274\255\357\274\263 \346\230\216\346\234\235", + /* Windows (MS mincho). */ + "\346\234\254\346\230\216\346\234\235\342\210\222\357\274\255", + /* Mac (honmincho-M). */ + NULL +}; + +static char *gothicAliases[] = { + "gothic", /* Unix. */ + "\357\274\255\357\274\263 \343\202\264\343\202\267\343\203\203\343\202\257", + /* Windows (MS goshikku). */ + "\344\270\270\343\202\264\343\202\267\343\203\203\343\202\257\342\210\222\357\274\255", + /* Mac (goshikku-M). */ + NULL +}; + +static char *dingbatsAliases[] = { + "dingbats", "zapfdingbats", "itc zapfdingbats", + /* Unix. */ + /* Windows. */ + "zapf dingbats", /* Mac. */ + NULL +}; + +static char **fontAliases[] = { + timesAliases, + helveticaAliases, + courierAliases, + minchoAliases, + gothicAliases, + dingbatsAliases, + NULL +}; + +/* + * Hardcoded font classes. If the character cannot be found in the base + * font, the classes are examined in order to see if some other similar + * font should be examined also. + */ + +static char *systemClass[] = { + "fixed", /* Unix. */ + /* Windows. */ + "chicago", "osaka", "sistemny", /* Mac. */ + NULL +}; + +static char *serifClass[] = { + "times", "palatino", "mincho", /* All platforms. */ + "song ti", /* Unix. */ + "ms serif", "simplified arabic", /* Windows. */ + "latinski", /* Mac. */ + NULL +}; + +static char *sansClass[] = { + "helvetica", "gothic", /* All platforms. */ + /* Unix. */ + "ms sans serif", "traditional arabic", + /* Windows. */ + "bastion", /* Mac. */ + NULL +}; + +static char *monoClass[] = { + "courier", "gothic", /* All platforms. */ + "fangsong ti", /* Unix. */ + "simplified arabic fixed", /* Windows. */ + "monaco", "pryamoy", /* Mac. */ + NULL +}; + +static char *symbolClass[] = { + "symbol", "dingbats", "wingdings", NULL +}; + +static char **fontFallbacks[] = { + systemClass, + serifClass, + sansClass, + monoClass, + symbolClass, + NULL +}; + +/* + * Global fallbacks. If the character could not be found in the preferred + * fallback list, this list is examined. If the character still cannot be + * found, all font families in the system are examined. + */ + +static char *globalFontClass[] = { + "symbol", /* All platforms. */ + /* Unix. */ + "lucida sans unicode", /* Windows. */ + "chicago", /* Mac. */ + NULL +}; #define GetFontAttributes(tkfont) \ ((CONST TkFontAttributes *) &((TkFont *) (tkfont))->fa) @@ -208,7 +324,13 @@ static char *fontOpt[] = { static int ConfigAttributesObj _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[], TkFontAttributes *faPtr)); +static int CreateNamedFont _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, CONST char *name, + TkFontAttributes *faPtr)); +static void DupFontObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, + Tcl_Obj *dupObjPtr)); static int FieldSpecified _ANSI_ARGS_((CONST char *field)); +static void FreeFontObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); static int GetAttributeInfoObj _ANSI_ARGS_((Tcl_Interp *interp, CONST TkFontAttributes *faPtr, Tcl_Obj *objPtr)); static LayoutChunk * NewChunk _ANSI_ARGS_((TextLayout **layoutPtrPtr, @@ -218,12 +340,27 @@ static int ParseFontNameObj _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, TkFontAttributes *faPtr)); static void RecomputeWidgets _ANSI_ARGS_((TkWindow *winPtr)); +static int SetFontFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); static void TheWorldHasChanged _ANSI_ARGS_(( ClientData clientData)); -static void UpdateDependantFonts _ANSI_ARGS_((TkFontInfo *fiPtr, +static void UpdateDependentFonts _ANSI_ARGS_((TkFontInfo *fiPtr, Tk_Window tkwin, Tcl_HashEntry *namedHashPtr)); - +/* + * The following structure defines the implementation of the "font" Tcl + * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of + * each font object points to the TkFont structure for the font, or + * NULL. + */ + +static Tcl_ObjType fontObjType = { + "font", /* name */ + FreeFontObjProc, /* freeIntRepProc */ + DupFontObjProc, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetFontFromAny /* setFromAnyProc */ +}; /* @@ -236,8 +373,8 @@ static void UpdateDependantFonts _ANSI_ARGS_((TkFontInfo *fiPtr, * package on a per application basis. * * Results: - * Returns a token that must be stored in the TkMainInfo for this - * application. + * Stores a token in the mainPtr to hold information needed by this + * package on a per application basis. * * Side effects: * Memory allocated. @@ -251,11 +388,13 @@ TkFontPkgInit(mainPtr) TkFontInfo *fiPtr; fiPtr = (TkFontInfo *) ckalloc(sizeof(TkFontInfo)); - Tcl_InitHashTable(&fiPtr->fontCache, sizeof(CachedFontKey) / sizeof(int)); - Tcl_InitHashTable(&fiPtr->namedTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&fiPtr->fontCache, TCL_STRING_KEYS); + Tcl_InitHashTable(&fiPtr->namedTable, TCL_STRING_KEYS); fiPtr->mainPtr = mainPtr; fiPtr->updatePending = 0; mainPtr->fontInfoPtr = fiPtr; + + TkpFontPkgInit(mainPtr); } /* @@ -281,12 +420,21 @@ TkFontPkgFree(mainPtr) TkMainInfo *mainPtr; /* The application being deleted. */ { TkFontInfo *fiPtr; - Tcl_HashEntry *hPtr; + Tcl_HashEntry *hPtr, *searchPtr; Tcl_HashSearch search; + int fontsLeft; fiPtr = mainPtr->fontInfoPtr; - if (fiPtr->fontCache.numEntries != 0) { + fontsLeft = 0; + for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); + searchPtr != NULL; + searchPtr = Tcl_NextHashEntry(&search)) { + fontsLeft++; + fprintf(stderr, "Font %s still in cache.\n", + Tcl_GetHashKey(&fiPtr->fontCache, searchPtr)); + } + if (fontsLeft) { panic("TkFontPkgFree: all fonts should have been freed already"); } Tcl_DeleteHashTable(&fiPtr->fontCache); @@ -368,7 +516,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) "font ?-displayof window? ?option?"); return TCL_ERROR; } - tkfont = Tk_GetFontFromObj(interp, tkwin, objv[2]); + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); if (tkfont == NULL) { return TCL_ERROR; } @@ -394,14 +542,14 @@ Tk_FontObjCmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?"); return TCL_ERROR; } - string = Tk_GetUid(Tcl_GetStringFromObj(objv[2], NULL)); + string = Tcl_GetString(objv[2]); namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); nfPtr = NULL; /* lint. */ if (namedHashPtr != NULL) { nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); } if ((namedHashPtr == NULL) || (nfPtr->deletePending != 0)) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "named font \"", string, + Tcl_AppendResult(interp, "named font \"", string, "\" doesn't exist", NULL); return TCL_ERROR; } @@ -412,7 +560,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) } else { result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3, &nfPtr->fa); - UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); + UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); return result; } return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); @@ -420,7 +568,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) case FONT_CREATE: { int skip, i; char *name; - char buf[32]; + char buf[16 + TCL_INTEGER_SPACE]; TkFontAttributes fa; Tcl_HashEntry *namedHashPtr; @@ -428,7 +576,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) if (objc < 3) { name = NULL; } else { - name = Tcl_GetStringFromObj(objv[2], NULL); + name = Tcl_GetString(objv[2]); if (name[0] == '-') { name = NULL; } @@ -440,8 +588,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) for (i = 1; ; i++) { sprintf(buf, "font%d", i); - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, - Tk_GetUid(buf)); + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf); if (namedHashPtr == NULL) { break; } @@ -454,10 +601,10 @@ Tk_FontObjCmd(clientData, interp, objc, objv) &fa) != TCL_OK) { return TCL_ERROR; } - if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { + if (CreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { return TCL_ERROR; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); + Tcl_AppendResult(interp, name, NULL); break; } case FONT_DELETE: { @@ -476,10 +623,10 @@ Tk_FontObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } for (i = 2; i < objc; i++) { - string = Tk_GetUid(Tcl_GetStringFromObj(objv[i], NULL)); + string = Tcl_GetString(objv[i]); namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); if (namedHashPtr == NULL) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "named font \"", string, + Tcl_AppendResult(interp, "named font \"", string, "\" doesn't exist", (char *) NULL); return TCL_ERROR; } @@ -511,6 +658,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) char *string; Tk_Font tkfont; int length, skip; + Tcl_Obj *resultPtr; skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); if (skip < 0) { @@ -521,17 +669,17 @@ Tk_FontObjCmd(clientData, interp, objc, objv) "font ?-displayof window? text"); return TCL_ERROR; } - tkfont = Tk_GetFontFromObj(interp, tkwin, objv[2]); + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); if (tkfont == NULL) { return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[3 + skip], &length); - Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_TextWidth(tkfont, string, length)); + resultPtr = Tcl_GetObjResult(interp); + Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length)); Tk_FreeFont(tkfont); break; } case FONT_METRICS: { - char buf[64]; Tk_Font tkfont; int skip, index, i; CONST TkFontMetrics *fmPtr; @@ -548,7 +696,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) "font ?-displayof window? ?option?"); return TCL_ERROR; } - tkfont = Tk_GetFontFromObj(interp, tkwin, objv[2]); + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); if (tkfont == NULL) { return TCL_ERROR; } @@ -556,11 +704,13 @@ Tk_FontObjCmd(clientData, interp, objc, objv) objv += skip; fmPtr = GetFontMetrics(tkfont); if (objc == 3) { + char buf[64 + TCL_INTEGER_SPACE * 4]; + sprintf(buf, "-ascent %d -descent %d -linespace %d -fixed %d", fmPtr->ascent, fmPtr->descent, fmPtr->ascent + fmPtr->descent, fmPtr->fixed); - Tcl_SetStringObj(Tcl_GetObjResult(interp), buf, -1); + Tcl_AppendResult(interp, buf, NULL); } else { if (Tcl_GetIndexFromObj(interp, objv[3], switches, "metric", 0, &index) != TCL_OK) { @@ -582,22 +732,23 @@ Tk_FontObjCmd(clientData, interp, objc, objv) } case FONT_NAMES: { char *string; - Tcl_Obj *strPtr; NamedFont *nfPtr; Tcl_HashSearch search; Tcl_HashEntry *namedHashPtr; + Tcl_Obj *strPtr, *resultPtr; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "names"); return TCL_ERROR; } + resultPtr = Tcl_GetObjResult(interp); namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (namedHashPtr != NULL) { nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->deletePending == 0) { string = Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr); strPtr = Tcl_NewStringObj(string, -1); - Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), strPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } namedHashPtr = Tcl_NextHashEntry(&search); } @@ -610,7 +761,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) /* *--------------------------------------------------------------------------- * - * UpdateDependantFonts, TheWorldHasChanged, RecomputeWidgets -- + * UpdateDependentFonts, TheWorldHasChanged, RecomputeWidgets -- * * Called when the attributes of a named font changes. Updates all * the instantiated fonts that depend on that named font and then @@ -627,7 +778,7 @@ Tk_FontObjCmd(clientData, interp, objc, objv) */ static void -UpdateDependantFonts(fiPtr, tkwin, namedHashPtr) +UpdateDependentFonts(fiPtr, tkwin, namedHashPtr) TkFontInfo *fiPtr; /* Info about application's fonts. */ Tk_Window tkwin; /* A window in the application. */ Tcl_HashEntry *namedHashPtr;/* The named font that is changing. */ @@ -647,15 +798,16 @@ UpdateDependantFonts(fiPtr, tkwin, namedHashPtr) return; } - cacheHashPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search); while (cacheHashPtr != NULL) { - fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); - if (fontPtr->namedHashPtr == namedHashPtr) { - TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa); - if (fiPtr->updatePending == 0) { - fiPtr->updatePending = 1; - Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData) fiPtr); + for (fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + fontPtr != NULL; fontPtr = fontPtr->nextPtr) { + if (fontPtr->namedHashPtr == namedHashPtr) { + TkpGetFontFromAttributes(fontPtr, tkwin, &nfPtr->fa); + if (fiPtr->updatePending == 0) { + fiPtr->updatePending = 1; + Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData) fiPtr); + } } } cacheHashPtr = Tcl_NextHashEntry(&search); @@ -690,7 +842,7 @@ RecomputeWidgets(winPtr) /* *--------------------------------------------------------------------------- * - * TkCreateNamedFont -- + * CreateNamedFont -- * * Create the specified named font with the given attributes in the * named font table associated with the interp. @@ -698,7 +850,7 @@ RecomputeWidgets(winPtr) * Results: * Returns TCL_OK if the font was successfully created, or TCL_ERROR * if the named font already existed. If TCL_ERROR is returned, an - * error message is left in interp->result. + * error message is left in the interp's result. * * Side effects: * Assume there used to exist a named font by the specified name, and @@ -711,8 +863,8 @@ RecomputeWidgets(winPtr) *--------------------------------------------------------------------------- */ -int -TkCreateNamedFont(interp, tkwin, name, faPtr) +static int +CreateNamedFont(interp, tkwin, name, faPtr) Tcl_Interp *interp; /* Interp for error return. */ Tk_Window tkwin; /* A window associated with interp. */ CONST char *name; /* Name for the new named font. */ @@ -725,14 +877,13 @@ TkCreateNamedFont(interp, tkwin, name, faPtr) fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - name = Tk_GetUid(name); namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &new); if (new == 0) { nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->deletePending == 0) { - interp->result[0] = '\0'; - Tcl_AppendResult(interp, "font \"", name, + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "named font \"", name, "\" already exists", (char *) NULL); return TCL_ERROR; } @@ -745,7 +896,7 @@ TkCreateNamedFont(interp, tkwin, name, faPtr) nfPtr->fa = *faPtr; nfPtr->deletePending = 0; - UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); + UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); return TCL_OK; } @@ -769,13 +920,13 @@ TkCreateNamedFont(interp, tkwin, name, faPtr) * Results: * The return value is token for the font, or NULL if an error * prevented the font from being created. If NULL is returned, an - * error message will be left in interp->result. + * error message will be left in the interp's result. * * Side effects: - * Calls Tk_GetFontFromObj(), which modifies interp's result object, - * then copies the string from the result object into interp->result. - * This procedure will go away when Tk_ConfigureWidget() is - * made into an object command. + * The font is added to an internal database with a reference + * count. For each call to this procedure, there should eventually + * be a call to Tk_FreeFont() or Tk_FreeFontFromObj() so that the + * database is cleaned up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ @@ -787,26 +938,20 @@ Tk_GetFont(interp, tkwin, string) CONST char *string; /* String describing font, as: named font, * native format, or parseable string. */ { + Tk_Font tkfont; Tcl_Obj *strPtr; - Tk_Font tkfont; - - strPtr = Tcl_NewStringObj((char *) string, -1); - - tkfont = Tk_GetFontFromObj(interp, tkwin, strPtr); - if (tkfont == NULL) { - Tcl_SetResult(interp, - Tcl_GetStringFromObj(Tcl_GetObjResult(interp), NULL), - TCL_VOLATILE); - } - Tcl_DecrRefCount(strPtr); /* done with object */ + strPtr = Tcl_NewStringObj((char *) string, -1); + Tcl_IncrRefCount(strPtr); + tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr); + Tcl_DecrRefCount(strPtr); return tkfont; } /* *--------------------------------------------------------------------------- * - * Tk_GetFontFromObj -- + * Tk_AllocFontFromObj -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. @@ -819,46 +964,77 @@ Tk_GetFont(interp, tkwin, string) * Side effects: * The font is added to an internal database with a reference * count. For each call to this procedure, there should eventually - * be a call to Tk_FreeFont() so that the database is cleaned up when - * fonts aren't in use anymore. + * be a call to Tk_FreeFont() or Tk_FreeFontFromObj() so that the + * database is cleaned up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ Tk_Font -Tk_GetFontFromObj(interp, tkwin, objPtr) +Tk_AllocFontFromObj(interp, tkwin, objPtr) Tcl_Interp *interp; /* Interp for database and error return. */ - Tk_Window tkwin; /* For display on which font will be used. */ + Tk_Window tkwin; /* For screen on which font will be used. */ Tcl_Obj *objPtr; /* Object describing font, as: named font, * native format, or parseable string. */ { TkFontInfo *fiPtr; - CachedFontKey key; Tcl_HashEntry *cacheHashPtr, *namedHashPtr; - TkFont *fontPtr; + TkFont *fontPtr, *firstFontPtr, *oldFontPtr; int new, descent; NamedFont *nfPtr; - char *string; - + fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; - string = Tcl_GetStringFromObj(objPtr, NULL); + if (objPtr->typePtr != &fontObjType) { + SetFontFromAny(interp, objPtr); + } - key.display = Tk_Display(tkwin); - key.string = Tk_GetUid(string); - cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache, (char *) &key, &new); + oldFontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; - if (new == 0) { - /* - * We have already constructed a font with this description for - * this display. Bump the reference count of the cached font. - */ + if (oldFontPtr != NULL) { + if (oldFontPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a TkFont that's + * no longer in use. Clear the reference. + */ - fontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); - fontPtr->refCount++; - return (Tk_Font) fontPtr; + FreeFontObjProc(objPtr); + oldFontPtr = NULL; + } else if (Tk_Screen(tkwin) == oldFontPtr->screen) { + oldFontPtr->resourceRefCount++; + return (Tk_Font) oldFontPtr; + } + } + + /* + * Next, search the list of fonts that have the name we want, to see + * if one of them is for the right screen. + */ + + new = 0; + if (oldFontPtr != NULL) { + cacheHashPtr = oldFontPtr->cacheHashPtr; + FreeFontObjProc(objPtr); + } else { + cacheHashPtr = Tcl_CreateHashEntry(&fiPtr->fontCache, + Tcl_GetString(objPtr), &new); + } + firstFontPtr = (TkFont *) Tcl_GetHashValue(cacheHashPtr); + for (fontPtr = firstFontPtr; (fontPtr != NULL); + fontPtr = fontPtr->nextPtr) { + if (Tk_Screen(tkwin) == fontPtr->screen) { + fontPtr->resourceRefCount++; + fontPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; + return (Tk_Font) fontPtr; + } } - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, key.string); + /* + * The desired font isn't in the table. Make a new one. + */ + + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, + Tcl_GetString(objPtr)); if (namedHashPtr != NULL) { /* * Construct a font based on a named font. @@ -873,15 +1049,19 @@ Tk_GetFontFromObj(interp, tkwin, objPtr) * Native font? */ - fontPtr = TkpGetNativeFont(tkwin, string); + fontPtr = TkpGetNativeFont(tkwin, Tcl_GetString(objPtr)); if (fontPtr == NULL) { TkFontAttributes fa; + Tcl_Obj *dupObjPtr = Tcl_DuplicateObj(objPtr); - TkInitFontAttributes(&fa); - if (ParseFontNameObj(interp, tkwin, objPtr, &fa) != TCL_OK) { - Tcl_DeleteHashEntry(cacheHashPtr); + if (ParseFontNameObj(interp, tkwin, dupObjPtr, &fa) != TCL_OK) { + if (new) { + Tcl_DeleteHashEntry(cacheHashPtr); + } + Tcl_DecrRefCount(dupObjPtr); return NULL; } + Tcl_DecrRefCount(dupObjPtr); /* * String contained the attributes inline. @@ -890,13 +1070,16 @@ Tk_GetFontFromObj(interp, tkwin, objPtr) fontPtr = TkpGetFontFromAttributes(NULL, tkwin, &fa); } } - Tcl_SetHashValue(cacheHashPtr, fontPtr); - fontPtr->refCount = 1; - fontPtr->cacheHashPtr = cacheHashPtr; - fontPtr->namedHashPtr = namedHashPtr; + fontPtr->resourceRefCount = 1; + fontPtr->objRefCount = 1; + fontPtr->cacheHashPtr = cacheHashPtr; + fontPtr->namedHashPtr = namedHashPtr; + fontPtr->screen = Tk_Screen(tkwin); + fontPtr->nextPtr = firstFontPtr; + Tcl_SetHashValue(cacheHashPtr, fontPtr); - Tk_MeasureChars((Tk_Font) fontPtr, "0", 1, 0, 0, &fontPtr->tabWidth); + Tk_MeasureChars((Tk_Font) fontPtr, "0", 1, -1, 0, &fontPtr->tabWidth); if (fontPtr->tabWidth == 0) { fontPtr->tabWidth = fontPtr->fm.maxWidth; } @@ -918,7 +1101,7 @@ Tk_GetFontFromObj(interp, tkwin, objPtr) descent = fontPtr->fm.descent; fontPtr->underlinePos = descent / 2; - fontPtr->underlineHeight = fontPtr->fa.pointsize / 10; + fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10; if (fontPtr->underlineHeight == 0) { fontPtr->underlineHeight = 1; } @@ -936,10 +1119,125 @@ Tk_GetFontFromObj(interp, tkwin, objPtr) } } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; return (Tk_Font) fontPtr; } /* + *---------------------------------------------------------------------- + * + * Tk_GetFontFromObj -- + * + * Find the font that corresponds to a given object. The font must + * have already been created by Tk_GetFont or Tk_AllocFontFromObj. + * + * Results: + * The return value is a token for the font that matches objPtr + * and is suitable for use in tkwin. + * + * Side effects: + * If the object is not already a font ref, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +Tk_Font +Tk_GetFontFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window that the font will be used in. */ + Tcl_Obj *objPtr; /* The object from which to get the font. */ +{ + TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; + TkFont *fontPtr; + Tcl_HashEntry *hashPtr; + + if (objPtr->typePtr != &fontObjType) { + SetFontFromAny((Tcl_Interp *) NULL, objPtr); + } + + fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; + + if (fontPtr != NULL) { + if (fontPtr->resourceRefCount == 0) { + /* + * This is a stale reference: it refers to a TkFont that's + * no longer in use. Clear the reference. + */ + + FreeFontObjProc(objPtr); + fontPtr = NULL; + } else if (Tk_Screen(tkwin) == fontPtr->screen) { + return (Tk_Font) fontPtr; + } + } + + /* + * Next, search the list of fonts that have the name we want, to see + * if one of them is for the right screen. + */ + + if (fontPtr != NULL) { + hashPtr = fontPtr->cacheHashPtr; + FreeFontObjProc(objPtr); + } else { + hashPtr = Tcl_FindHashEntry(&fiPtr->fontCache, Tcl_GetString(objPtr)); + } + if (hashPtr != NULL) { + for (fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); fontPtr != NULL; + fontPtr = fontPtr->nextPtr) { + if (Tk_Screen(tkwin) == fontPtr->screen) { + fontPtr->objRefCount++; + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; + return (Tk_Font) fontPtr; + } + } + } + + panic("Tk_GetFontFromObj called with non-existent font!"); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * SetFontFromAny -- + * + * Convert the internal representation of a Tcl object to the + * font internal form. + * + * Results: + * Always returns TCL_OK. + * + * Side effects: + * The object is left with its typePtr pointing to fontObjType. + * The TkFont pointer is NULL. + * + *---------------------------------------------------------------------- + */ + +static int +SetFontFromAny(interp, objPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetString(objPtr); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &fontObjType; + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + + return TCL_OK; +} + +/* *--------------------------------------------------------------------------- * * Tk_NameOfFont -- @@ -963,14 +1261,9 @@ Tk_NameOfFont(tkfont) Tk_Font tkfont; /* Font whose name is desired. */ { TkFont *fontPtr; - Tcl_HashEntry *hPtr; - CachedFontKey *keyPtr; fontPtr = (TkFont *) tkfont; - hPtr = fontPtr->cacheHashPtr; - - keyPtr = (CachedFontKey *) Tcl_GetHashKey(hPtr->tablePtr, hPtr); - return (char *) keyPtr->string; + return fontPtr->cacheHashPtr->key.string; } /* @@ -994,30 +1287,144 @@ void Tk_FreeFont(tkfont) Tk_Font tkfont; /* Font to be released. */ { - TkFont *fontPtr; + TkFont *fontPtr, *prevPtr; NamedFont *nfPtr; if (tkfont == NULL) { return; } fontPtr = (TkFont *) tkfont; - fontPtr->refCount--; - if (fontPtr->refCount == 0) { - if (fontPtr->namedHashPtr != NULL) { - /* - * The font is being deleted. Determine if the associated named - * font definition should and/or can be deleted too. - */ + fontPtr->resourceRefCount--; + if (fontPtr->resourceRefCount > 0) { + return; + } + if (fontPtr->namedHashPtr != NULL) { + /* + * This font derived from a named font. Reduce the reference + * count on the named font and free it if no-one else is + * using it. + */ - nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr); - nfPtr->refCount--; - if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) { - Tcl_DeleteHashEntry(fontPtr->namedHashPtr); - ckfree((char *) nfPtr); - } + nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr); + nfPtr->refCount--; + if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) { + Tcl_DeleteHashEntry(fontPtr->namedHashPtr); + ckfree((char *) nfPtr); } - Tcl_DeleteHashEntry(fontPtr->cacheHashPtr); - TkpDeleteFont(fontPtr); + } + + prevPtr = (TkFont *) Tcl_GetHashValue(fontPtr->cacheHashPtr); + if (prevPtr == fontPtr) { + if (fontPtr->nextPtr == NULL) { + Tcl_DeleteHashEntry(fontPtr->cacheHashPtr); + } else { + Tcl_SetHashValue(fontPtr->cacheHashPtr, fontPtr->nextPtr); + } + } else { + while (prevPtr->nextPtr != fontPtr) { + prevPtr = prevPtr->nextPtr; + } + prevPtr->nextPtr = fontPtr->nextPtr; + } + + TkpDeleteFont(fontPtr); + if (fontPtr->objRefCount == 0) { + ckfree((char *) fontPtr); + } +} + +/* + *--------------------------------------------------------------------------- + * + * Tk_FreeFontFromObj -- + * + * Called to release a font inside a Tcl_Obj *. Decrements the refCount + * of the font and removes it from the hash tables if necessary. + * + * Results: + * None. + * + * Side effects: + * The reference count associated with font is decremented, and + * only deallocated when no one is using it. + * + *--------------------------------------------------------------------------- + */ + +void +Tk_FreeFontFromObj(tkwin, objPtr) + Tk_Window tkwin; /* The window this font lives in. Needed + * for the screen value. */ + Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ +{ + Tk_FreeFont(Tk_GetFontFromObj(tkwin, objPtr)); +} + +/* + *--------------------------------------------------------------------------- + * + * FreeFontObjProc -- + * + * This proc is called to release an object reference to a font. + * Called when the object's internal rep is released or when + * the cached fontPtr needs to be changed. + * + * Results: + * None. + * + * Side effects: + * The object reference count is decremented. When both it + * and the hash ref count go to zero, the font's resources + * are released. + * + *--------------------------------------------------------------------------- + */ + +static void +FreeFontObjProc(objPtr) + Tcl_Obj *objPtr; /* The object we are releasing. */ +{ + TkFont *fontPtr = (TkFont *) objPtr->internalRep.twoPtrValue.ptr1; + + if (fontPtr != NULL) { + fontPtr->objRefCount--; + if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) { + ckfree((char *) fontPtr); + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + } + } +} + +/* + *--------------------------------------------------------------------------- + * + * DupFontObjProc -- + * + * When a cached font object is duplicated, this is called to + * update the internal reps. + * + * Results: + * None. + * + * Side effects: + * The font's objRefCount is incremented and the internal rep + * of the copy is set to point to it. + * + *--------------------------------------------------------------------------- + */ + +static void +DupFontObjProc(srcObjPtr, dupObjPtr) + Tcl_Obj *srcObjPtr; /* The object we are copying from. */ + Tcl_Obj *dupObjPtr; /* The object we are copying to. */ +{ + TkFont *fontPtr = (TkFont *) srcObjPtr->internalRep.twoPtrValue.ptr1; + + dupObjPtr->typePtr = srcObjPtr->typePtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; + + if (fontPtr != NULL) { + fontPtr->objRefCount++; } } @@ -1112,7 +1519,6 @@ Tk_GetFontMetrics(tkfont, fmPtr) *--------------------------------------------------------------------------- */ - int Tk_PostscriptFontName(tkfont, dsPtr) Tk_Font tkfont; /* Font in which text will be printed. */ @@ -1154,6 +1560,8 @@ Tk_PostscriptFontName(tkfont, dsPtr) } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { + Tcl_UniChar ch; + /* * Inline, capitalize the first letter of each word, lowercase the * rest of the letters in each word, and then take out the spaces @@ -1165,16 +1573,19 @@ Tk_PostscriptFontName(tkfont, dsPtr) src = dest = Tcl_DStringValue(dsPtr) + len; upper = 1; - for (; *src != '\0'; src++, dest++) { - while (isspace(UCHAR(*src))) { + for (; *src != '\0'; ) { + while (isspace(UCHAR(*src))) { /* INTL: ISO space */ src++; upper = 1; } - *dest = *src; - if ((upper != 0) && (islower(UCHAR(*src)))) { - *dest = toupper(UCHAR(*src)); + src += Tcl_UtfToUniChar(src, &ch); + if (upper) { + ch = Tcl_UniCharToUpper(ch); + upper = 0; + } else { + ch = Tcl_UniCharToLower(ch); } - upper = 0; + dest += Tcl_UniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr)); @@ -1251,7 +1662,7 @@ Tk_PostscriptFontName(tkfont, dsPtr) } } - return fontPtr->fa.pointsize; + return fontPtr->fa.size; } /* @@ -1273,18 +1684,18 @@ Tk_PostscriptFontName(tkfont, dsPtr) */ int -Tk_TextWidth(tkfont, string, numChars) +Tk_TextWidth(tkfont, string, numBytes) Tk_Font tkfont; /* Font in which text will be measured. */ CONST char *string; /* String whose width will be computed. */ - int numChars; /* Number of characters to consider from + int numBytes; /* Number of bytes to consider from * string, or < 0 for strlen(). */ { int width; - if (numChars < 0) { - numChars = strlen(string); + if (numBytes < 0) { + numBytes = strlen(string); } - Tk_MeasureChars(tkfont, string, numChars, 0, 0, &width); + Tk_MeasureChars(tkfont, string, numBytes, -1, 0, &width); return width; } @@ -1311,8 +1722,8 @@ Tk_TextWidth(tkfont, string, numChars) */ void -Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstChar, - lastChar) +Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstByte, + lastByte) Display *display; /* Display on which to draw. */ Drawable drawable; /* Window or pixmap in which to draw. */ GC gc; /* Graphics context for actually drawing @@ -1324,16 +1735,17 @@ Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstChar, * underlined or overstruck. */ int x, y; /* Coordinates at which first character of * string is drawn. */ - int firstChar; /* Index of first character. */ - int lastChar; /* Index of one after the last character. */ + int firstByte; /* Index of first byte of first character. */ + int lastByte; /* Index of first byte after the last + * character. */ { TkFont *fontPtr; int startX, endX; fontPtr = (TkFont *) tkfont; - Tk_MeasureChars(tkfont, string, firstChar, 0, 0, &startX); - Tk_MeasureChars(tkfont, string, lastChar, 0, 0, &endX); + Tk_MeasureChars(tkfont, string, firstByte, -1, 0, &startX); + Tk_MeasureChars(tkfont, string, lastByte, -1, 0, &endX); XFillRectangle(display, drawable, gc, x + startX, y + fontPtr->underlinePos, (unsigned int) (endX - startX), @@ -1394,18 +1806,16 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, { TkFont *fontPtr; CONST char *start, *end, *special; - int n, y, charsThisChunk, maxChunks; + int n, y, bytesThisChunk, maxChunks; int baseline, height, curX, newX, maxWidth; TextLayout *layoutPtr; LayoutChunk *chunkPtr; CONST TkFontMetrics *fmPtr; -#define MAX_LINES 50 - int staticLineLengths[MAX_LINES]; + Tcl_DString lineBuffer; int *lineLengths; - int maxLines, curLine, layoutHeight; + int curLine, layoutHeight; - lineLengths = staticLineLengths; - maxLines = MAX_LINES; + Tcl_DStringInit(&lineBuffer); fontPtr = (TkFont *) tkfont; fmPtr = &fontPtr->fm; @@ -1413,7 +1823,10 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, height = fmPtr->ascent + fmPtr->descent; if (numChars < 0) { - numChars = strlen(string); + numChars = Tcl_NumUtfChars(string, -1); + } + if (wrapLength == 0) { + wrapLength = -1; } maxChunks = 1; @@ -1433,16 +1846,20 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, curX = 0; - end = string + numChars; + end = Tcl_UtfAtIndex(string, numChars); special = string; flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES; flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE; - curLine = 0; for (start = string; start < end; ) { if (start >= special) { /* * Find the next special character in the string. + * + * INTL: Note that it is safe to increment by byte, because we are + * looking for 7-bit characters that will appear unchanged in + * UTF-8. At some point we may need to support the full Unicode + * whitespace set. */ for (special = start; special < end; special++) { @@ -1466,15 +1883,15 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, chunkPtr = NULL; if (start < special) { - charsThisChunk = Tk_MeasureChars(tkfont, start, special - start, + bytesThisChunk = Tk_MeasureChars(tkfont, start, special - start, wrapLength - curX, flags, &newX); newX += curX; flags &= ~TK_AT_LEAST_ONE; - if (charsThisChunk > 0) { + if (bytesThisChunk > 0) { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, - charsThisChunk, curX, newX, baseline); + bytesThisChunk, curX, newX, baseline); - start += charsThisChunk; + start += bytesThisChunk; curX = newX; } } @@ -1482,6 +1899,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, if ((start == special) && (special < end)) { /* * Handle the special character. + * + * INTL: Special will be pointing at a 7-bit character so we + * can safely treat it as a single byte. */ chunkPtr = NULL; @@ -1515,7 +1935,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * Consume all extra spaces at end of line. */ - while ((start < end) && isspace(UCHAR(*start))) { + while ((start < end) && isspace(UCHAR(*start))) { /* INTL: ISO space */ if (!(flags & TK_IGNORE_NEWLINES)) { if ((*start == '\n') || (*start == '\r')) { break; @@ -1529,15 +1949,21 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, start++; } if (chunkPtr != NULL) { + CONST char *end; + /* * Append all the extra spaces on this line to the end of the - * last text chunk. + * last text chunk. This is a little tricky because we are + * switching back and forth between characters and bytes. */ - charsThisChunk = start - (chunkPtr->start + chunkPtr->numChars); - if (charsThisChunk > 0) { - chunkPtr->numChars += Tk_MeasureChars(tkfont, - chunkPtr->start + chunkPtr->numChars, charsThisChunk, - 0, 0, &chunkPtr->totalWidth); + + end = chunkPtr->start + chunkPtr->numBytes; + bytesThisChunk = start - end; + if (bytesThisChunk > 0) { + bytesThisChunk = Tk_MeasureChars(tkfont, end, bytesThisChunk, + -1, 0, &chunkPtr->totalWidth); + chunkPtr->numBytes += bytesThisChunk; + chunkPtr->numChars += Tcl_NumUtfChars(end, bytesThisChunk); chunkPtr->totalWidth += curX; } } @@ -1559,19 +1985,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * can be centered or right justified, if necessary. */ - if (curLine >= maxLines) { - int *newLengths; - - newLengths = (int *) ckalloc(2 * maxLines * sizeof(int)); - memcpy((void *) newLengths, lineLengths, maxLines * sizeof(int)); - if (lineLengths != staticLineLengths) { - ckfree((char *) lineLengths); - } - lineLengths = newLengths; - maxLines *= 2; - } - lineLengths[curLine] = curX; - curLine++; + Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); curX = 0; baseline += height; @@ -1588,34 +2002,11 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, 0, curX, 1000000000, baseline); chunkPtr->numDisplayChars = -1; + Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); baseline += height; } } - /* - * Using maximum line length, shift all the chunks so that the lines are - * all justified correctly. - */ - - curLine = 0; - chunkPtr = layoutPtr->chunks; - y = chunkPtr->y; - for (n = 0; n < layoutPtr->numChunks; n++) { - int extra; - - if (chunkPtr->y != y) { - curLine++; - y = chunkPtr->y; - } - extra = maxWidth - lineLengths[curLine]; - if (justify == TK_JUSTIFY_CENTER) { - chunkPtr->x += extra / 2; - } else if (justify == TK_JUSTIFY_RIGHT) { - chunkPtr->x += extra; - } - chunkPtr++; - } - layoutPtr->width = maxWidth; layoutHeight = baseline - fmPtr->ascent; if (layoutPtr->numChunks == 0) { @@ -1629,12 +2020,38 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, layoutPtr->numChunks = 1; layoutPtr->chunks[0].start = string; + layoutPtr->chunks[0].numBytes = 0; layoutPtr->chunks[0].numChars = 0; layoutPtr->chunks[0].numDisplayChars = -1; layoutPtr->chunks[0].x = 0; layoutPtr->chunks[0].y = fmPtr->ascent; layoutPtr->chunks[0].totalWidth = 0; layoutPtr->chunks[0].displayWidth = 0; + } else { + /* + * Using maximum line length, shift all the chunks so that the lines + * are all justified correctly. + */ + + curLine = 0; + chunkPtr = layoutPtr->chunks; + y = chunkPtr->y; + lineLengths = (int *) Tcl_DStringValue(&lineBuffer); + for (n = 0; n < layoutPtr->numChunks; n++) { + int extra; + + if (chunkPtr->y != y) { + curLine++; + y = chunkPtr->y; + } + extra = maxWidth - lineLengths[curLine]; + if (justify == TK_JUSTIFY_CENTER) { + chunkPtr->x += extra / 2; + } else if (justify == TK_JUSTIFY_RIGHT) { + chunkPtr->x += extra; + } + chunkPtr++; + } } if (widthPtr != NULL) { @@ -1643,9 +2060,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, if (heightPtr != NULL) { *heightPtr = layoutHeight; } - if (lineLengths != staticLineLengths) { - ckfree((char *) lineLengths); - } + Tcl_DStringFree(&lineBuffer); return (Tk_TextLayout) layoutPtr; } @@ -1718,6 +2133,8 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) { TextLayout *layoutPtr; int i, numDisplayChars, drawX; + CONST char *firstByte; + CONST char *lastByte; LayoutChunk *chunkPtr; layoutPtr = (TextLayout *) layout; @@ -1735,15 +2152,18 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) if (firstChar <= 0) { drawX = 0; firstChar = 0; + firstByte = chunkPtr->start; } else { - Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start, firstChar, - 0, 0, &drawX); + firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar); + Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start, + firstByte - chunkPtr->start, -1, 0, &drawX); } if (lastChar < numDisplayChars) { numDisplayChars = lastChar; } + lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars); Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, - chunkPtr->start + firstChar, numDisplayChars - firstChar, + firstByte, lastByte - firstByte, x + chunkPtr->x + drawX, y + chunkPtr->y); } firstChar -= chunkPtr->numChars; @@ -1849,7 +2269,7 @@ Tk_PointToChar(layout, x, y) TextLayout *layoutPtr; LayoutChunk *chunkPtr, *lastPtr; TkFont *fontPtr; - int i, n, dummy, baseline, pos; + int i, n, dummy, baseline, pos, numChars; if (y < 0) { /* @@ -1867,6 +2287,7 @@ Tk_PointToChar(layout, x, y) layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; lastPtr = chunkPtr = layoutPtr->chunks; + numChars = 0; for (i = 0; i < layoutPtr->numChunks; i++) { baseline = chunkPtr->y; if (y < baseline + fontPtr->fm.descent) { @@ -1876,7 +2297,7 @@ Tk_PointToChar(layout, x, y) * the index of the first character on this line. */ - return chunkPtr->start - layoutPtr->string; + return numChars; } if (x >= layoutPtr->width) { /* @@ -1907,13 +2328,14 @@ Tk_PointToChar(layout, x, y) * tab or newline char. */ - return chunkPtr->start - layoutPtr->string; + return numChars; } n = Tk_MeasureChars((Tk_Font) fontPtr, chunkPtr->start, - chunkPtr->numChars, x + 1 - chunkPtr->x, - TK_PARTIAL_OK, &dummy); - return (chunkPtr->start + n - 1) - layoutPtr->string; + chunkPtr->numBytes, x - chunkPtr->x, + 0, &dummy); + return numChars + Tcl_NumUtfChars(chunkPtr->start, n); } + numChars += chunkPtr->numChars; lastPtr = chunkPtr; chunkPtr++; i++; @@ -1925,12 +2347,13 @@ Tk_PointToChar(layout, x, y) * chunk on this line. */ - pos = (lastPtr->start + lastPtr->numChars) - layoutPtr->string; + pos = numChars; if (i < layoutPtr->numChunks) { pos--; } return pos; } + numChars += chunkPtr->numChars; lastPtr = chunkPtr; chunkPtr++; } @@ -1997,6 +2420,7 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) int i, x, w; Tk_Font tkfont; TkFont *fontPtr; + CONST char *end; if (index < 0) { return 0; @@ -2015,12 +2439,15 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) goto check; } } else if (index < chunkPtr->numChars) { + end = Tcl_UtfAtIndex(chunkPtr->start, index); if (xPtr != NULL) { - Tk_MeasureChars(tkfont, chunkPtr->start, index, 0, 0, &x); + Tk_MeasureChars(tkfont, chunkPtr->start, + end - chunkPtr->start, -1, 0, &x); x += chunkPtr->x; } if (widthPtr != NULL) { - Tk_MeasureChars(tkfont, chunkPtr->start + index, 1, 0, 0, &w); + Tk_MeasureChars(tkfont, end, Tcl_UtfNext(end) - end, + -1, 0, &w); } goto check; } @@ -2276,7 +2703,7 @@ Tk_IntersectTextLayout(layout, x, y, width, height) * location of the baseline for the string. * * Results: - * Interp->result is modified to hold the Postscript code that + * The interp's result is modified to hold the Postscript code that * will render the text layout. * * Side effects: @@ -2294,6 +2721,8 @@ Tk_TextLayoutToPostscript(interp, layout) char buf[MAXUSE+10]; LayoutChunk *chunkPtr; int i, j, used, c, baseline; + Tcl_UniChar ch; + CONST char *p; TextLayout *layoutPtr; layoutPtr = (TextLayout *) layout; @@ -2314,8 +2743,16 @@ Tk_TextLayoutToPostscript(interp, layout) buf[used++] = 't'; } } else { + p = chunkPtr->start; for (j = 0; j < chunkPtr->numDisplayChars; j++) { - c = UCHAR(chunkPtr->start[j]); + /* + * INTL: For now we just treat the characters as binary + * data and display the lower byte. Eventually this should + * be revised to handle international postscript fonts. + */ + + p += Tcl_UtfToUniChar(p, &ch); + c = UCHAR(ch & 0xff); if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) || (c >= UCHAR(0x7f))) { /* @@ -2359,36 +2796,6 @@ Tk_TextLayoutToPostscript(interp, layout) /* *--------------------------------------------------------------------------- * - * TkInitFontAttributes -- - * - * Initialize the font attributes structure to contain sensible - * values. This must be called before using any other font - * attributes functions. - * - * Results: - * None. - * - * Side effects. - * None. - * - *--------------------------------------------------------------------------- - */ - -void -TkInitFontAttributes(faPtr) - TkFontAttributes *faPtr; /* The attributes structure to initialize. */ -{ - faPtr->family = NULL; - faPtr->pointsize = 0; - faPtr->weight = TK_FW_NORMAL; - faPtr->slant = TK_FS_ROMAN; - faPtr->underline = 0; - faPtr->overstrike = 0; -} - -/* - *--------------------------------------------------------------------------- - * * ConfigAttributesObj -- * * Process command line options to fill in fields of a properly @@ -2419,68 +2826,74 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) * be properly initialized. */ { int i, n, index; - Tcl_Obj *value; - char *option, *string; + Tcl_Obj *optionPtr, *valuePtr; + char *value; - if (objc & 1) { - string = Tcl_GetStringFromObj(objv[objc - 1], NULL); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "missing value for \"", - string, "\" option", (char *) NULL); - return TCL_ERROR; - } - for (i = 0; i < objc; i += 2) { - option = Tcl_GetStringFromObj(objv[i], NULL); - value = objv[i + 1]; + optionPtr = objv[i]; + valuePtr = objv[i + 1]; - if (Tcl_GetIndexFromObj(interp, objv[i], fontOpt, "option", 1, + if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1, &index) != TCL_OK) { return TCL_ERROR; } + if (objc & 1) { + /* + * This test occurs after Tcl_GetIndexFromObj() so that + * "font create xyz -xyz" will return the error message + * that "-xyz" is a bad option, rather than that the value + * for "-xyz" is missing. + */ + + Tcl_AppendResult(interp, "value for \"", + Tcl_GetString(optionPtr), "\" option missing", + (char *) NULL); + return TCL_ERROR; + } + switch (index) { - case FONT_FAMILY: - string = Tcl_GetStringFromObj(value, NULL); - faPtr->family = Tk_GetUid(string); + case FONT_FAMILY: { + value = Tcl_GetString(valuePtr); + faPtr->family = Tk_GetUid(value); break; - - case FONT_SIZE: - if (Tcl_GetIntFromObj(interp, value, &n) != TCL_OK) { + } + case FONT_SIZE: { + if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { return TCL_ERROR; } - faPtr->pointsize = n; + faPtr->size = n; break; - - case FONT_WEIGHT: - string = Tcl_GetStringFromObj(value, NULL); - n = TkFindStateNum(interp, option, weightMap, string); + } + case FONT_WEIGHT: { + n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); if (n == TK_FW_UNKNOWN) { return TCL_ERROR; } faPtr->weight = n; break; - - case FONT_SLANT: - string = Tcl_GetStringFromObj(value, NULL); - n = TkFindStateNum(interp, option, slantMap, string); + } + case FONT_SLANT: { + n = TkFindStateNumObj(interp, optionPtr, slantMap, valuePtr); if (n == TK_FS_UNKNOWN) { return TCL_ERROR; } faPtr->slant = n; break; - - case FONT_UNDERLINE: - if (Tcl_GetBooleanFromObj(interp, value, &n) != TCL_OK) { + } + case FONT_UNDERLINE: { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { return TCL_ERROR; } faPtr->underline = n; break; - - case FONT_OVERSTRIKE: - if (Tcl_GetBooleanFromObj(interp, value, &n) != TCL_OK) { + } + case FONT_OVERSTRIKE: { + if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { return TCL_ERROR; } faPtr->overstrike = n; break; + } } } return TCL_OK; @@ -2515,18 +2928,19 @@ GetAttributeInfoObj(interp, faPtr, objPtr) CONST TkFontAttributes *faPtr; /* The font attributes to inspect. */ Tcl_Obj *objPtr; /* If non-NULL, indicates the single * option whose value is to be - * returned. Otherwise - * information is returned for - * all options. */ + * returned. Otherwise information is + * returned for all options. */ { - int i, index, start, end, num; + int i, index, start, end; char *str; - Tcl_Obj *newPtr; + Tcl_Obj *optionPtr, *valuePtr, *resultPtr; + + resultPtr = Tcl_GetObjResult(interp); start = 0; end = FONT_NUMFIELDS; if (objPtr != NULL) { - if (Tcl_GetIndexFromObj(interp, objPtr, fontOpt, "option", 1, + if (Tcl_GetIndexFromObj(interp, objPtr, fontOpt, "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } @@ -2534,55 +2948,43 @@ GetAttributeInfoObj(interp, faPtr, objPtr) end = index + 1; } + valuePtr = NULL; for (i = start; i < end; i++) { - str = NULL; - num = 0; /* Needed only to prevent compiler - * warning. */ switch (i) { case FONT_FAMILY: str = faPtr->family; - if (str == NULL) { - str = ""; - } + valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1)); break; case FONT_SIZE: - num = faPtr->pointsize; + valuePtr = Tcl_NewIntObj(faPtr->size); break; case FONT_WEIGHT: str = TkFindStateString(weightMap, faPtr->weight); + valuePtr = Tcl_NewStringObj(str, -1); break; case FONT_SLANT: str = TkFindStateString(slantMap, faPtr->slant); + valuePtr = Tcl_NewStringObj(str, -1); break; case FONT_UNDERLINE: - num = faPtr->underline; + valuePtr = Tcl_NewBooleanObj(faPtr->underline); break; case FONT_OVERSTRIKE: - num = faPtr->overstrike; + valuePtr = Tcl_NewBooleanObj(faPtr->overstrike); break; } - if (objPtr == NULL) { - Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), - Tcl_NewStringObj(fontOpt[i], -1)); - if (str != NULL) { - newPtr = Tcl_NewStringObj(str, -1); - } else { - newPtr = Tcl_NewIntObj(num); - } - Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), - newPtr); - } else { - if (str != NULL) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), str, -1); - } else { - Tcl_SetIntObj(Tcl_GetObjResult(interp), num); - } + if (objPtr != NULL) { + Tcl_SetObjResult(interp, valuePtr); + return TCL_OK; } + optionPtr = Tcl_NewStringObj(fontOpt[i], -1); + Tcl_ListObjAppendElement(NULL, resultPtr, optionPtr); + Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr); } return TCL_OK; } @@ -2597,7 +2999,7 @@ GetAttributeInfoObj(interp, faPtr, objPtr) * * The string rep of the object can be one of the following forms: * XLFD (see X documentation) - * "Family [size [style] [style ...]]" + * "family [size] [style1 [style2 ...]" * "-option value [-option value ...]" * * Results: @@ -2614,20 +3016,25 @@ GetAttributeInfoObj(interp, faPtr, objPtr) static int ParseFontNameObj(interp, tkwin, objPtr, faPtr) - Tcl_Interp *interp; /* Interp for error return. */ + Tcl_Interp *interp; /* Interp for error return. Must not be + * NULL. */ Tk_Window tkwin; /* For display on which font is used. */ Tcl_Obj *objPtr; /* Parseable font description object. */ - TkFontAttributes *faPtr; /* Font attributes structure whose fields - * are to be modified. Structure must already - * be properly initialized. */ + TkFontAttributes *faPtr; /* Filled with attributes parsed from font + * name. Any attributes that were not + * specified in font name are filled with + * default values. */ { char *dash; int objc, result, i, n; Tcl_Obj **objv; - TkXLFDAttributes xa; + Tcl_Obj *resultPtr; char *string; - string = Tcl_GetStringFromObj(objPtr, NULL); + TkInitFontAttributes(faPtr); + resultPtr = Tcl_GetObjResult(interp); + + string = Tcl_GetString(objPtr); if (*string == '-') { /* * This may be an XLFD or an "-option value" string. @@ -2640,7 +3047,8 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) goto xlfd; } dash = strchr(string + 1, '-'); - if ((dash != NULL) && (!isspace(UCHAR(dash[-1])))) { + if ((dash != NULL) + && (!isspace(UCHAR(dash[-1])))) { /* INTL: ISO space */ goto xlfd; } @@ -2653,15 +3061,16 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) if (*string == '*') { /* - * This appears to be an XLFD. + * This is appears to be an XLFD. Under Unix, all valid XLFDs were + * already handled by TkpGetNativeFont. If we are here, either we + * have something that initially looks like an XLFD but isn't or we + * have encountered an XLFD on Windows or Mac. */ xlfd: - xa.fa = *faPtr; - result = TkParseXLFD(string, &xa); + result = TkFontParseXLFD(string, faPtr, NULL); if (result == TCL_OK) { - *faPtr = xa.fa; - return result; + return TCL_OK; } } @@ -2670,21 +3079,19 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) * "font size style" list. */ - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; - } - if (objc < 1) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "font \"", string, - "\" doesn't exist", (char *) NULL); + if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) + || (objc < 1)) { + Tcl_AppendResult(interp, "font \"", string, "\" doesn't exist", + (char *) NULL); return TCL_ERROR; } - faPtr->family = Tk_GetUid(Tcl_GetStringFromObj(objv[0], NULL)); + faPtr->family = Tk_GetUid(Tcl_GetString(objv[0])); if (objc > 1) { if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) { return TCL_ERROR; } - faPtr->pointsize = n; + faPtr->size = n; } i = 2; @@ -2695,23 +3102,22 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) i = 0; } for ( ; i < objc; i++) { - string = Tcl_GetStringFromObj(objv[i], NULL); - n = TkFindStateNum(NULL, NULL, weightMap, string); + n = TkFindStateNumObj(NULL, NULL, weightMap, objv[i]); if (n != TK_FW_UNKNOWN) { faPtr->weight = n; continue; } - n = TkFindStateNum(NULL, NULL, slantMap, string); + n = TkFindStateNumObj(NULL, NULL, slantMap, objv[i]); if (n != TK_FS_UNKNOWN) { faPtr->slant = n; continue; } - n = TkFindStateNum(NULL, NULL, underlineMap, string); + n = TkFindStateNumObj(NULL, NULL, underlineMap, objv[i]); if (n != 0) { faPtr->underline = n; continue; } - n = TkFindStateNum(NULL, NULL, overstrikeMap, string); + n = TkFindStateNumObj(NULL, NULL, overstrikeMap, objv[i]); if (n != 0) { faPtr->overstrike = n; continue; @@ -2721,9 +3127,8 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) * Unknown style. */ - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "unknown font style \"", string, "\"", - (char *) NULL); + Tcl_AppendResult(interp, "unknown font style \"", + Tcl_GetString(objv[i]), "\"", (char *) NULL); return TCL_ERROR; } return TCL_OK; @@ -2732,7 +3137,69 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) /* *--------------------------------------------------------------------------- * - * TkParseXLFD -- + * NewChunk -- + * + * Helper function for Tk_ComputeTextLayout(). Encapsulates a + * measured set of characters in a chunk that can be quickly + * drawn. + * + * Results: + * A pointer to the new chunk in the text layout. + * + * Side effects: + * The text layout is reallocated to hold more chunks as necessary. + * + * Currently, Tk_ComputeTextLayout() stores contiguous ranges of + * "normal" characters in a chunk, along with individual tab + * and newline chars in their own chunks. All characters in the + * text layout are accounted for. + * + *--------------------------------------------------------------------------- + */ +static LayoutChunk * +NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y) + TextLayout **layoutPtrPtr; + int *maxPtr; + CONST char *start; + int numBytes; + int curX; + int newX; + int y; +{ + TextLayout *layoutPtr; + LayoutChunk *chunkPtr; + int maxChunks, numChars; + size_t s; + + layoutPtr = *layoutPtrPtr; + maxChunks = *maxPtr; + if (layoutPtr->numChunks == maxChunks) { + maxChunks *= 2; + s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk)); + layoutPtr = (TextLayout *) ckrealloc((char *) layoutPtr, s); + + *layoutPtrPtr = layoutPtr; + *maxPtr = maxChunks; + } + numChars = Tcl_NumUtfChars(start, numBytes); + chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks]; + chunkPtr->start = start; + chunkPtr->numBytes = numBytes; + chunkPtr->numChars = numChars; + chunkPtr->numDisplayChars = numChars; + chunkPtr->x = curX; + chunkPtr->y = y; + chunkPtr->totalWidth = newX - curX; + chunkPtr->displayWidth = newX - curX; + layoutPtr->numChunks++; + + return chunkPtr; +} + +/* + *--------------------------------------------------------------------------- + * + * TkFontParseXLFD -- * * Break up a fully specified XLFD into a set of font attributes. * @@ -2748,18 +3215,31 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) */ int -TkParseXLFD(string, xaPtr) +TkFontParseXLFD(string, faPtr, xaPtr) CONST char *string; /* Parseable font description string. */ - TkXLFDAttributes *xaPtr; /* XLFD attributes structure whose fields - * are to be modified. Structure must already - * be properly initialized. */ + TkFontAttributes *faPtr; /* Filled with attributes parsed from font + * name. Any attributes that were not + * specified in font name are filled with + * default values. */ + TkXLFDAttributes *xaPtr; /* Filled with X-specific attributes parsed + * from font name. Any attributes that were + * not specified in font name are filled with + * default values. May be NULL if such + * information is not desired. */ { char *src; CONST char *str; int i, j; char *field[XLFD_NUMFIELDS + 2]; Tcl_DString ds; + TkXLFDAttributes xa; + if (xaPtr == NULL) { + xaPtr = &xa; + } + TkInitFontAttributes(faPtr); + TkInitXLFDAttributes(xaPtr); + memset(field, '\0', sizeof(field)); str = string; @@ -2773,27 +3253,32 @@ TkParseXLFD(string, xaPtr) field[0] = src; for (i = 0; *src != '\0'; src++) { - if (isupper(UCHAR(*src))) { - *src = tolower(UCHAR(*src)); + if (!(*src & 0x90) + && isupper(UCHAR(*src))) { /* INTL: 7-bit ISO only. */ + *src = tolower(UCHAR(*src)); /* INTL: 7-bit ISO only. */ } if (*src == '-') { i++; - if (i > XLFD_NUMFIELDS) { - break; + if (i == XLFD_NUMFIELDS) { + continue; } *src = '\0'; field[i] = src + 1; + if (i > XLFD_NUMFIELDS) { + break; + } } } /* - * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common, + * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common, * but it is (strictly) malformed, because the first * is eliding both * the Setwidth and the Addstyle fields. If the Addstyle field is a * number, then assume the above incorrect form was used and shift all - * the rest of the fields up by one, so the number gets interpreted + * the rest of the fields right by one, so the number gets interpreted * as a pixelsize. This fix is so that we don't get a million reports - * that "it works under X, but gives a syntax error under Windows". + * that "it works under X (as a native font name), but gives a syntax + * error under Windows (as a parsed set of attributes)". */ if ((i > XLFD_ADD_STYLE) && (FieldSpecified(field[XLFD_ADD_STYLE]))) { @@ -2820,19 +3305,19 @@ TkParseXLFD(string, xaPtr) } if (FieldSpecified(field[XLFD_FAMILY])) { - xaPtr->fa.family = Tk_GetUid(field[XLFD_FAMILY]); + faPtr->family = Tk_GetUid(field[XLFD_FAMILY]); } if (FieldSpecified(field[XLFD_WEIGHT])) { - xaPtr->fa.weight = TkFindStateNum(NULL, NULL, xlfdWeightMap, + faPtr->weight = TkFindStateNum(NULL, NULL, xlfdWeightMap, field[XLFD_WEIGHT]); } if (FieldSpecified(field[XLFD_SLANT])) { xaPtr->slant = TkFindStateNum(NULL, NULL, xlfdSlantMap, field[XLFD_SLANT]); if (xaPtr->slant == TK_FS_ROMAN) { - xaPtr->fa.slant = TK_FS_ROMAN; + faPtr->slant = TK_FS_ROMAN; } else { - xaPtr->fa.slant = TK_FS_ITALIC; + faPtr->slant = TK_FS_ITALIC; } } if (FieldSpecified(field[XLFD_SETWIDTH])) { @@ -2843,9 +3328,12 @@ TkParseXLFD(string, xaPtr) /* XLFD_ADD_STYLE ignored. */ /* - * Pointsize in tenths of a point, but treat it as tenths of a pixel. + * Pointsize in tenths of a point, but treat it as tenths of a pixel + * for historical compatibility. */ + faPtr->size = 12; + if (FieldSpecified(field[XLFD_POINT_SIZE])) { if (field[XLFD_POINT_SIZE][0] == '[') { /* @@ -2858,10 +3346,10 @@ TkParseXLFD(string, xaPtr) * the purpose of, so I ignore them. */ - xaPtr->fa.pointsize = atoi(field[XLFD_POINT_SIZE] + 1); + faPtr->size = atoi(field[XLFD_POINT_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE], - &xaPtr->fa.pointsize) == TCL_OK) { - xaPtr->fa.pointsize /= 10; + &faPtr->size) == TCL_OK) { + faPtr->size /= 10; } else { return TCL_ERROR; } @@ -2883,14 +3371,14 @@ TkParseXLFD(string, xaPtr) * the purpose of, so I ignore them. */ - xaPtr->fa.pointsize = atoi(field[XLFD_PIXEL_SIZE] + 1); + faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], - &xaPtr->fa.pointsize) != TCL_OK) { + &faPtr->size) != TCL_OK) { return TCL_ERROR; } } - xaPtr->fa.pointsize = -xaPtr->fa.pointsize; + faPtr->size = -faPtr->size; /* XLFD_RESOLUTION_X ignored. */ @@ -2900,14 +3388,11 @@ TkParseXLFD(string, xaPtr) /* XLFD_AVERAGE_WIDTH ignored. */ - if (FieldSpecified(field[XLFD_REGISTRY])) { - xaPtr->charset = TkFindStateNum(NULL, NULL, xlfdCharsetMap, - field[XLFD_REGISTRY]); - } - if (FieldSpecified(field[XLFD_ENCODING])) { - xaPtr->encoding = atoi(field[XLFD_ENCODING]); + if (FieldSpecified(field[XLFD_CHARSET])) { + xaPtr->charset = Tk_GetUid(field[XLFD_CHARSET]); + } else { + xaPtr->charset = Tk_GetUid("iso8859-1"); } - Tcl_DStringFree(&ds); return TCL_OK; } @@ -2949,60 +3434,223 @@ FieldSpecified(field) /* *--------------------------------------------------------------------------- * - * NewChunk -- + * TkFontGetPixels -- * - * Helper function for Tk_ComputeTextLayout(). Encapsulates a - * measured set of characters in a chunk that can be quickly - * drawn. + * Given a font size specification (as described in the TkFontAttributes + * structure) return the number of pixels it represents. * * Results: - * A pointer to the new chunk in the text layout. + * As above. * * Side effects: - * The text layout is reallocated to hold more chunks as necessary. + * None. * - * Currently, Tk_ComputeTextLayout() stores contiguous ranges of - * "normal" characters in a chunk, along with individual tab - * and newline chars in their own chunks. All characters in the - * text layout are accounted for. + *--------------------------------------------------------------------------- + */ + +int +TkFontGetPixels(tkwin, size) + Tk_Window tkwin; /* For point->pixel conversion factor. */ + int size; /* Font size. */ +{ + double d; + + if (size < 0) { + return -size; + } + + d = size * 25.4 / 72.0; + d *= WidthOfScreen(Tk_Screen(tkwin)); + d /= WidthMMOfScreen(Tk_Screen(tkwin)); + return (int) (d + 0.5); +} + +/* + *--------------------------------------------------------------------------- + * + * TkFontGetPoints -- + * + * Given a font size specification (as described in the TkFontAttributes + * structure) return the number of points it represents. + * + * Results: + * As above. + * + * Side effects: + * None. * *--------------------------------------------------------------------------- */ -static LayoutChunk * -NewChunk(layoutPtrPtr, maxPtr, start, numChars, curX, newX, y) - TextLayout **layoutPtrPtr; - int *maxPtr; - CONST char *start; - int numChars; - int curX; - int newX; - int y; + +int +TkFontGetPoints(tkwin, size) + Tk_Window tkwin; /* For pixel->point conversion factor. */ + int size; /* Font size. */ { - TextLayout *layoutPtr; - LayoutChunk *chunkPtr; - int maxChunks; - size_t s; - - layoutPtr = *layoutPtrPtr; - maxChunks = *maxPtr; - if (layoutPtr->numChunks == maxChunks) { - maxChunks *= 2; - s = sizeof(TextLayout) + ((maxChunks - 1) * sizeof(LayoutChunk)); - layoutPtr = (TextLayout *) ckrealloc((char *) layoutPtr, s); + double d; - *layoutPtrPtr = layoutPtr; - *maxPtr = maxChunks; + if (size >= 0) { + return size; } - chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks]; - chunkPtr->start = start; - chunkPtr->numChars = numChars; - chunkPtr->numDisplayChars = numChars; - chunkPtr->x = curX; - chunkPtr->y = y; - chunkPtr->totalWidth = newX - curX; - chunkPtr->displayWidth = newX - curX; - layoutPtr->numChunks++; - return chunkPtr; + d = -size * 72.0 / 25.4; + d *= WidthMMOfScreen(Tk_Screen(tkwin)); + d /= WidthOfScreen(Tk_Screen(tkwin)); + return (int) (d + 0.5); } + +/* + *------------------------------------------------------------------------- + * + * TkFontGetAliasList -- + * + * Given a font name, find the list of all aliases for that font + * name. One of the names in this list will probably be the name + * that this platform expects when asking for the font. + * + * Results: + * As above. The return value is NULL if the font name has no + * aliases. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +char ** +TkFontGetAliasList(faceName) + CONST char *faceName; /* Font name to test for aliases. */ +{ + int i, j; + for (i = 0; fontAliases[i] != NULL; i++) { + for (j = 0; fontAliases[i][j] != NULL; j++) { + if (strcasecmp(faceName, fontAliases[i][j]) == 0) { + return fontAliases[i]; + } + } + } + return NULL; +} + +/* + *------------------------------------------------------------------------- + * + * TkFontGetFallbacks -- + * + * Get the list of font fallbacks that the platform-specific code + * can use to try to find the closest matching font the name + * requested. + * + * Results: + * As above. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +char *** +TkFontGetFallbacks() +{ + return fontFallbacks; +} + +/* + *------------------------------------------------------------------------- + * + * TkFontGetGlobalClass -- + * + * Get the list of fonts to try if the requested font name does not + * exist and no fallbacks for that font name could be used either. + * The names in this list are considered preferred over all the other + * font names in the system when looking for a last-ditch fallback. + * + * Results: + * As above. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +char ** +TkFontGetGlobalClass() +{ + return globalFontClass; +} + +/* + *------------------------------------------------------------------------- + * + * TkFontGetSymbolClass -- + * + * Get the list of fonts that are symbolic; used if the operating + * system cannot apriori identify symbolic fonts on its own. + * + * Results: + * As above. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +char ** +TkFontGetSymbolClass() +{ + return symbolClass; +} + +/* + *---------------------------------------------------------------------- + * + * TkDebugFont -- + * + * This procedure returns debugging information about a font. + * + * Results: + * The return value is a list with one sublist for each TkFont + * corresponding to "name". Each sublist has two elements that + * contain the resourceRefCount and objRefCount fields from the + * TkFont structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TkDebugFont(tkwin, name) + Tk_Window tkwin; /* The window in which the font will be + * used (not currently used). */ + char *name; /* Name of the desired color. */ +{ + TkFont *fontPtr; + Tcl_HashEntry *hashPtr; + Tcl_Obj *resultPtr, *objPtr; + + resultPtr = Tcl_NewObj(); + hashPtr = Tcl_FindHashEntry( + &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name); + if (hashPtr != NULL) { + fontPtr = (TkFont *) Tcl_GetHashValue(hashPtr); + if (fontPtr == NULL) { + panic("TkDebugFont found empty hash table entry"); + } + for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) { + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(fontPtr->resourceRefCount)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(fontPtr->objRefCount)); + Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); + } + } + return resultPtr; +} diff --git a/generic/tkFont.h b/generic/tkFont.h index e2a7e04..cc57167 100644 --- a/generic/tkFont.h +++ b/generic/tkFont.h @@ -5,12 +5,12 @@ * specific parts of the font package. This information is not * visible outside of the font package. * - * Copyright (c) 1996 Sun Microsystems, Inc. + * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFont.h,v 1.4 1998/09/14 18:23:10 stanton Exp $ + * RCS: @(#) $Id: tkFont.h,v 1.5 1999/04/16 01:51:14 stanton Exp $ */ #ifndef _TKFONT @@ -28,8 +28,9 @@ */ typedef struct TkFontAttributes { - Tk_Uid family; /* Font family. The most important field. */ - int pointsize; /* Pointsize of font, 0 for default size, or + Tk_Uid family; /* Font family, or NULL to represent + * plaform-specific default system font. */ + int size; /* Pointsize of font, 0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ @@ -91,13 +92,25 @@ typedef struct TkFont { * Fields used and maintained exclusively by generic code. */ - int refCount; /* Number of users of the TkFont. */ + int resourceRefCount; /* Number of active uses of this font (each + * active use corresponds to a call to + * Tk_AllocFontFromTable or Tk_GetFont). + * If this count is 0, then this TkFont + * structure is no longer valid and it isn't + * present in a hash table: it is being + * kept around only because there are objects + * referring to it. The structure is freed + * when resourceRefCount and objRefCount + * are both 0. */ + int objRefCount; /* The number of Tcl objects that reference + * this structure. */ Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure, * used when deleting it. */ Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that * corresponds to the named font that the * tkfont was based on, or NULL if the tkfont * was not based on a named font. */ + Screen *screen; /* The screen where this font is valid. */ int tabWidth; /* Width of tabs in this font (pixels). */ int underlinePos; /* Offset from baseline to origin of * underline bar (used for drawing underlines @@ -106,7 +119,7 @@ typedef struct TkFont { * underlines on a non-underlined font). */ /* - * Fields in the generic font structure that are filled in by + * Fields used in the generic code that are filled in by * platform-specific code. */ @@ -121,6 +134,11 @@ typedef struct TkFont { * that was used to create this font. */ TkFontMetrics fm; /* Font metrics determined when font was * created. */ + struct TkFont *nextPtr; /* Points to the next TkFont structure with + * the same name. All fonts with the + * same name (but different displays) are + * chained together off a single entry in + * a hash table. */ } TkFont; /* @@ -130,16 +148,12 @@ typedef struct TkFont { */ typedef struct TkXLFDAttributes { - TkFontAttributes fa; /* Standard set of font attributes. */ Tk_Uid foundry; /* The foundry of the font. */ int slant; /* The tristate value for the slant, which * is significant under X. */ int setwidth; /* The proportionate width, see below for * definition. */ - int charset; /* The character set encoding (the glyph - * family), see below for definition. */ - int encoding; /* Variations within a charset for the - * glyphs above character 127. */ + Tk_Uid charset; /* The actual charset string. */ } TkXLFDAttributes; /* @@ -155,15 +169,6 @@ typedef struct TkXLFDAttributes { * stored in the setwidth field. */ /* - * Possible values for the "charset" field in a TkXLFDAttributes structure. - * The charset is the set of glyphs that are used in the font. - */ - -#define TK_CS_NORMAL 0 -#define TK_CS_SYMBOL 1 -#define TK_CS_OTHER 2 - -/* * The following defines specify the meaning of the fields in a fully * qualified XLFD. */ @@ -180,28 +185,33 @@ typedef struct TkXLFDAttributes { #define XLFD_RESOLUTION_Y 9 #define XLFD_SPACING 10 #define XLFD_AVERAGE_WIDTH 11 -#define XLFD_REGISTRY 12 -#define XLFD_ENCODING 13 -#define XLFD_NUMFIELDS 14 /* Number of fields in XLFD. */ +#define XLFD_CHARSET 12 +#define XLFD_NUMFIELDS 13 /* Number of fields in XLFD. */ /* - * Exported from generic code to platform-specific code. + * Low-level API exported by generic code to platform-specific code. */ -EXTERN int TkCreateNamedFont _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, CONST char *name, - TkFontAttributes *faPtr)); -EXTERN void TkInitFontAttributes _ANSI_ARGS_(( - TkFontAttributes *faPtr)); -EXTERN int TkParseXLFD _ANSI_ARGS_((CONST char *string, - TkXLFDAttributes *xaPtr)); +#define TkInitFontAttributes(fa) memset((fa), 0, sizeof(TkFontAttributes)); +#define TkInitXLFDAttributes(xa) memset((xa), 0, sizeof(TkXLFDAttributes)); + +EXTERN int TkFontParseXLFD _ANSI_ARGS_((CONST char *string, + TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr)); +EXTERN char ** TkFontGetAliasList _ANSI_ARGS_((CONST char *faceName)); +EXTERN char *** TkFontGetFallbacks _ANSI_ARGS_((void)); +EXTERN int TkFontGetPixels _ANSI_ARGS_((Tk_Window tkwin, + int size)); +EXTERN int TkFontGetPoints _ANSI_ARGS_((Tk_Window tkwin, + int size)); +EXTERN char ** TkFontGetGlobalClass _ANSI_ARGS_((void)); +EXTERN char ** TkFontGetSymbolClass _ANSI_ARGS_((void)); /* - * Common APIs exported to tkFont.c from all platform-specific - * implementations. + * Low-level API exported by platform-specific code to generic code. */ EXTERN void TkpDeleteFont _ANSI_ARGS_((TkFont *tkFontPtr)); +EXTERN void TkpFontPkgInit _ANSI_ARGS_((TkMainInfo *mainPtr)); EXTERN TkFont * TkpGetFontFromAttributes _ANSI_ARGS_(( TkFont *tkFontPtr, Tk_Window tkwin, CONST TkFontAttributes *faPtr)); diff --git a/generic/tkFrame.c b/generic/tkFrame.c index 18ce64f..9bdee9a 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.c @@ -7,12 +7,12 @@ * attributes. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFrame.c,v 1.2 1998/09/14 18:23:10 stanton Exp $ + * RCS: @(#) $Id: tkFrame.c,v 1.3 1999/04/16 01:51:14 stanton Exp $ */ #include "default.h" @@ -441,7 +441,7 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) if (toplevel) { Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr); } - interp->result = Tk_PathName(new); + Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC); return TCL_OK; error: @@ -597,7 +597,7 @@ DestroyFrame(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, diff --git a/generic/tkGC.c b/generic/tkGC.c index dd53e32..b719137 100644 --- a/generic/tkGC.c +++ b/generic/tkGC.c @@ -10,11 +10,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGC.c,v 1.2 1998/09/14 18:23:11 stanton Exp $ + * RCS: @(#) $Id: tkGC.c,v 1.3 1999/04/16 01:51:14 stanton Exp $ */ #include "tkPort.h" -#include "tk.h" +#include "tkInt.h" /* * One of the following data structures exists for each GC that is @@ -31,12 +31,6 @@ typedef struct { * this structure). */ } TkGC; -/* - * Hash table to map from a GC's values to a TkGC structure describing - * a GC with those values (used by Tk_GetGC). - */ - -static Tcl_HashTable valueTable; typedef struct { XGCValues values; /* Desired values for GC. */ Display *display; /* Display for which GC is valid. */ @@ -45,24 +39,10 @@ typedef struct { } ValueKey; /* - * Hash table for <display + GC> -> TkGC mapping. This table is used by - * Tk_FreeGC. - */ - -static Tcl_HashTable idTable; -typedef struct { - Display *display; /* Display for which GC was allocated. */ - GC gc; /* X's identifier for GC. */ -} IdKey; - -static int initialized = 0; /* 0 means static structures haven't been - * initialized yet. */ - -/* * Forward declarations for procedures defined in this file: */ -static void GCInit _ANSI_ARGS_((void)); +static void GCInit _ANSI_ARGS_((TkDisplay *dispPtr)); /* *---------------------------------------------------------------------- @@ -98,14 +78,14 @@ Tk_GetGC(tkwin, valueMask, valuePtr) * in valueMask. */ { ValueKey valueKey; - IdKey idKey; Tcl_HashEntry *valueHashPtr, *idHashPtr; register TkGC *gcPtr; int new; Drawable d, freeDrawable; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - GCInit(); + if (!dispPtr->gcInit) { + GCInit(dispPtr); } /* @@ -238,7 +218,8 @@ Tk_GetGC(tkwin, valueMask, valuePtr) valueKey.display = Tk_Display(tkwin); valueKey.screenNum = Tk_ScreenNumber(tkwin); valueKey.depth = Tk_Depth(tkwin); - valueHashPtr = Tcl_CreateHashEntry(&valueTable, (char *) &valueKey, &new); + valueHashPtr = Tcl_CreateHashEntry(&dispPtr->gcValueTable, + (char *) &valueKey, &new); if (!new) { gcPtr = (TkGC *) Tcl_GetHashValue(valueHashPtr); gcPtr->refCount++; @@ -275,9 +256,8 @@ Tk_GetGC(tkwin, valueMask, valuePtr) gcPtr->display = valueKey.display; gcPtr->refCount = 1; gcPtr->valueHashPtr = valueHashPtr; - idKey.display = valueKey.display; - idKey.gc = gcPtr->gc; - idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) &idKey, &new); + idHashPtr = Tcl_CreateHashEntry(&dispPtr->gcIdTable, + (char *) gcPtr->gc, &new); if (!new) { panic("GC already registered in Tk_GetGC"); } @@ -313,17 +293,15 @@ Tk_FreeGC(display, gc) Display *display; /* Display for which gc was allocated. */ GC gc; /* Graphics context to be released. */ { - IdKey idKey; Tcl_HashEntry *idHashPtr; register TkGC *gcPtr; + TkDisplay *dispPtr = TkGetDisplay(display); - if (!initialized) { + if (!dispPtr->gcInit) { panic("Tk_FreeGC called before Tk_GetGC"); } - idKey.display = display; - idKey.gc = gc; - idHashPtr = Tcl_FindHashEntry(&idTable, (char *) &idKey); + idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc); if (idHashPtr == NULL) { panic("Tk_FreeGC received unknown gc argument"); } @@ -355,9 +333,10 @@ Tk_FreeGC(display, gc) */ static void -GCInit() +GCInit(dispPtr) + TkDisplay *dispPtr; { - initialized = 1; - Tcl_InitHashTable(&valueTable, sizeof(ValueKey)/sizeof(int)); - Tcl_InitHashTable(&idTable, sizeof(IdKey)/sizeof(int)); + dispPtr->gcInit = 1; + Tcl_InitHashTable(&dispPtr->gcValueTable, sizeof(ValueKey)/sizeof(int)); + Tcl_InitHashTable(&dispPtr->gcIdTable, TCL_ONE_WORD_KEYS); } diff --git a/generic/tkGeometry.c b/generic/tkGeometry.c index 64f0b26..1851965 100644 --- a/generic/tkGeometry.c +++ b/generic/tkGeometry.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGeometry.c,v 1.2 1998/09/14 18:23:11 stanton Exp $ + * RCS: @(#) $Id: tkGeometry.c,v 1.3 1999/04/16 01:51:14 stanton Exp $ */ #include "tkPort.h" @@ -53,19 +53,6 @@ typedef struct MaintainMaster { } MaintainMaster; /* - * Hash table that maps from a master's Tk_Window token to a list of - * Maintains for that master: - */ - -static Tcl_HashTable maintainHashTable; - -/* - * Has maintainHashTable been initialized yet? - */ - -static int initialized = 0; - -/* * Prototypes for static procedures in this file: */ @@ -261,10 +248,11 @@ Tk_MaintainGeometry(slave, master, x, y, width, height) register MaintainSlave *slavePtr; int new, map; Tk_Window ancestor, parent; + TkDisplay *dispPtr = ((TkWindow *) master)->dispPtr; - if (!initialized) { - initialized = 1; - Tcl_InitHashTable(&maintainHashTable, TCL_ONE_WORD_KEYS); + if (!dispPtr->geomInit) { + dispPtr->geomInit = 1; + Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS); } /* @@ -273,7 +261,8 @@ Tk_MaintainGeometry(slave, master, x, y, width, height) */ parent = Tk_Parent(slave); - hPtr = Tcl_CreateHashEntry(&maintainHashTable, (char *) master, &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->maintainHashTable, + (char *) master, &new); if (!new) { masterPtr = (MaintainMaster *) Tcl_GetHashValue(hPtr); } else { @@ -383,16 +372,17 @@ Tk_UnmaintainGeometry(slave, master) MaintainMaster *masterPtr; register MaintainSlave *slavePtr, *prevPtr; Tk_Window ancestor; + TkDisplay *dispPtr = ((TkWindow *) slave)->dispPtr; - if (!initialized) { - initialized = 1; - Tcl_InitHashTable(&maintainHashTable, TCL_ONE_WORD_KEYS); + if (!dispPtr->geomInit) { + dispPtr->geomInit = 1; + Tcl_InitHashTable(&dispPtr->maintainHashTable, TCL_ONE_WORD_KEYS); } if (!(((TkWindow *) slave)->flags & TK_ALREADY_DEAD)) { Tk_UnmapWindow(slave); } - hPtr = Tcl_FindHashEntry(&maintainHashTable, (char *) master); + hPtr = Tcl_FindHashEntry(&dispPtr->maintainHashTable, (char *) master); if (hPtr == NULL) { return; } diff --git a/generic/tkGet.c b/generic/tkGet.c index 3507e9b..95833a1 100644 --- a/generic/tkGet.c +++ b/generic/tkGet.c @@ -8,24 +8,76 @@ * files. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGet.c,v 1.2 1998/09/14 18:23:11 stanton Exp $ + * RCS: @(#) $Id: tkGet.c,v 1.3 1999/04/16 01:51:14 stanton Exp $ */ #include "tkInt.h" #include "tkPort.h" /* - * The hash table below is used to keep track of all the Tk_Uids created - * so far. + * One of these structures is created per thread to store + * thread-specific data. In this case, it is used to house the + * Tk_Uids used by each thread. The "dataKey" below is used to + * locate the ThreadSpecificData for the current thread. */ -static Tcl_HashTable uidTable; -static int initialized = 0; +typedef struct ThreadSpecificData { + int initialized; + Tcl_HashTable uidTable; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* + * The following tables defines the string values for reliefs, which are + * used by Tk_GetAnchorFromObj and Tk_GetJustifyFromObj. + */ + +static char *anchorStrings[] = {"n", "ne", "e", "se", "s", "sw", "w", "nw", + "center", (char *) NULL}; +static char *justifyStrings[] = {"left", "right", "center", (char *) NULL}; + + +/* + *---------------------------------------------------------------------- + * + * Tk_GetAnchorFromObj -- + * + * Return a Tk_Anchor value based on the value of the objPtr. + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * The object gets converted by Tcl_GetIndexFromObj. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetAnchorFromObj(interp, objPtr, anchorPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *objPtr; /* The object we are trying to get the + * value from. */ + Tk_Anchor *anchorPtr; /* Where to place the Tk_Anchor that + * corresponds to the string value of + * objPtr. */ +{ + int index, code; + + code = Tcl_GetIndexFromObj(interp, objPtr, anchorStrings, "anchor", 0, + &index); + if (code == TCL_OK) { + *anchorPtr = (Tk_Anchor) index; + } + return code; +} /* *-------------------------------------------------------------- @@ -39,7 +91,7 @@ static int initialized = 0; * TCL_OK is returned, then everything went well and the * position is stored at *anchorPtr; otherwise TCL_ERROR * is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -155,7 +207,7 @@ Tk_NameOfAnchor(anchor) * TCL_OK is returned, then everything went well and the * justification is stored at *joinPtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -237,7 +289,7 @@ Tk_NameOfJoinStyle(join) * TCL_OK is returned, then everything went well and the * justification is stored at *capPtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -308,6 +360,43 @@ Tk_NameOfCapStyle(cap) } /* + *---------------------------------------------------------------------- + * + * Tk_GetJustifyFromObj -- + * + * Return a Tk_Justify value based on the value of the objPtr. + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * The object gets converted by Tcl_GetIndexFromObj. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetJustifyFromObj(interp, objPtr, justifyPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *objPtr; /* The object we are trying to get the + * value from. */ + Tk_Justify *justifyPtr; /* Where to place the Tk_Justify that + * corresponds to the string value of + * objPtr. */ +{ + int index, code; + + code = Tcl_GetIndexFromObj(interp, objPtr, justifyStrings, + "justification", 0, &index); + if (code == TCL_OK) { + *justifyPtr = (Tk_Justify) index; + } + return code; +} + +/* *-------------------------------------------------------------- * * Tk_GetJustify -- @@ -319,7 +408,7 @@ Tk_NameOfCapStyle(cap) * TCL_OK is returned, then everything went well and the * justification is stored at *justifyPtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -417,13 +506,16 @@ Tk_GetUid(string) CONST char *string; /* String to convert. */ { int dummy; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_HashTable *tablePtr = &tsdPtr->uidTable; - if (!initialized) { - Tcl_InitHashTable(&uidTable, TCL_STRING_KEYS); - initialized = 1; + if (!tsdPtr->initialized) { + Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS); + tsdPtr->initialized = 1; } - return (Tk_Uid) Tcl_GetHashKey(&uidTable, - Tcl_CreateHashEntry(&uidTable, string, &dummy)); + return (Tk_Uid) Tcl_GetHashKey(tablePtr, + Tcl_CreateHashEntry(tablePtr, string, &dummy)); } /* @@ -439,7 +531,7 @@ Tk_GetUid(string) * TCL_OK is returned, then everything went well and the * screen distance is stored at *doublePtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -515,7 +607,7 @@ Tk_GetScreenMM(interp, tkwin, string, doublePtr) * TCL_OK is returned, then everything went well and the * rounded pixel distance is stored at *intPtr; otherwise * TCL_ERROR is returned and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * None. @@ -584,3 +676,5 @@ Tk_GetPixels(interp, tkwin, string, intPtr) } return TCL_OK; } + + diff --git a/generic/tkGrab.c b/generic/tkGrab.c index b013a63..16b8b2a 100644 --- a/generic/tkGrab.c +++ b/generic/tkGrab.c @@ -4,12 +4,12 @@ * This file provides procedures that implement grabs for Tk. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGrab.c,v 1.3 1999/03/10 07:04:39 stanton Exp $ + * RCS: @(#) $Id: tkGrab.c,v 1.4 1999/04/16 01:51:14 stanton Exp $ */ #include "tkPort.h" @@ -242,10 +242,11 @@ Tk_GrabCmd(clientData, interp, argc, argv) } dispPtr = ((TkWindow *) tkwin)->dispPtr; if (dispPtr->eventualGrabWinPtr != NULL) { - interp->result = dispPtr->eventualGrabWinPtr->pathName; + Tcl_SetResult(interp, dispPtr->eventualGrabWinPtr->pathName, + TCL_STATIC); } } else { - for (dispPtr = tkDisplayList; dispPtr != NULL; + for (dispPtr = TkGetDisplayList(); dispPtr != NULL; dispPtr = dispPtr->nextPtr) { if (dispPtr->eventualGrabWinPtr != NULL) { Tcl_AppendElement(interp, @@ -307,11 +308,11 @@ Tk_GrabCmd(clientData, interp, argc, argv) } dispPtr = winPtr->dispPtr; if (dispPtr->eventualGrabWinPtr != winPtr) { - interp->result = "none"; + Tcl_SetResult(interp, "none", TCL_STATIC); } else if (dispPtr->grabFlags & GRAB_GLOBAL) { - interp->result = "global"; + Tcl_SetResult(interp, "global", TCL_STATIC); } else { - interp->result = "local"; + Tcl_SetResult(interp, "local", TCL_STATIC); } } else { Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1], @@ -333,7 +334,7 @@ Tk_GrabCmd(clientData, interp, argc, argv) * Results: * A standard Tcl result is returned. TCL_OK is the normal return * value; if the grab could not be set then TCL_ERROR is returned - * and interp->result will hold an error message. + * and the interp's result will hold an error message. * * Side effects: * Once this call completes successfully, no window outside the @@ -370,7 +371,8 @@ Tk_Grab(interp, tkwin, grabGlobal) } if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) { alreadyGrabbed: - interp->result = "grab failed: another application has grab"; + Tcl_SetResult(interp, "grab failed: another application has grab", + TCL_STATIC); return TCL_ERROR; } Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr); @@ -436,15 +438,18 @@ Tk_Grab(interp, tkwin, grabGlobal) if (grabResult != 0) { grabError: if (grabResult == GrabNotViewable) { - interp->result = "grab failed: window not viewable"; + Tcl_SetResult(interp, "grab failed: window not viewable", + TCL_STATIC); } else if (grabResult == AlreadyGrabbed) { goto alreadyGrabbed; } else if (grabResult == GrabFrozen) { - interp->result = "grab failed: keyboard or pointer frozen"; + Tcl_SetResult(interp, + "grab failed: keyboard or pointer frozen", TCL_STATIC); } else if (grabResult == GrabInvalidTime) { - interp->result = "grab failed: invalid time"; + Tcl_SetResult(interp, "grab failed: invalid time", + TCL_STATIC); } else { - char msg[100]; + char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "grab failed for unknown reason (code %d)", grabResult); diff --git a/generic/tkGrid.c b/generic/tkGrid.c index ea7a54c..11ae69d 100644 --- a/generic/tkGrid.c +++ b/generic/tkGrid.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGrid.c,v 1.3 1999/01/06 21:10:46 stanton Exp $ + * RCS: @(#) $Id: tkGrid.c,v 1.4 1999/04/16 01:51:14 stanton Exp $ */ #include "tkInt.h" @@ -222,14 +222,6 @@ typedef struct Gridder { #define DONT_PROPAGATE 2 /* - * Hash table used to map from Tk_Window tokens to corresponding - * Grid structures: - */ - -static Tcl_HashTable gridHashTable; -static int initialized = 0; - -/* * Prototypes for procedures used only in this file: */ @@ -314,6 +306,7 @@ Tk_GridCmd(clientData, interp, argc, argv) int endX, endY; /* last column/row in the layout */ int x=0, y=0; /* starting pixels for this bounding box */ int width, height; /* size of the bounding box */ + char buf[TCL_INTEGER_SPACE * 4]; if (argc!=3 && argc != 5 && argc != 7) { Tcl_AppendResult(interp, "wrong number of arguments: ", @@ -351,7 +344,7 @@ Tk_GridCmd(clientData, interp, argc, argv) gridPtr = masterPtr->masterDataPtr; if (gridPtr == NULL) { - sprintf(interp->result, "%d %d %d %d",0,0,0,0); + Tcl_SetResult(interp, "0 0 0 0", TCL_STATIC); return(TCL_OK); } @@ -360,7 +353,7 @@ Tk_GridCmd(clientData, interp, argc, argv) endY = MAX(gridPtr->rowEnd, gridPtr->rowMax); if ((endX == 0) || (endY == 0)) { - sprintf(interp->result, "%d %d %d %d",0,0,0,0); + Tcl_SetResult(interp, "0 0 0 0", TCL_STATIC); return(TCL_OK); } if (argc == 3) { @@ -406,8 +399,9 @@ Tk_GridCmd(clientData, interp, argc, argv) height = gridPtr->rowPtr[row2].offset - y; } - sprintf(interp->result, "%d %d %d %d", - x + gridPtr->startX, y + gridPtr->startY, width, height); + sprintf(buf, "%d %d %d %d", x + gridPtr->startX, y + gridPtr->startY, + width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) { if (argv[2][0] != '.') { Tcl_AppendResult(interp, "bad argument \"", argv[2], @@ -459,7 +453,7 @@ Tk_GridCmd(clientData, interp, argc, argv) } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { register Gridder *slavePtr; Tk_Window slave; - char buffer[70]; + char buffer[64 + TCL_INTEGER_SPACE * 4]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -472,7 +466,7 @@ Tk_GridCmd(clientData, interp, argc, argv) } slavePtr = GetGrid(slave); if (slavePtr->masterPtr == NULL) { - interp->result[0] = '\0'; + Tcl_ResetResult(interp); return TCL_OK; } @@ -494,6 +488,7 @@ Tk_GridCmd(clientData, interp, argc, argv) int x, y; /* Offset in pixels, from edge of parent. */ int i, j; /* Corresponding column and row indeces. */ int endX, endY; /* end of grid */ + char buf[TCL_INTEGER_SPACE * 2]; if (argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -515,7 +510,7 @@ Tk_GridCmd(clientData, interp, argc, argv) masterPtr = GetGrid(master); if (masterPtr->masterDataPtr == NULL) { - sprintf(interp->result, "%d %d", -1, -1); + Tcl_SetResult(interp, "-1 -1", TCL_STATIC); return TCL_OK; } gridPtr = masterPtr->masterDataPtr; @@ -554,7 +549,8 @@ Tk_GridCmd(clientData, interp, argc, argv) } } - sprintf(interp->result, "%d %d", i, j); + sprintf(buf, "%d %d", i, j); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'p') && (strncmp(argv[1], "propagate", length) == 0)) { Tk_Window master; int propagate; @@ -571,7 +567,9 @@ Tk_GridCmd(clientData, interp, argc, argv) } masterPtr = GetGrid(master); if (argc == 3) { - interp->result = (masterPtr->flags & DONT_PROPAGATE) ? "0" : "1"; + Tcl_SetResult(interp, + ((masterPtr->flags & DONT_PROPAGATE) ? "0" : "1"), + TCL_STATIC); return TCL_OK; } if (Tcl_GetBoolean(interp, argv[3], &propagate) != TCL_OK) { @@ -609,13 +607,16 @@ Tk_GridCmd(clientData, interp, argc, argv) masterPtr = GetGrid(master); if (masterPtr->masterDataPtr != NULL) { + char buf[TCL_INTEGER_SPACE * 2]; + SetGridSize(masterPtr); gridPtr = masterPtr->masterDataPtr; - sprintf(interp->result, "%d %d", - MAX(gridPtr->columnEnd, gridPtr->columnMax), - MAX(gridPtr->rowEnd, gridPtr->rowMax)); + sprintf(buf, "%d %d", + MAX(gridPtr->columnEnd, gridPtr->columnMax), + MAX(gridPtr->rowEnd, gridPtr->rowMax)); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else { - sprintf(interp->result, "%d %d",0, 0); + Tcl_SetResult(interp, "0 0", TCL_STATIC); } } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0) && (length > 1)) { @@ -757,12 +758,16 @@ Tk_GridCmd(clientData, interp, argc, argv) Tcl_Free((char *)argvPtr); } if ((argc == 4) && (ok == TCL_OK)) { - sprintf(interp->result,"-minsize %d -pad %d -weight %d", + char buf[64 + TCL_INTEGER_SPACE * 3]; + + sprintf(buf, "-minsize %d -pad %d -weight %d", slotPtr[slot].minSize,slotPtr[slot].pad, slotPtr[slot].weight); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return (TCL_OK); } else if (argc == 4) { - sprintf(interp->result,"-minsize %d -pad %d -weight %d", 0,0,0); + Tcl_SetResult(interp, "-minsize 0 -pad 0 -weight 0", + TCL_STATIC); return (TCL_OK); } @@ -783,8 +788,12 @@ Tk_GridCmd(clientData, interp, argc, argv) } if (strncmp(argv[i], "-minsize", length) == 0) { if (argc == 5) { - int value = ok == TCL_OK ? slotPtr[slot].minSize : 0; - sprintf(interp->result,"%d",value); + char buf[TCL_INTEGER_SPACE]; + int value; + + value = (ok == TCL_OK) ? slotPtr[slot].minSize : 0; + sprintf(buf, "%d", value); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (Tk_GetPixels(interp, master, argv[i+1], &size) != TCL_OK) { Tcl_Free((char *)argvPtr); @@ -796,8 +805,12 @@ Tk_GridCmd(clientData, interp, argc, argv) else if (strncmp(argv[i], "-weight", length) == 0) { int wt; if (argc == 5) { - int value = ok == TCL_OK ? slotPtr[slot].weight : 0; - sprintf(interp->result,"%d",value); + char buf[TCL_INTEGER_SPACE]; + int value; + + value = (ok == TCL_OK) ? slotPtr[slot].weight : 0; + sprintf(buf, "%d", value); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (Tcl_GetInt(interp, argv[i+1], &wt) != TCL_OK) { Tcl_Free((char *)argvPtr); return TCL_ERROR; @@ -812,8 +825,12 @@ Tk_GridCmd(clientData, interp, argc, argv) } else if (strncmp(argv[i], "-pad", length) == 0) { if (argc == 5) { - int value = ok == TCL_OK ? slotPtr[slot].pad : 0; - sprintf(interp->result,"%d",value); + char buf[TCL_INTEGER_SPACE]; + int value; + + value = (ok == TCL_OK) ? slotPtr[slot].pad : 0; + sprintf(buf, "%d", value); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (Tk_GetPixels(interp, master, argv[i+1], &size) != TCL_OK) { Tcl_Free((char *)argvPtr); @@ -1717,10 +1734,11 @@ GetGrid(tkwin) register Gridder *gridPtr; Tcl_HashEntry *hPtr; int new; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - initialized = 1; - Tcl_InitHashTable(&gridHashTable, TCL_ONE_WORD_KEYS); + if (!dispPtr->gridInit) { + Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS); + dispPtr->gridInit = 1; } /* @@ -1728,7 +1746,7 @@ GetGrid(tkwin) * then create a new one. */ - hPtr = Tcl_CreateHashEntry(&gridHashTable, (char *) tkwin, &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char *) tkwin, &new); if (!new) { return (Gridder *) Tcl_GetHashValue(hPtr); } @@ -2048,6 +2066,7 @@ GridStructureProc(clientData, eventPtr) XEvent *eventPtr; /* Describes what just happened. */ { register Gridder *gridPtr = (Gridder *) clientData; + TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr; if (eventPtr->type == ConfigureNotify) { if (!(gridPtr->flags & REQUESTED_RELAYOUT)) { @@ -2075,7 +2094,7 @@ GridStructureProc(clientData, eventPtr) nextPtr = gridPtr2->nextPtr; gridPtr2->nextPtr = NULL; } - Tcl_DeleteHashEntry(Tcl_FindHashEntry(&gridHashTable, + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable, (char *) gridPtr->tkwin)); if (gridPtr->flags & REQUESTED_RELAYOUT) { Tk_CancelIdleCall(ArrangeGrid, (ClientData) gridPtr); @@ -2110,7 +2129,7 @@ GridStructureProc(clientData, eventPtr) * * Results: * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is - * returned and interp->result is set to contain an error message. + * returned and the interp's result is set to contain an error message. * * Side effects: * Slave windows get taken over by the grid. @@ -2284,7 +2303,8 @@ ConfigureSlaves(interp, tkwin, argc, argv) return TCL_ERROR; } if (other == slave) { - sprintf(interp->result,"Window can't be managed in itself"); + Tcl_SetResult(interp, "Window can't be managed in itself", + TCL_STATIC); return TCL_ERROR; } masterPtr = GetGrid(other); diff --git a/generic/tkImage.c b/generic/tkImage.c index d2733ba..f9ff2b4 100644 --- a/generic/tkImage.c +++ b/generic/tkImage.c @@ -6,12 +6,12 @@ * widgets. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImage.c,v 1.2 1998/09/14 18:23:12 stanton Exp $ + * RCS: @(#) $Id: tkImage.c,v 1.3 1999/04/16 01:51:15 stanton Exp $ */ #include "tkInt.h" @@ -71,12 +71,11 @@ typedef struct ImageMaster { * derived from this name. */ } ImageMaster; -/* - * The following variable points to the first in a list of all known - * image types. - */ - -static Tk_ImageType *imageTypeList = NULL; +typedef struct ThreadSpecificData { + Tk_ImageType *imageTypeList;/* First in a list of all known image + * types. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Prototypes for local procedures: @@ -110,8 +109,11 @@ Tk_CreateImageType(typePtr) * in by caller. Must not have been passed * to Tk_CreateImageType previously. */ { - typePtr->nextPtr = imageTypeList; - imageTypeList = typePtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + typePtr->nextPtr = tsdPtr->imageTypeList; + tsdPtr->imageTypeList = typePtr; } /* @@ -146,8 +148,10 @@ Tk_ImageCmd(clientData, interp, argc, argv) Image *imagePtr; Tcl_HashEntry *hPtr; Tcl_HashSearch search; - char idString[30], *name; - static int id = 0; + char idString[16 + TCL_INTEGER_SPACE], *name; + TkDisplay *dispPtr = winPtr->dispPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -168,7 +172,7 @@ Tk_ImageCmd(clientData, interp, argc, argv) * Look up the image type. */ - for (typePtr = imageTypeList; typePtr != NULL; + for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; typePtr = typePtr->nextPtr) { if ((c == typePtr->name[0]) && (strcmp(argv[2], typePtr->name) == 0)) { @@ -186,8 +190,8 @@ Tk_ImageCmd(clientData, interp, argc, argv) */ if ((argc == 3) || (argv[3][0] == '-')) { - id++; - sprintf(idString, "image%d", id); + dispPtr->imageId++; + sprintf(idString, "image%d", dispPtr->imageId); name = idString; firstOption = 3; } else { @@ -248,7 +252,9 @@ Tk_ImageCmd(clientData, interp, argc, argv) imagePtr->instanceData = (*typePtr->getProc)( imagePtr->tkwin, masterPtr->masterData); } - interp->result = Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr); + Tcl_SetResult(interp, + Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), + TCL_STATIC); } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) { for (i = 2; i < argc; i++) { hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, argv[i]); @@ -261,6 +267,8 @@ Tk_ImageCmd(clientData, interp, argc, argv) DeleteImage(masterPtr); } } else if ((c == 'h') && (strncmp(argv[1], "height", length) == 0)) { + char buf[TCL_INTEGER_SPACE]; + if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " height name\"", (char *) NULL); @@ -273,7 +281,8 @@ Tk_ImageCmd(clientData, interp, argc, argv) return TCL_ERROR; } masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - sprintf(interp->result, "%d", masterPtr->height); + sprintf(buf, "%d", masterPtr->height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'n') && (strncmp(argv[1], "names", length) == 0)) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -299,7 +308,7 @@ Tk_ImageCmd(clientData, interp, argc, argv) } masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); if (masterPtr->typePtr != NULL) { - interp->result = masterPtr->typePtr->name; + Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC); } } else if ((c == 't') && (strcmp(argv[1], "types") == 0)) { if (argc != 2) { @@ -307,11 +316,13 @@ Tk_ImageCmd(clientData, interp, argc, argv) " types\"", (char *) NULL); return TCL_ERROR; } - for (typePtr = imageTypeList; typePtr != NULL; + for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; typePtr = typePtr->nextPtr) { Tcl_AppendElement(interp, typePtr->name); } } else if ((c == 'w') && (strncmp(argv[1], "width", length) == 0)) { + char buf[TCL_INTEGER_SPACE]; + if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " width name\"", (char *) NULL); @@ -324,7 +335,8 @@ Tk_ImageCmd(clientData, interp, argc, argv) return TCL_ERROR; } masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - sprintf(interp->result, "%d", masterPtr->width); + sprintf(buf, "%d", masterPtr->width); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, height, names, type, types,", @@ -416,7 +428,7 @@ Tk_NameOfImage(imageMaster) * Results: * The return value is a token for the image. If there is no image * by the given name, then NULL is returned and an error message is - * left in interp->result. + * left in the interp's result. * * Side effects: * Tk records the fact that the widget is using the image, and diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index d7be9de..093abac 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImgBmap.c,v 1.5 1999/02/04 20:56:15 stanton Exp $ + * RCS: @(#) $Id: tkImgBmap.c,v 1.6 1999/04/16 01:51:15 stanton Exp $ */ #include "tkInt.h" @@ -227,7 +227,7 @@ ImgBmapCreate(interp, name, argc, argv, typePtr, master, clientDataPtr) * * Results: * A standard Tcl return value. If TCL_ERROR is returned then - * an error message is left in masterPtr->interp->result. + * an error message is left in the masterPtr->interp's result. * * Side effects: * Existing instances of the image will be redisplayed to match @@ -278,7 +278,8 @@ ImgBmapConfigureMaster(masterPtr, argc, argv, flags) if ((masterPtr->maskFileString != NULL) || (masterPtr->maskDataString != NULL)) { if (masterPtr->data == NULL) { - masterPtr->interp->result = "can't have mask without bitmap"; + Tcl_SetResult(masterPtr->interp, "can't have mask without bitmap", + TCL_STATIC); return TCL_ERROR; } masterPtr->maskData = TkGetBitmapData(masterPtr->interp, @@ -291,7 +292,8 @@ ImgBmapConfigureMaster(masterPtr, argc, argv, flags) || (maskHeight != masterPtr->height)) { ckfree(masterPtr->maskData); masterPtr->maskData = NULL; - masterPtr->interp->result = "bitmap and mask have different sizes"; + Tcl_SetResult(masterPtr->interp, + "bitmap and mask have different sizes", TCL_STATIC); return TCL_ERROR; } } @@ -459,7 +461,7 @@ ImgBmapConfigureInstance(instancePtr) * *heightPtr. *hotXPtr and *hotYPtr are set to the bitmap * hotspot if one is defined, otherwise they are set to -1, -1. * If an error occurred, NULL is returned and an error message is - * left in interp->result. + * left in the interp's result. * * Side effects: * A bitmap is created. @@ -628,9 +630,8 @@ TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr, return data; error: - if (interp != NULL) { - interp->result = "format error in bitmap data"; - } + Tcl_SetResult(interp, "format error in bitmap data", TCL_STATIC); + errorCleanup: if (data != NULL) { ckfree(data); @@ -740,9 +741,8 @@ ImgBmapCmd(clientData, interp, argc, argv) size_t length; if (argc < 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s option ?arg arg ...?\"", - argv[0]); + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " option ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } c = argv[1][0]; diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index d9dd900..88edfa8 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -27,7 +27,7 @@ * | provided "as is" without express or implied warranty. | * +-------------------------------------------------------------------+ * - * RCS: @(#) $Id: tkImgGIF.c,v 1.2 1998/09/14 18:23:12 stanton Exp $ + * RCS: @(#) $Id: tkImgGIF.c,v 1.3 1999/04/16 01:51:15 stanton Exp $ */ /* @@ -61,6 +61,17 @@ typedef struct mFile { #include "tkPort.h" /* + * HACK ALERT!! HACK ALERT!! HACK ALERT!! + * This code is hard-wired for reading from files. In order to read + * from a data stream, we'll trick fread so we can reuse the same code + */ + +typedef struct ThreadSpecificData { + int fromData; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* * The format record for the GIF file format: */ @@ -100,14 +111,6 @@ Tk_PhotoImageFormat tkImgFmtGIF = { #define ReadOK(file,buffer,len) (Fread(buffer, len, 1, file) != 0) /* - * HACK ALERT!! HACK ALERT!! HACK ALERT!! - * This code is hard-wired for reading from files. In order to read - * from a data stream, we'll trick fread so we can reuse the same code - */ - -static int fromData=0; - -/* * Prototypes for local procedures defined in this file: */ @@ -184,7 +187,7 @@ FileMatchGIF(chan, fileName, formatString, widthPtr, heightPtr) * * Results: * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in interp->result. + * then an error message is left in the interp's result. * * Side effects: * The access position in file f is changed, and new data is @@ -287,12 +290,14 @@ FileReadGIF(interp, chan, fileName, formatString, imageHandle, destX, destY, */ if (Fread(buf, 1, 1, chan) != 1) { - interp->result = - "error reading extension function code in GIF image"; + Tcl_SetResult(interp, + "error reading extension function code in GIF image", + TCL_STATIC); goto error; } if (DoExtension(chan, buf[0], &transparent) < 0) { - interp->result = "error reading extension in GIF image"; + Tcl_SetResult(interp, "error reading extension in GIF image", + TCL_STATIC); goto error; } continue; @@ -306,7 +311,9 @@ FileReadGIF(interp, chan, fileName, formatString, imageHandle, destX, destY, } if (Fread(buf, 1, 9, chan) != 9) { - interp->result = "couldn't read left/top/width/height in GIF image"; + Tcl_SetResult(interp, + "couldn't read left/top/width/height in GIF image", + TCL_STATIC); goto error; } @@ -418,7 +425,7 @@ StringMatchGIF(string, formatString, widthPtr, heightPtr) * * Results: * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in interp->result. + * then an error message is left in the interp's result. * * Side effects: * new data is added to the image given by imageHandle. This @@ -439,15 +446,18 @@ StringReadGIF(interp,string,formatString,imageHandle, int width, height; /* image to copy */ int srcX, srcY; { - int result; - MFile handle; - mInit((unsigned char *)string,&handle); - fromData = 1; - result = FileReadGIF(interp, (Tcl_Channel) &handle, "inline data", - formatString, imageHandle, destX, destY, width, height, - srcX, srcY); - fromData = 0; - return(result); + int result; + MFile handle; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + mInit((unsigned char *)string,&handle); + tsdPtr->fromData = 1; + result = FileReadGIF(interp, (Tcl_Channel) &handle, "inline data", + formatString, imageHandle, destX, destY, width, height, + srcX, srcY); + tsdPtr->fromData = 0; + return(result); } /* @@ -619,7 +629,7 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap, } if (LWZReadByte(chan, 1, c) < 0) { - interp->result = "format error in GIF image"; + Tcl_SetResult(interp, "format error in GIF image", TCL_STATIC); return TCL_ERROR; } @@ -1051,7 +1061,10 @@ Fread(dst, hunk, count, chan) size_t hunk,count; /* how many */ Tcl_Channel chan; { - if (fromData) { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (tsdPtr->fromData) { return(Mread(dst, hunk, count, (MFile *) chan)); } else { return Tcl_Read(chan, (char *) dst, (int) (hunk * count)); diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c index 7573955..7482692 100644 --- a/generic/tkImgPPM.c +++ b/generic/tkImgPPM.c @@ -13,7 +13,7 @@ * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPPM.c,v 1.2 1998/09/14 18:23:13 stanton Exp $ + * RCS: @(#) $Id: tkImgPPM.c,v 1.3 1999/04/16 01:51:15 stanton Exp $ */ #include "tkInt.h" @@ -110,7 +110,7 @@ FileMatchPPM(chan, fileName, formatString, widthPtr, heightPtr) * * Results: * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in interp->result. + * then an error message is left in the interp's result. * * Side effects: * The access position in file f is changed, and new data is @@ -151,7 +151,7 @@ FileReadPPM(interp, chan, fileName, formatString, imageHandle, destX, destY, return TCL_ERROR; } if ((maxIntensity <= 0) || (maxIntensity >= 256)) { - char buffer[30]; + char buffer[TCL_INTEGER_SPACE]; sprintf(buffer, "%d", maxIntensity); Tcl_AppendResult(interp, "PPM image file \"", fileName, @@ -243,7 +243,7 @@ FileReadPPM(interp, chan, fileName, formatString, imageHandle, destX, destY, * * Results: * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in interp->result. + * then an error message is left in the interp's result. * * Side effects: * Data is written to the file given by "fileName". @@ -262,7 +262,7 @@ FileWritePPM(interp, fileName, formatString, blockPtr) int w, h; int greenOffset, blueOffset, nBytes; unsigned char *pixelPtr, *pixLinePtr; - char header[30]; + char header[16 + TCL_INTEGER_SPACE * 2]; chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (chan == NULL) { diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 285f1df..9fb74e6 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -11,7 +11,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.5 1999/03/10 07:04:39 stanton Exp $ + * Author: Paul Mackerras (paulus@cs.anu.edu.au), + * Department of Computer Science, + * Australian National University. + * + * RCS: @(#) $Id: tkImgPhoto.c,v 1.6 1999/04/16 01:51:15 stanton Exp $ */ #include "tkInt.h" @@ -293,6 +297,12 @@ Tk_ImageType tkPhotoImageType = { (Tk_ImageType *) NULL /* nextPtr */ }; +typedef struct ThreadSpecificData { + Tk_PhotoImageFormat *formatList; /* Pointer to the first in the + * list of known photo image formats.*/ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + /* * Default configuration */ @@ -334,12 +344,6 @@ static int imgPhotoColorHashInitialized; #define N_COLOR_HASH (sizeof(ColorTableId) / sizeof(int)) /* - * Pointer to the first in the list of known photo image formats. - */ - -static Tk_PhotoImageFormat *formatList = NULL; - -/* * Forward declarations */ @@ -419,13 +423,15 @@ Tk_CreatePhotoImageFormat(formatPtr) * to Tk_CreatePhotoImageFormat previously. */ { Tk_PhotoImageFormat *copyPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); copyPtr = (Tk_PhotoImageFormat *) ckalloc(sizeof(Tk_PhotoImageFormat)); *copyPtr = *formatPtr; copyPtr->name = (char *) ckalloc((unsigned) (strlen(formatPtr->name) + 1)); strcpy(copyPtr->name, formatPtr->name); - copyPtr->nextPtr = formatList; - formatList = copyPtr; + copyPtr->nextPtr = tsdPtr->formatList; + tsdPtr->formatList = copyPtr; } /* @@ -526,7 +532,6 @@ ImgPhotoCmd(clientData, interp, argc, argv) unsigned char *pixelPtr; Tk_PhotoImageBlock block; Tk_Window tkwin; - char string[16]; XColor color; Tk_PhotoImageFormat *imageFormat; int imageWidth, imageHeight; @@ -534,6 +539,8 @@ ImgPhotoCmd(clientData, interp, argc, argv) Tcl_Channel chan; Tk_PhotoHandle srcHandle; size_t length; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -682,6 +689,8 @@ ImgPhotoCmd(clientData, interp, argc, argv) * photo get command - first parse and check parameters. */ + char string[TCL_INTEGER_SPACE * 3]; + if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " get x y\"", (char *) NULL); @@ -978,7 +987,7 @@ ImgPhotoCmd(clientData, interp, argc, argv) */ matched = 0; - for (imageFormat = formatList; imageFormat != NULL; + for (imageFormat = tsdPtr->formatList; imageFormat != NULL; imageFormat = imageFormat->nextPtr) { if ((options.format == NULL) || (strncasecmp(options.format, imageFormat->name, @@ -1258,7 +1267,7 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, argc, argv) * * Results: * A standard Tcl return value. If TCL_ERROR is returned then - * an error message is left in masterPtr->interp->result. + * an error message is left in the masterPtr->interp's result. * * Side effects: * Existing instances of the image will be redisplayed to match @@ -1601,7 +1610,7 @@ ImgPhotoGet(tkwin, masterData) int mono, nRed, nGreen, nBlue; XVisualInfo visualInfo, *visInfoPtr; XRectangle validBox; - char buf[16]; + char buf[TCL_INTEGER_SPACE * 3]; int numVisuals; XColor *white, *black; XGCValues gcValues; @@ -3022,6 +3031,8 @@ MatchFileFormat(interp, chan, fileName, formatString, imageFormatPtr, { int matched; Tk_PhotoImageFormat *formatPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Scan through the table of file format handlers to find @@ -3029,7 +3040,7 @@ MatchFileFormat(interp, chan, fileName, formatString, imageFormatPtr, */ matched = 0; - for (formatPtr = formatList; formatPtr != NULL; + for (formatPtr = tsdPtr->formatList; formatPtr != NULL; formatPtr = formatPtr->nextPtr) { if (formatString != NULL) { if (strncasecmp(formatString, formatPtr->name, @@ -3112,6 +3123,8 @@ MatchStringFormat(interp, string, formatString, imageFormatPtr, { int matched; Tk_PhotoImageFormat *formatPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Scan through the table of file format handlers to find @@ -3119,7 +3132,7 @@ MatchStringFormat(interp, string, formatString, imageFormatPtr, */ matched = 0; - for (formatPtr = formatList; formatPtr != NULL; + for (formatPtr = tsdPtr->formatList; formatPtr != NULL; formatPtr = formatPtr->nextPtr) { if (formatString != NULL) { if (strncasecmp(formatString, formatPtr->name, diff --git a/generic/tkInitScript.h b/generic/tkInitScript.h index a478fd0..2e2b234 100644 --- a/generic/tkInitScript.h +++ b/generic/tkInitScript.h @@ -9,9 +9,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkInitScript.h,v 1.7 1998/09/14 18:23:13 stanton Exp $ + * RCS: @(#) $Id: tkInitScript.h,v 1.8 1999/04/16 01:51:15 stanton Exp $ */ + + /* * In order to find tk.tcl during initialization, the following script * is invoked by Tk_Init(). It looks in several different directories: @@ -48,7 +50,7 @@ static char initScript[] = "if {[info proc tkInit]==\"\"} {\n\ proc tkInit {} {\n\ global tk_library tk_version tk_patchLevel\n\ - rename tkInit {}\n\ + rename tkInit {}\n\ tcl_findLibrary tk $tk_version $tk_patchLevel tk.tcl TK_LIBRARY tk_library\n\ }\n\ }\n\ diff --git a/generic/tkInt.decls b/generic/tkInt.decls index dd70ef8..edb69f2 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -1,4 +1,4 @@ -# tkInt.decls -- + # tkInt.decls -- # # This file contains the declarations for all unsupported # functions that are exported by the Tk library. This file @@ -9,7 +9,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: tkInt.decls,v 1.4 1999/03/12 03:17:47 stanton Exp $ +# RCS: @(#) $Id: tkInt.decls,v 1.5 1999/04/16 01:51:15 stanton Exp $ library tk @@ -156,8 +156,9 @@ declare 28 generic { void TkFreeBindingTags (TkWindow *winPtr) } +# Name change only, TkFreeCursor in Tcl 8.0.x now TkpFreeCursor declare 29 generic { - void TkFreeCursor (TkCursor *cursorPtr) + void TkpFreeCursor (TkCursor *cursorPtr) } declare 30 generic { @@ -237,12 +238,12 @@ declare 46 generic { } declare 47 generic { - int TkLineToArea (TkDouble2 end1Ptr, TkDouble2 end2Ptr, TkDouble4 rectPtr) + int TkLineToArea (double end1Ptr[], double end2Ptr[], double rectPtr[]) } declare 48 generic { double TkLineToPoint (double end1Ptr[], \ - TkDouble2 end2Ptr, TkDouble2 pointPtr) + double end2Ptr[], double pointPtr[]) } declare 49 generic { @@ -269,8 +270,8 @@ declare 53 generic { } declare 54 generic { - double TkOvalToPoint (TkDouble4 ovalPtr, \ - double width, int filled, TkDouble2 pointPtr) + double TkOvalToPoint (double ovalPtr[], \ + double width, int filled, double pointPtr[]) } declare 55 generic { @@ -456,6 +457,73 @@ declare 97 generic { void TkWmUnmapWindow (TkWindow *winPtr) } +# new for 8.1 + +declare 98 generic { + Tcl_Obj * TkDebugBitmap ( Tk_Window tkwin, char *name) +} + +declare 99 generic { + Tcl_Obj * TkDebugBorder ( Tk_Window tkwin, char *name) +} + +declare 100 generic { + Tcl_Obj * TkDebugCursor ( Tk_Window tkwin, char *name) +} + +declare 101 generic { + Tcl_Obj * TkDebugColor ( Tk_Window tkwin, char *name) +} + +declare 102 generic { + Tcl_Obj * TkDebugConfig (Tcl_Interp *interp, Tk_OptionTable table) +} + +declare 103 generic { + Tcl_Obj * TkDebugFont ( Tk_Window tkwin, char *name) +} + +declare 104 generic { + int TkFindStateNumObj (Tcl_Interp *interp, \ + Tcl_Obj *optionPtr, CONST TkStateMap *mapPtr, \ + Tcl_Obj *keyPtr) +} + +declare 105 generic { + Tcl_HashTable * TkGetBitmapPredefTable (void) +} + +declare 106 generic { + TkDisplay * TkGetDisplayList (void) +} + +declare 107 generic { + TkMainInfo * TkGetMainInfoList (void) +} + +declare 108 generic { + int TkGetWindowFromObj (Tcl_Interp *interp, \ + Tk_Window tkwin, Tcl_Obj *objPtr, \ + Tk_Window *windowPtr) +} + +declare 109 generic { + char * TkpGetString (TkWindow *winPtr, \ + XEvent *eventPtr, Tcl_DString *dsPtr) +} + +declare 110 generic { + void TkpGetSubFonts (Tcl_Interp *interp, Tk_Font tkfont) +} + +declare 111 generic { + Tcl_Obj * TkpGetSystemDefault (Tk_Window tkwin, \ + char *dbName, char *className) +} + +declare 112 generic { + void TkpMenuThreadInit (void) +} ############################################################################## @@ -655,6 +723,24 @@ declare 35 win { void TkWinXInit (HINSTANCE hInstance) } +# new for 8.1 + +declare 36 win { + void TkWinSetForegroundWindow (TkWindow *winPtr) +} + +declare 37 win { + void TkWinDialogDebug (int debug) +} + +declare 38 win { + Tcl_Obj * TkWinGetMenuSystemDefault (Tk_Window tkwin, \ + char *dbName, char *className) +} + +declare 39 win { + int TkWinGetPlatformId(void) +} ######################## # Mac specific functions @@ -1089,7 +1175,7 @@ declare 25 win { declare 26 win { Pixmap XCreateBitmapFromData(Display* display, Drawable d, \ _Xconst char* data, unsigned int width,unsigned int height) -} +} declare 27 win { void XDefineCursor (Display* d, Window w, Cursor c) @@ -1327,13 +1413,118 @@ declare 80 win { int dest_x, int dest_y, unsigned int width, \ unsigned int height) } +# This slot is reserved for use by the clipping rectangle patch: +# declare 81 win { +# XSetClipRectangles(Display *display, GC gc, int clip_x_origin, \ +# int clip_y_origin, XRectangle rectangles[], int n, int ordering) +# } + +declare 82 win { + Status XParseColor (Display *display, Colormap map, \ + _Xconst char* spec, XColor *colorPtr) +} + +declare 83 win { + GC XCreateGC(Display* display, Drawable d, \ + unsigned long valuemask, XGCValues* values) +} + +declare 84 win { + void XFreeGC(Display* display, GC gc) +} + +declare 85 win { + Atom XInternAtom(Display* display,_Xconst char* atom_name, \ + Bool only_if_exists) +} + +declare 86 win { + void XSetBackground(Display* display, GC gc, \ + unsigned long foreground) +} + +declare 87 win { + void XSetForeground(Display* display, GC gc, \ + unsigned long foreground) +} + +declare 88 win { + void XSetClipMask(Display* display, GC gc, Pixmap pixmap) +} + +declare 89 win { + void XSetClipOrigin(Display* display, GC gc, \ + int clip_x_origin, int clip_y_origin) +} + +declare 90 win { + void XSetTSOrigin(Display* display, GC gc, \ + int ts_x_origin, int ts_y_origin) +} + +declare 91 win { + void XChangeGC(Display * d, GC gc, unsigned long mask, XGCValues *values) +} + +declare 92 win { + void XSetFont(Display *display, GC gc, Font font) +} + +declare 93 win { + void XSetArcMode(Display *display, GC gc, int arc_mode) +} + +declare 94 win { + void XSetStipple(Display *display, GC gc, Pixmap stipple) +} + +declare 95 win { + void XSetFillRule(Display *display, GC gc, int fill_rule) +} + +declare 96 win { + void XSetFillStyle(Display *display, GC gc, int fill_style) +} + +declare 97 win { + void XSetFunction(Display *display, GC gc, int function) +} + +declare 98 win { + void XSetLineAttributes(Display *display, GC gc, \ + unsigned int line_width, int line_style, \ + int cap_style, int join_style) +} + +declare 99 win { + int _XInitImageFuncPtrs(XImage *image) +} + +declare 100 win { + XIC XCreateIC(void) +} + +declare 101 win { + XVisualInfo *XGetVisualInfo(Display* display, long vinfo_mask, \ + XVisualInfo* vinfo_template, int* nitems_return) +} + +declare 102 win { + void XSetWMClientMachine(Display* display, Window w, XTextProperty* text_prop) +} + +declare 103 win { + Status XStringListToTextProperty(char** list, int count, \ + XTextProperty* text_prop_return) +} # X functions for Mac # This slot is reserved for use by the dash patch: -# declare 0 mac { +# declare 0 win { # XSetDashes # } + declare 1 mac { XModifierKeymap* XGetModifierMapping (Display* d) } @@ -1422,7 +1613,7 @@ declare 18 mac { declare 19 mac { Pixmap XCreateBitmapFromData(Display* display, Drawable d, \ _Xconst char* data, unsigned int width,unsigned int height) -} +} declare 20 mac { void XDefineCursor (Display* d, Window w, Cursor c) @@ -1591,5 +1782,102 @@ declare 57 mac { GC gc, XImage* image, int src_x, int src_y, \ int dest_x, int dest_y, unsigned int width, \ unsigned int height) +} +declare 58 mac { + Status XParseColor (Display *display, Colormap map, \ + _Xconst char* spec, XColor *colorPtr) +} + +declare 59 mac { + GC XCreateGC(Display* display, Drawable d, \ + unsigned long valuemask, XGCValues* values) +} + +declare 60 mac { + void XFreeGC(Display* display, GC gc) +} + +declare 61 mac { + Atom XInternAtom(Display* display,_Xconst char* atom_name, \ + Bool only_if_exists) +} + +declare 62 mac { + void XSetBackground(Display* display, GC gc, \ + unsigned long foreground) +} + +declare 63 mac { + void XSetForeground(Display* display, GC gc, \ + unsigned long foreground) +} + +declare 64 mac { + void XSetClipMask(Display* display, GC gc, Pixmap pixmap) } +declare 65 mac { + void XSetClipOrigin(Display* display, GC gc, \ + int clip_x_origin, int clip_y_origin) +} + +declare 66 mac { + void XSetTSOrigin(Display* display, GC gc, \ + int ts_x_origin, int ts_y_origin) +} + +declare 67 mac { + void XChangeGC(Display * d, GC gc, unsigned long mask, XGCValues *values) +} + +declare 68 mac { + void XSetFont(Display *display, GC gc, Font font) +} + +declare 69 mac { + void XSetArcMode(Display *display, GC gc, int arc_mode) +} + +declare 70 mac { + void XSetStipple(Display *display, GC gc, Pixmap stipple) +} + +declare 71 mac { + void XSetFillRule(Display *display, GC gc, int fill_rule) +} + +declare 72 mac { + void XSetFillStyle(Display *display, GC gc, int fill_style) +} + +declare 73 mac { + void XSetFunction(Display *display, GC gc, int function) +} + +declare 74 mac { + void XSetLineAttributes(Display *display, GC gc, \ + unsigned int line_width, int line_style, \ + int cap_style, int join_style) +} + +declare 75 mac { + int _XInitImageFuncPtrs(XImage *image) +} + +declare 76 mac { + XIC XCreateIC(void) +} + +declare 77 mac { + XVisualInfo *XGetVisualInfo(Display* display, long vinfo_mask, \ + XVisualInfo* vinfo_template, int* nitems_return) +} + +declare 78 mac { + void XSetWMClientMachine(Display* display, Window w, XTextProperty* text_prop) +} + +declare 79 mac { + Status XStringListToTextProperty(char** list, int count, \ + XTextProperty* text_prop_return) +} diff --git a/generic/tkInt.h b/generic/tkInt.h index c9706e9..68091bc 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -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: tkInt.h,v 1.9 1999/03/10 07:04:40 stanton Exp $ + * RCS: $Id: tkInt.h,v 1.10 1999/04/16 01:51:15 stanton Exp $ */ #ifndef _TKINT @@ -40,13 +40,6 @@ typedef struct TkStressedCmap TkStressedCmap; typedef struct TkBindInfo_ *TkBindInfo; /* - * Array type definitions - */ - -typedef double TkDouble2[2]; -typedef double TkDouble4[4]; - -/* * Procedure types. */ @@ -89,16 +82,37 @@ typedef struct TkClassProcs { typedef struct TkCursor { Tk_Cursor cursor; /* System specific identifier for cursor. */ - int refCount; /* Number of active uses of cursor. */ + Display *display; /* Display containing cursor. Needed for + * disposal and retrieval of cursors. */ + int resourceRefCount; /* Number of active uses of this cursor (each + * active use corresponds to a call to + * Tk_AllocPreserveFromObj or Tk_GetPreserve). + * If this count is 0, then this structure + * is no longer valid and it isn't present + * in a hash table: it is being kept around + * only because there are objects referring + * to it. The structure is freed when + * resourceRefCount and objRefCount are + * both 0. */ + int objRefCount; /* Number of Tcl objects that reference + * this structure.. */ Tcl_HashTable *otherTable; /* Second table (other than idTable) used * to index this entry. */ Tcl_HashEntry *hashPtr; /* Entry in otherTable for this structure * (needed when deleting). */ + Tcl_HashEntry *idHashPtr; /* Entry in idTable for this structure + * (needed when deleting). */ + struct TkCursor *nextPtr; /* Points to the next TkCursor structure with + * the same name. Cursors with the same + * name but different displays are chained + * together off a single hash table entry. */ } TkCursor; /* * One of the following structures is maintained for each display - * containing a window managed by Tk: + * containing a window managed by Tk. In part, the structure is + * used to store thread-specific data, since each thread will have + * its own TkDisplay structure. */ typedef struct TkDisplay { @@ -110,6 +124,23 @@ typedef struct TkDisplay { * display. */ /* + * Information used primarily by tk3d.c: + */ + + int borderInit; /* 0 means borderTable needs initializing. */ + Tcl_HashTable borderTable; /* Maps from color name to TkBorder + * structure. */ + + /* + * Information used by tkAtom.c only: + */ + + int atomInit; /* 0 means stuff below hasn't been + * initialized yet. */ + Tcl_HashTable nameTable; /* Maps from names to Atom's. */ + Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ + + /* * Information used primarily by tkBind.c: */ @@ -135,6 +166,63 @@ typedef struct TkDisplay { * may be NULL. */ /* + * Information used by tkBitmap.c only: + */ + + int bitmapInit; /* 0 means tables above need initializing. */ + int bitmapAutoNumber; /* Used to number bitmaps. */ + Tcl_HashTable bitmapNameTable; + /* Maps from name of bitmap to the first + * TkBitmap record for that name. */ + Tcl_HashTable bitmapIdTable;/* Maps from bitmap id to the TkBitmap + * structure for the bitmap. */ + Tcl_HashTable bitmapDataTable; + /* Used by Tk_GetBitmapFromData to map from + * a collection of in-core data about a + * bitmap to a reference giving an auto- + * matically-generated name for the bitmap. */ + + /* + * Information used by tkCanvas.c only: + */ + + int numIdSearches; + int numSlowSearches; + + /* + * Used by tkColor.c only: + */ + + int colorInit; /* 0 means color module needs initializing. */ + TkStressedCmap *stressPtr; /* First in list of colormaps that have + * filled up, so we have to pick an + * approximate color. */ + Tcl_HashTable colorNameTable; + /* Maps from color name to TkColor structure + * for that color. */ + Tcl_HashTable colorValueTable; + /* Maps from integer RGB values to TkColor + * structures. */ + + /* + * Used by tkCursor.c only: + */ + + int cursorInit; /* 0 means cursor module need initializing. */ + Tcl_HashTable cursorNameTable; + /* Maps from a string name to a cursor to the + * TkCursor record for the cursor. */ + Tcl_HashTable cursorDataTable; + /* Maps from a collection of in-core data + * about a cursor to a TkCursor structure. */ + Tcl_HashTable cursorIdTable; + /* Maps from a cursor id to the TkCursor + * structure for the cursor. */ + char cursorString[20]; /* Used to store a cursor id string. */ + Font cursorFont; /* Font to use for standard cursors. + * None means font not loaded yet. */ + + /* * Information used by tkError.c only: */ @@ -148,68 +236,65 @@ typedef struct TkDisplay { * gets big, handlers get cleaned up. */ /* - * Information used by tkSend.c only: + * Used by tkEvent.c only: */ - Tk_Window commTkwin; /* Window used for communication - * between interpreters during "send" - * commands. NULL means send info hasn't - * been initialized yet. */ - Atom commProperty; /* X's name for comm property. */ - Atom registryProperty; /* X's name for property containing - * registry of interpreter names. */ - Atom appNameProperty; /* X's name for property used to hold the - * application name on each comm window. */ + struct TkWindowEvent *delayedMotionPtr; + /* Points to a malloc-ed motion event + * whose processing has been delayed in + * the hopes that another motion event + * will come along right away and we can + * merge the two of them together. NULL + * means that there is no delayed motion + * event. */ /* - * Information used by tkSelect.c and tkClipboard.c only: + * Information used by tkFocus.c only: */ - struct TkSelectionInfo *selectionInfoPtr; - /* First in list of selection information - * records. Each entry contains information - * about the current owner of a particular - * selection on this display. */ - Atom multipleAtom; /* Atom for MULTIPLE. None means - * selection stuff isn't initialized. */ - Atom incrAtom; /* Atom for INCR. */ - Atom targetsAtom; /* Atom for TARGETS. */ - Atom timestampAtom; /* Atom for TIMESTAMP. */ - Atom textAtom; /* Atom for TEXT. */ - Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ - Atom applicationAtom; /* Atom for TK_APPLICATION. */ - Atom windowAtom; /* Atom for TK_WINDOW. */ - Atom clipboardAtom; /* Atom for CLIPBOARD. */ + int focusDebug; /* 1 means collect focus debugging + * statistics. */ + struct TkWindow *implicitWinPtr; + /* If the focus arrived at a toplevel window + * implicitly via an Enter event (rather + * than via a FocusIn event), this points + * to the toplevel window. Otherwise it is + * NULL. */ + struct TkWindow *focusPtr; /* Points to the window on this display that + * should be receiving keyboard events. When + * multiple applications on the display have + * the focus, this will refer to the + * innermost window in the innermost + * application. This information isn't used + * under Unix or Windows, but it's needed on + * the Macintosh. */ - Tk_Window clipWindow; /* Window used for clipboard ownership and to - * retrieve selections between processes. NULL - * means clipboard info hasn't been - * initialized. */ - int clipboardActive; /* 1 means we currently own the clipboard - * selection, 0 means we don't. */ - struct TkMainInfo *clipboardAppPtr; - /* Last application that owned clipboard. */ - struct TkClipboardTarget *clipTargetPtr; - /* First in list of clipboard type information - * records. Each entry contains information - * about the buffers for a given selection - * target. */ + /* + * Information used by tkGC.c only: + */ + + Tcl_HashTable gcValueTable; /* Maps from a GC's values to a TkGC structure + * describing a GC with those values. */ + Tcl_HashTable gcIdTable; /* Maps from a GC to a TkGC. */ + int gcInit; /* 0 means the tables below need + * initializing. */ /* - * Information used by tkAtom.c only: + * Information used by tkGeometry.c only: */ - int atomInit; /* 0 means stuff below hasn't been - * initialized yet. */ - Tcl_HashTable nameTable; /* Maps from names to Atom's. */ - Tcl_HashTable atomTable; /* Maps from Atom's back to names. */ + Tcl_HashTable maintainHashTable; + /* Hash table that maps from a master's + * Tk_Window token to a list of slaves + * managed by that master. */ + int geomInit; /* - * Information used by tkCursor.c only: + * Information used by tkGet.c only: */ - - Font cursorFont; /* Font to use for standard cursors. - * None means font not loaded yet. */ + + Tcl_HashTable uidTable; /* Stores all Tk_Uids used in a thread. */ + int uidInit; /* 0 means uidTable needs initializing. */ /* * Information used by tkGrab.c only: @@ -247,6 +332,100 @@ typedef struct TkDisplay { * in tkGrab.c. */ /* + * Information used by tkGrid.c only: + */ + + int gridInit; /* 0 means table below needs initializing. */ + Tcl_HashTable gridHashTable;/* Maps from Tk_Window tokens to + * corresponding Grid structures. */ + + /* + * Information used by tkImage.c only: + */ + + int imageId; /* Value used to number image ids. */ + + /* + * Information used by tkMacWinMenu.c only: + */ + + int postCommandGeneration; + + /* + * Information used by tkOption.c only. + */ + + + + /* + * Information used by tkPack.c only. + */ + + int packInit; /* 0 means table below needs initializing. */ + Tcl_HashTable packerHashTable; + /* Maps from Tk_Window tokens to + * corresponding Packer structures. */ + + + /* + * Information used by tkPlace.c only. + */ + + int placeInit; /* 0 means tables below need initializing. */ + Tcl_HashTable masterTable; /* Maps from Tk_Window toke to the Master + * structure for the window, if it exists. */ + Tcl_HashTable slaveTable; /* Maps from Tk_Window toke to the Slave + * structure for the window, if it exists. */ + + /* + * Information used by tkSelect.c and tkClipboard.c only: + */ + + struct TkSelectionInfo *selectionInfoPtr; + /* First in list of selection information + * records. Each entry contains information + * about the current owner of a particular + * selection on this display. */ + Atom multipleAtom; /* Atom for MULTIPLE. None means + * selection stuff isn't initialized. */ + Atom incrAtom; /* Atom for INCR. */ + Atom targetsAtom; /* Atom for TARGETS. */ + Atom timestampAtom; /* Atom for TIMESTAMP. */ + Atom textAtom; /* Atom for TEXT. */ + Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ + Atom applicationAtom; /* Atom for TK_APPLICATION. */ + Atom windowAtom; /* Atom for TK_WINDOW. */ + Atom clipboardAtom; /* Atom for CLIPBOARD. */ + + Tk_Window clipWindow; /* Window used for clipboard ownership and to + * retrieve selections between processes. NULL + * means clipboard info hasn't been + * initialized. */ + int clipboardActive; /* 1 means we currently own the clipboard + * selection, 0 means we don't. */ + struct TkMainInfo *clipboardAppPtr; + /* Last application that owned clipboard. */ + struct TkClipboardTarget *clipTargetPtr; + /* First in list of clipboard type information + * records. Each entry contains information + * about the buffers for a given selection + * target. */ + + /* + * Information used by tkSend.c only: + */ + + Tk_Window commTkwin; /* Window used for communication + * between interpreters during "send" + * commands. NULL means send info hasn't + * been initialized yet. */ + Atom commProperty; /* X's name for comm property. */ + Atom registryProperty; /* X's name for property containing + * registry of interpreter names. */ + Atom appNameProperty; /* X's name for property used to hold the + * application name on each comm window. */ + + /* * Information used by tkXId.c only: */ @@ -265,6 +444,19 @@ typedef struct TkDisplay { * hasn't. */ /* + * Information used by tkUnixWm.c and tkWinWm.c only: + */ + + int wmTracing; /* Used to enable or disable tracing in + * this module. If tracing is enabled, + * then information is printed on + * standard output about interesting + * interactions with the window manager. */ + struct TkWmInfo *firstWmPtr; /* Points to first top-level window. */ + struct TkWmInfo *foregroundWmPtr; + /* Points to the foreground window. */ + + /* * Information maintained by tkWindow.c for use later on by tkXId.c: */ @@ -285,46 +477,6 @@ typedef struct TkDisplay { * allocated for this display. */ /* - * Information used by tkFocus.c only: - */ - - struct TkWindow *implicitWinPtr; - /* If the focus arrived at a toplevel window - * implicitly via an Enter event (rather - * than via a FocusIn event), this points - * to the toplevel window. Otherwise it is - * NULL. */ - struct TkWindow *focusPtr; /* Points to the window on this display that - * should be receiving keyboard events. When - * multiple applications on the display have - * the focus, this will refer to the - * innermost window in the innermost - * application. This information isn't used - * under Unix or Windows, but it's needed on - * the Macintosh. */ - - /* - * Used by tkColor.c only: - */ - - TkStressedCmap *stressPtr; /* First in list of colormaps that have - * filled up, so we have to pick an - * approximate color. */ - - /* - * Used by tkEvent.c only: - */ - - struct TkWindowEvent *delayedMotionPtr; - /* Points to a malloc-ed motion event - * whose processing has been delayed in - * the hopes that another motion event - * will come along right away and we can - * merge the two of them together. NULL - * means that there is no delayed motion - * event. */ - - /* * Miscellaneous information: */ @@ -375,6 +527,9 @@ typedef struct TkErrorHandler { * list. */ } TkErrorHandler; + + + /* * One of the following structures exists for each event handler * created by calling Tk_CreateEventHandler. This information @@ -417,10 +572,10 @@ typedef struct TkMainInfo { /* Used in conjunction with "bind" command * to bind events to Tcl commands. */ TkBindInfo bindInfo; /* Information used by tkBind.c on a per - * interpreter basis. */ + * application basis. */ struct TkFontInfo *fontInfoPtr; - /* Hold named font tables. Used only by - * tkFont.c. */ + /* Information used by tkFont.c on a per + * application basis. */ /* * Information used only by tkFocus.c and tk*Embed.c: @@ -711,67 +866,82 @@ extern int tkSendSerial; # define TCL_STORAGE_CLASS DLLEXPORT #endif -int TkConsoleInit _ANSI_ARGS_((Tcl_Interp *interp)); -void TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp, - int devId, char *buffer, long size)); - /* - * For backwards compatibility, need the tkIntPlatDecls.h here for - * windows & mac X wrappers. + * Internal procedures shared among Tk modules but not exported + * to the outside world: */ +EXTERN int Tk_AfterCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_BellObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); EXTERN int Tk_BindCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_BindtagsCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_ButtonCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_ButtonObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_CanvasCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_CheckbuttonCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_CheckbuttonObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_ClipboardCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_ChooseColorCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_ChooseColorObjCmd _ANSI_ARGS_(( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[])); +EXTERN int Tk_ChooseDirectoryObjCmd _ANSI_ARGS_(( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[])); +EXTERN int Tk_ChooseFontObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_DestroyCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_EntryCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_EventCmd _ANSI_ARGS_((ClientData clientData, +EXTERN int Tk_EntryObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +EXTERN int Tk_EventObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +EXTERN int Tk_FileeventCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_FrameCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_FocusCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_FocusObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_FontObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +EXTERN int Tk_GetOpenFileObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +EXTERN int Tk_GetSaveFileObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -EXTERN int Tk_GetOpenFileCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_GetSaveFileCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_GrabCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_GridCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_ImageCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_LabelCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_LabelObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_ListboxCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_LowerCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_MenuCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_MenubuttonCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_MessageBoxCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_MenubuttonObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); +EXTERN int Tk_MessageBoxObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_MessageCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_OptionCmd _ANSI_ARGS_((ClientData clientData, @@ -780,18 +950,23 @@ EXTERN int Tk_PackCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_PlaceCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_RadiobuttonCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_RadiobuttonObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_RaiseCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_ScaleCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_ScaleObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_ScrollbarCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_SelectionCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_SendCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_SendObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_TextCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_TkObjCmd _ANSI_ARGS_((ClientData clientData, @@ -801,17 +976,26 @@ EXTERN int Tk_TkwaitCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_ToplevelCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int Tk_UpdateCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +EXTERN int Tk_UpdateObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); EXTERN int Tk_WinfoObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); EXTERN int Tk_WmCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); -EXTERN int TkDeadAppCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -EXTERN int TkpTestembedCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +int TkConsoleInit _ANSI_ARGS_((Tcl_Interp *interp)); +void TkConsolePrint _ANSI_ARGS_((Tcl_Interp *interp, + int devId, char *buffer, long size)); + +EXTERN void TkEventInit _ANSI_ARGS_((void)); + +EXTERN int TkCreateMenuCmd _ANSI_ARGS_((Tcl_Interp *interp)); +EXTERN int TkDeadAppCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, char **argv)); + +EXTERN int TkpTestembedCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, char **argv)); /* * Unsupported commands. diff --git a/generic/tkIntDecls.h b/generic/tkIntDecls.h index fb929eb..2ca0147 100644 --- a/generic/tkIntDecls.h +++ b/generic/tkIntDecls.h @@ -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: tkIntDecls.h,v 1.2 1999/03/10 07:04:40 stanton Exp $ + * RCS: @(#) $Id: tkIntDecls.h,v 1.3 1999/04/16 01:51:16 stanton Exp $ */ #ifndef _TKINTDECLS @@ -127,7 +127,7 @@ EXTERN void TkFontPkgFree _ANSI_ARGS_((TkMainInfo * mainPtr)); /* 28 */ EXTERN void TkFreeBindingTags _ANSI_ARGS_((TkWindow * winPtr)); /* 29 */ -EXTERN void TkFreeCursor _ANSI_ARGS_((TkCursor * cursorPtr)); +EXTERN void TkpFreeCursor _ANSI_ARGS_((TkCursor * cursorPtr)); /* 30 */ EXTERN char * TkGetBitmapData _ANSI_ARGS_((Tcl_Interp * interp, char * string, char * fileName, @@ -181,11 +181,11 @@ EXTERN void TkInstallFrameMenu _ANSI_ARGS_((Tk_Window tkwin)); /* 46 */ EXTERN char * TkKeysymToString _ANSI_ARGS_((KeySym keysym)); /* 47 */ -EXTERN int TkLineToArea _ANSI_ARGS_((TkDouble2 end1Ptr, - TkDouble2 end2Ptr, TkDouble4 rectPtr)); +EXTERN int TkLineToArea _ANSI_ARGS_((double end1Ptr[], + double end2Ptr[], double rectPtr[])); /* 48 */ EXTERN double TkLineToPoint _ANSI_ARGS_((double end1Ptr[], - TkDouble2 end2Ptr, TkDouble2 pointPtr)); + double end2Ptr[], double pointPtr[])); /* 49 */ EXTERN int TkMakeBezierCurve _ANSI_ARGS_((Tk_Canvas canvas, double * pointPtr, int numPoints, @@ -203,8 +203,8 @@ EXTERN void TkOptionDeadWindow _ANSI_ARGS_((TkWindow * winPtr)); EXTERN int TkOvalToArea _ANSI_ARGS_((double * ovalPtr, double * rectPtr)); /* 54 */ -EXTERN double TkOvalToPoint _ANSI_ARGS_((TkDouble4 ovalPtr, - double width, int filled, TkDouble2 pointPtr)); +EXTERN double TkOvalToPoint _ANSI_ARGS_((double ovalPtr[], + double width, int filled, double pointPtr[])); /* 55 */ EXTERN int TkpChangeFocus _ANSI_ARGS_((TkWindow * winPtr, int force)); @@ -327,6 +327,49 @@ EXTERN void TkWmRestackToplevel _ANSI_ARGS_((TkWindow * winPtr, EXTERN void TkWmSetClass _ANSI_ARGS_((TkWindow * winPtr)); /* 97 */ EXTERN void TkWmUnmapWindow _ANSI_ARGS_((TkWindow * winPtr)); +/* 98 */ +EXTERN Tcl_Obj * TkDebugBitmap _ANSI_ARGS_((Tk_Window tkwin, + char * name)); +/* 99 */ +EXTERN Tcl_Obj * TkDebugBorder _ANSI_ARGS_((Tk_Window tkwin, + char * name)); +/* 100 */ +EXTERN Tcl_Obj * TkDebugCursor _ANSI_ARGS_((Tk_Window tkwin, + char * name)); +/* 101 */ +EXTERN Tcl_Obj * TkDebugColor _ANSI_ARGS_((Tk_Window tkwin, + char * name)); +/* 102 */ +EXTERN Tcl_Obj * TkDebugConfig _ANSI_ARGS_((Tcl_Interp * interp, + Tk_OptionTable table)); +/* 103 */ +EXTERN Tcl_Obj * TkDebugFont _ANSI_ARGS_((Tk_Window tkwin, + char * name)); +/* 104 */ +EXTERN int TkFindStateNumObj _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_Obj * optionPtr, + CONST TkStateMap * mapPtr, Tcl_Obj * keyPtr)); +/* 105 */ +EXTERN Tcl_HashTable * TkGetBitmapPredefTable _ANSI_ARGS_((void)); +/* 106 */ +EXTERN TkDisplay * TkGetDisplayList _ANSI_ARGS_((void)); +/* 107 */ +EXTERN TkMainInfo * TkGetMainInfoList _ANSI_ARGS_((void)); +/* 108 */ +EXTERN int TkGetWindowFromObj _ANSI_ARGS_((Tcl_Interp * interp, + Tk_Window tkwin, Tcl_Obj * objPtr, + Tk_Window * windowPtr)); +/* 109 */ +EXTERN char * TkpGetString _ANSI_ARGS_((TkWindow * winPtr, + XEvent * eventPtr, Tcl_DString * dsPtr)); +/* 110 */ +EXTERN void TkpGetSubFonts _ANSI_ARGS_((Tcl_Interp * interp, + Tk_Font tkfont)); +/* 111 */ +EXTERN Tcl_Obj * TkpGetSystemDefault _ANSI_ARGS_((Tk_Window tkwin, + char * dbName, char * className)); +/* 112 */ +EXTERN void TkpMenuThreadInit _ANSI_ARGS_((void)); typedef struct TkIntStubs { int magic; @@ -361,7 +404,7 @@ typedef struct TkIntStubs { void (*tkFontPkgInit) _ANSI_ARGS_((TkMainInfo * mainPtr)); /* 26 */ void (*tkFontPkgFree) _ANSI_ARGS_((TkMainInfo * mainPtr)); /* 27 */ void (*tkFreeBindingTags) _ANSI_ARGS_((TkWindow * winPtr)); /* 28 */ - void (*tkFreeCursor) _ANSI_ARGS_((TkCursor * cursorPtr)); /* 29 */ + void (*tkpFreeCursor) _ANSI_ARGS_((TkCursor * cursorPtr)); /* 29 */ char * (*tkGetBitmapData) _ANSI_ARGS_((Tcl_Interp * interp, char * string, char * fileName, int * widthPtr, int * heightPtr, int * hotXPtr, int * hotYPtr)); /* 30 */ void (*tkGetButtPoints) _ANSI_ARGS_((double p1[], double p2[], double width, int project, double m1[], double m2[])); /* 31 */ TkCursor * (*tkGetCursorByName) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tk_Uid string)); /* 32 */ @@ -379,14 +422,14 @@ typedef struct TkIntStubs { void (*tkInOutEvents) _ANSI_ARGS_((XEvent * eventPtr, TkWindow * sourcePtr, TkWindow * destPtr, int leaveType, int enterType, Tcl_QueuePosition position)); /* 44 */ void (*tkInstallFrameMenu) _ANSI_ARGS_((Tk_Window tkwin)); /* 45 */ char * (*tkKeysymToString) _ANSI_ARGS_((KeySym keysym)); /* 46 */ - int (*tkLineToArea) _ANSI_ARGS_((TkDouble2 end1Ptr, TkDouble2 end2Ptr, TkDouble4 rectPtr)); /* 47 */ - double (*tkLineToPoint) _ANSI_ARGS_((double end1Ptr[], TkDouble2 end2Ptr, TkDouble2 pointPtr)); /* 48 */ + int (*tkLineToArea) _ANSI_ARGS_((double end1Ptr[], double end2Ptr[], double rectPtr[])); /* 47 */ + double (*tkLineToPoint) _ANSI_ARGS_((double end1Ptr[], double end2Ptr[], double pointPtr[])); /* 48 */ int (*tkMakeBezierCurve) _ANSI_ARGS_((Tk_Canvas canvas, double * pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[])); /* 49 */ void (*tkMakeBezierPostscript) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Canvas canvas, double * pointPtr, int numPoints)); /* 50 */ void (*tkOptionClassChanged) _ANSI_ARGS_((TkWindow * winPtr)); /* 51 */ void (*tkOptionDeadWindow) _ANSI_ARGS_((TkWindow * winPtr)); /* 52 */ int (*tkOvalToArea) _ANSI_ARGS_((double * ovalPtr, double * rectPtr)); /* 53 */ - double (*tkOvalToPoint) _ANSI_ARGS_((TkDouble4 ovalPtr, double width, int filled, TkDouble2 pointPtr)); /* 54 */ + double (*tkOvalToPoint) _ANSI_ARGS_((double ovalPtr[], double width, int filled, double pointPtr[])); /* 54 */ int (*tkpChangeFocus) _ANSI_ARGS_((TkWindow * winPtr, int force)); /* 55 */ void (*tkpCloseDisplay) _ANSI_ARGS_((TkDisplay * dispPtr)); /* 56 */ void (*tkpClaimFocus) _ANSI_ARGS_((TkWindow * topLevelPtr, int force)); /* 57 */ @@ -430,6 +473,21 @@ typedef struct TkIntStubs { void (*tkWmRestackToplevel) _ANSI_ARGS_((TkWindow * winPtr, int aboveBelow, TkWindow * otherPtr)); /* 95 */ void (*tkWmSetClass) _ANSI_ARGS_((TkWindow * winPtr)); /* 96 */ void (*tkWmUnmapWindow) _ANSI_ARGS_((TkWindow * winPtr)); /* 97 */ + Tcl_Obj * (*tkDebugBitmap) _ANSI_ARGS_((Tk_Window tkwin, char * name)); /* 98 */ + Tcl_Obj * (*tkDebugBorder) _ANSI_ARGS_((Tk_Window tkwin, char * name)); /* 99 */ + Tcl_Obj * (*tkDebugCursor) _ANSI_ARGS_((Tk_Window tkwin, char * name)); /* 100 */ + Tcl_Obj * (*tkDebugColor) _ANSI_ARGS_((Tk_Window tkwin, char * name)); /* 101 */ + Tcl_Obj * (*tkDebugConfig) _ANSI_ARGS_((Tcl_Interp * interp, Tk_OptionTable table)); /* 102 */ + Tcl_Obj * (*tkDebugFont) _ANSI_ARGS_((Tk_Window tkwin, char * name)); /* 103 */ + int (*tkFindStateNumObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * optionPtr, CONST TkStateMap * mapPtr, Tcl_Obj * keyPtr)); /* 104 */ + Tcl_HashTable * (*tkGetBitmapPredefTable) _ANSI_ARGS_((void)); /* 105 */ + TkDisplay * (*tkGetDisplayList) _ANSI_ARGS_((void)); /* 106 */ + TkMainInfo * (*tkGetMainInfoList) _ANSI_ARGS_((void)); /* 107 */ + int (*tkGetWindowFromObj) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Window tkwin, Tcl_Obj * objPtr, Tk_Window * windowPtr)); /* 108 */ + char * (*tkpGetString) _ANSI_ARGS_((TkWindow * winPtr, XEvent * eventPtr, Tcl_DString * dsPtr)); /* 109 */ + void (*tkpGetSubFonts) _ANSI_ARGS_((Tcl_Interp * interp, Tk_Font tkfont)); /* 110 */ + Tcl_Obj * (*tkpGetSystemDefault) _ANSI_ARGS_((Tk_Window tkwin, char * dbName, char * className)); /* 111 */ + void (*tkpMenuThreadInit) _ANSI_ARGS_((void)); /* 112 */ } TkIntStubs; extern TkIntStubs *tkIntStubsPtr; @@ -441,396 +499,456 @@ extern TkIntStubs *tkIntStubsPtr; */ #ifndef TkAllocWindow -#define TkAllocWindow(dispPtr, screenNum, parentPtr) \ - (tkIntStubsPtr->tkAllocWindow)(dispPtr, screenNum, parentPtr) /* 0 */ +#define TkAllocWindow \ + (tkIntStubsPtr->tkAllocWindow) /* 0 */ #endif #ifndef TkBezierPoints -#define TkBezierPoints(control, numSteps, coordPtr) \ - (tkIntStubsPtr->tkBezierPoints)(control, numSteps, coordPtr) /* 1 */ +#define TkBezierPoints \ + (tkIntStubsPtr->tkBezierPoints) /* 1 */ #endif #ifndef TkBezierScreenPoints -#define TkBezierScreenPoints(canvas, control, numSteps, xPointPtr) \ - (tkIntStubsPtr->tkBezierScreenPoints)(canvas, control, numSteps, xPointPtr) /* 2 */ +#define TkBezierScreenPoints \ + (tkIntStubsPtr->tkBezierScreenPoints) /* 2 */ #endif #ifndef TkBindDeadWindow -#define TkBindDeadWindow(winPtr) \ - (tkIntStubsPtr->tkBindDeadWindow)(winPtr) /* 3 */ +#define TkBindDeadWindow \ + (tkIntStubsPtr->tkBindDeadWindow) /* 3 */ #endif #ifndef TkBindEventProc -#define TkBindEventProc(winPtr, eventPtr) \ - (tkIntStubsPtr->tkBindEventProc)(winPtr, eventPtr) /* 4 */ +#define TkBindEventProc \ + (tkIntStubsPtr->tkBindEventProc) /* 4 */ #endif #ifndef TkBindFree -#define TkBindFree(mainPtr) \ - (tkIntStubsPtr->tkBindFree)(mainPtr) /* 5 */ +#define TkBindFree \ + (tkIntStubsPtr->tkBindFree) /* 5 */ #endif #ifndef TkBindInit -#define TkBindInit(mainPtr) \ - (tkIntStubsPtr->tkBindInit)(mainPtr) /* 6 */ +#define TkBindInit \ + (tkIntStubsPtr->tkBindInit) /* 6 */ #endif #ifndef TkChangeEventWindow -#define TkChangeEventWindow(eventPtr, winPtr) \ - (tkIntStubsPtr->tkChangeEventWindow)(eventPtr, winPtr) /* 7 */ +#define TkChangeEventWindow \ + (tkIntStubsPtr->tkChangeEventWindow) /* 7 */ #endif #ifndef TkClipInit -#define TkClipInit(interp, dispPtr) \ - (tkIntStubsPtr->tkClipInit)(interp, dispPtr) /* 8 */ +#define TkClipInit \ + (tkIntStubsPtr->tkClipInit) /* 8 */ #endif #ifndef TkComputeAnchor -#define TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr) \ - (tkIntStubsPtr->tkComputeAnchor)(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr) /* 9 */ +#define TkComputeAnchor \ + (tkIntStubsPtr->tkComputeAnchor) /* 9 */ #endif #ifndef TkCopyAndGlobalEval -#define TkCopyAndGlobalEval(interp, script) \ - (tkIntStubsPtr->tkCopyAndGlobalEval)(interp, script) /* 10 */ +#define TkCopyAndGlobalEval \ + (tkIntStubsPtr->tkCopyAndGlobalEval) /* 10 */ #endif #ifndef TkCreateBindingProcedure -#define TkCreateBindingProcedure(interp, bindingTable, object, eventString, evalProc, freeProc, clientData) \ - (tkIntStubsPtr->tkCreateBindingProcedure)(interp, bindingTable, object, eventString, evalProc, freeProc, clientData) /* 11 */ +#define TkCreateBindingProcedure \ + (tkIntStubsPtr->tkCreateBindingProcedure) /* 11 */ #endif #ifndef TkCreateCursorFromData -#define TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot, fg, bg) \ - (tkIntStubsPtr->tkCreateCursorFromData)(tkwin, source, mask, width, height, xHot, yHot, fg, bg) /* 12 */ +#define TkCreateCursorFromData \ + (tkIntStubsPtr->tkCreateCursorFromData) /* 12 */ #endif #ifndef TkCreateFrame -#define TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) \ - (tkIntStubsPtr->tkCreateFrame)(clientData, interp, argc, argv, toplevel, appName) /* 13 */ +#define TkCreateFrame \ + (tkIntStubsPtr->tkCreateFrame) /* 13 */ #endif #ifndef TkCreateMainWindow -#define TkCreateMainWindow(interp, screenName, baseName) \ - (tkIntStubsPtr->tkCreateMainWindow)(interp, screenName, baseName) /* 14 */ +#define TkCreateMainWindow \ + (tkIntStubsPtr->tkCreateMainWindow) /* 14 */ #endif #ifndef TkCurrentTime -#define TkCurrentTime(dispPtr) \ - (tkIntStubsPtr->tkCurrentTime)(dispPtr) /* 15 */ +#define TkCurrentTime \ + (tkIntStubsPtr->tkCurrentTime) /* 15 */ #endif #ifndef TkDeleteAllImages -#define TkDeleteAllImages(mainPtr) \ - (tkIntStubsPtr->tkDeleteAllImages)(mainPtr) /* 16 */ +#define TkDeleteAllImages \ + (tkIntStubsPtr->tkDeleteAllImages) /* 16 */ #endif #ifndef TkDoConfigureNotify -#define TkDoConfigureNotify(winPtr) \ - (tkIntStubsPtr->tkDoConfigureNotify)(winPtr) /* 17 */ +#define TkDoConfigureNotify \ + (tkIntStubsPtr->tkDoConfigureNotify) /* 17 */ #endif #ifndef TkDrawInsetFocusHighlight -#define TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, padding) \ - (tkIntStubsPtr->tkDrawInsetFocusHighlight)(tkwin, gc, width, drawable, padding) /* 18 */ +#define TkDrawInsetFocusHighlight \ + (tkIntStubsPtr->tkDrawInsetFocusHighlight) /* 18 */ #endif #ifndef TkEventDeadWindow -#define TkEventDeadWindow(winPtr) \ - (tkIntStubsPtr->tkEventDeadWindow)(winPtr) /* 19 */ +#define TkEventDeadWindow \ + (tkIntStubsPtr->tkEventDeadWindow) /* 19 */ #endif #ifndef TkFillPolygon -#define TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC) \ - (tkIntStubsPtr->tkFillPolygon)(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC) /* 20 */ +#define TkFillPolygon \ + (tkIntStubsPtr->tkFillPolygon) /* 20 */ #endif #ifndef TkFindStateNum -#define TkFindStateNum(interp, option, mapPtr, strKey) \ - (tkIntStubsPtr->tkFindStateNum)(interp, option, mapPtr, strKey) /* 21 */ +#define TkFindStateNum \ + (tkIntStubsPtr->tkFindStateNum) /* 21 */ #endif #ifndef TkFindStateString -#define TkFindStateString(mapPtr, numKey) \ - (tkIntStubsPtr->tkFindStateString)(mapPtr, numKey) /* 22 */ +#define TkFindStateString \ + (tkIntStubsPtr->tkFindStateString) /* 22 */ #endif #ifndef TkFocusDeadWindow -#define TkFocusDeadWindow(winPtr) \ - (tkIntStubsPtr->tkFocusDeadWindow)(winPtr) /* 23 */ +#define TkFocusDeadWindow \ + (tkIntStubsPtr->tkFocusDeadWindow) /* 23 */ #endif #ifndef TkFocusFilterEvent -#define TkFocusFilterEvent(winPtr, eventPtr) \ - (tkIntStubsPtr->tkFocusFilterEvent)(winPtr, eventPtr) /* 24 */ +#define TkFocusFilterEvent \ + (tkIntStubsPtr->tkFocusFilterEvent) /* 24 */ #endif #ifndef TkFocusKeyEvent -#define TkFocusKeyEvent(winPtr, eventPtr) \ - (tkIntStubsPtr->tkFocusKeyEvent)(winPtr, eventPtr) /* 25 */ +#define TkFocusKeyEvent \ + (tkIntStubsPtr->tkFocusKeyEvent) /* 25 */ #endif #ifndef TkFontPkgInit -#define TkFontPkgInit(mainPtr) \ - (tkIntStubsPtr->tkFontPkgInit)(mainPtr) /* 26 */ +#define TkFontPkgInit \ + (tkIntStubsPtr->tkFontPkgInit) /* 26 */ #endif #ifndef TkFontPkgFree -#define TkFontPkgFree(mainPtr) \ - (tkIntStubsPtr->tkFontPkgFree)(mainPtr) /* 27 */ +#define TkFontPkgFree \ + (tkIntStubsPtr->tkFontPkgFree) /* 27 */ #endif #ifndef TkFreeBindingTags -#define TkFreeBindingTags(winPtr) \ - (tkIntStubsPtr->tkFreeBindingTags)(winPtr) /* 28 */ +#define TkFreeBindingTags \ + (tkIntStubsPtr->tkFreeBindingTags) /* 28 */ #endif -#ifndef TkFreeCursor -#define TkFreeCursor(cursorPtr) \ - (tkIntStubsPtr->tkFreeCursor)(cursorPtr) /* 29 */ +#ifndef TkpFreeCursor +#define TkpFreeCursor \ + (tkIntStubsPtr->tkpFreeCursor) /* 29 */ #endif #ifndef TkGetBitmapData -#define TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr, hotXPtr, hotYPtr) \ - (tkIntStubsPtr->tkGetBitmapData)(interp, string, fileName, widthPtr, heightPtr, hotXPtr, hotYPtr) /* 30 */ +#define TkGetBitmapData \ + (tkIntStubsPtr->tkGetBitmapData) /* 30 */ #endif #ifndef TkGetButtPoints -#define TkGetButtPoints(p1, p2, width, project, m1, m2) \ - (tkIntStubsPtr->tkGetButtPoints)(p1, p2, width, project, m1, m2) /* 31 */ +#define TkGetButtPoints \ + (tkIntStubsPtr->tkGetButtPoints) /* 31 */ #endif #ifndef TkGetCursorByName -#define TkGetCursorByName(interp, tkwin, string) \ - (tkIntStubsPtr->tkGetCursorByName)(interp, tkwin, string) /* 32 */ +#define TkGetCursorByName \ + (tkIntStubsPtr->tkGetCursorByName) /* 32 */ #endif #ifndef TkGetDefaultScreenName -#define TkGetDefaultScreenName(interp, screenName) \ - (tkIntStubsPtr->tkGetDefaultScreenName)(interp, screenName) /* 33 */ +#define TkGetDefaultScreenName \ + (tkIntStubsPtr->tkGetDefaultScreenName) /* 33 */ #endif #ifndef TkGetDisplay -#define TkGetDisplay(display) \ - (tkIntStubsPtr->tkGetDisplay)(display) /* 34 */ +#define TkGetDisplay \ + (tkIntStubsPtr->tkGetDisplay) /* 34 */ #endif #ifndef TkGetDisplayOf -#define TkGetDisplayOf(interp, objc, objv, tkwinPtr) \ - (tkIntStubsPtr->tkGetDisplayOf)(interp, objc, objv, tkwinPtr) /* 35 */ +#define TkGetDisplayOf \ + (tkIntStubsPtr->tkGetDisplayOf) /* 35 */ #endif #ifndef TkGetFocusWin -#define TkGetFocusWin(winPtr) \ - (tkIntStubsPtr->tkGetFocusWin)(winPtr) /* 36 */ +#define TkGetFocusWin \ + (tkIntStubsPtr->tkGetFocusWin) /* 36 */ #endif #ifndef TkGetInterpNames -#define TkGetInterpNames(interp, tkwin) \ - (tkIntStubsPtr->tkGetInterpNames)(interp, tkwin) /* 37 */ +#define TkGetInterpNames \ + (tkIntStubsPtr->tkGetInterpNames) /* 37 */ #endif #ifndef TkGetMiterPoints -#define TkGetMiterPoints(p1, p2, p3, width, m1, m2) \ - (tkIntStubsPtr->tkGetMiterPoints)(p1, p2, p3, width, m1, m2) /* 38 */ +#define TkGetMiterPoints \ + (tkIntStubsPtr->tkGetMiterPoints) /* 38 */ #endif #ifndef TkGetPointerCoords -#define TkGetPointerCoords(tkwin, xPtr, yPtr) \ - (tkIntStubsPtr->tkGetPointerCoords)(tkwin, xPtr, yPtr) /* 39 */ +#define TkGetPointerCoords \ + (tkIntStubsPtr->tkGetPointerCoords) /* 39 */ #endif #ifndef TkGetServerInfo -#define TkGetServerInfo(interp, tkwin) \ - (tkIntStubsPtr->tkGetServerInfo)(interp, tkwin) /* 40 */ +#define TkGetServerInfo \ + (tkIntStubsPtr->tkGetServerInfo) /* 40 */ #endif #ifndef TkGrabDeadWindow -#define TkGrabDeadWindow(winPtr) \ - (tkIntStubsPtr->tkGrabDeadWindow)(winPtr) /* 41 */ +#define TkGrabDeadWindow \ + (tkIntStubsPtr->tkGrabDeadWindow) /* 41 */ #endif #ifndef TkGrabState -#define TkGrabState(winPtr) \ - (tkIntStubsPtr->tkGrabState)(winPtr) /* 42 */ +#define TkGrabState \ + (tkIntStubsPtr->tkGrabState) /* 42 */ #endif #ifndef TkIncludePoint -#define TkIncludePoint(itemPtr, pointPtr) \ - (tkIntStubsPtr->tkIncludePoint)(itemPtr, pointPtr) /* 43 */ +#define TkIncludePoint \ + (tkIntStubsPtr->tkIncludePoint) /* 43 */ #endif #ifndef TkInOutEvents -#define TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position) \ - (tkIntStubsPtr->tkInOutEvents)(eventPtr, sourcePtr, destPtr, leaveType, enterType, position) /* 44 */ +#define TkInOutEvents \ + (tkIntStubsPtr->tkInOutEvents) /* 44 */ #endif #ifndef TkInstallFrameMenu -#define TkInstallFrameMenu(tkwin) \ - (tkIntStubsPtr->tkInstallFrameMenu)(tkwin) /* 45 */ +#define TkInstallFrameMenu \ + (tkIntStubsPtr->tkInstallFrameMenu) /* 45 */ #endif #ifndef TkKeysymToString -#define TkKeysymToString(keysym) \ - (tkIntStubsPtr->tkKeysymToString)(keysym) /* 46 */ +#define TkKeysymToString \ + (tkIntStubsPtr->tkKeysymToString) /* 46 */ #endif #ifndef TkLineToArea -#define TkLineToArea(end1Ptr, end2Ptr, rectPtr) \ - (tkIntStubsPtr->tkLineToArea)(end1Ptr, end2Ptr, rectPtr) /* 47 */ +#define TkLineToArea \ + (tkIntStubsPtr->tkLineToArea) /* 47 */ #endif #ifndef TkLineToPoint -#define TkLineToPoint(end1Ptr, end2Ptr, pointPtr) \ - (tkIntStubsPtr->tkLineToPoint)(end1Ptr, end2Ptr, pointPtr) /* 48 */ +#define TkLineToPoint \ + (tkIntStubsPtr->tkLineToPoint) /* 48 */ #endif #ifndef TkMakeBezierCurve -#define TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) \ - (tkIntStubsPtr->tkMakeBezierCurve)(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) /* 49 */ +#define TkMakeBezierCurve \ + (tkIntStubsPtr->tkMakeBezierCurve) /* 49 */ #endif #ifndef TkMakeBezierPostscript -#define TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints) \ - (tkIntStubsPtr->tkMakeBezierPostscript)(interp, canvas, pointPtr, numPoints) /* 50 */ +#define TkMakeBezierPostscript \ + (tkIntStubsPtr->tkMakeBezierPostscript) /* 50 */ #endif #ifndef TkOptionClassChanged -#define TkOptionClassChanged(winPtr) \ - (tkIntStubsPtr->tkOptionClassChanged)(winPtr) /* 51 */ +#define TkOptionClassChanged \ + (tkIntStubsPtr->tkOptionClassChanged) /* 51 */ #endif #ifndef TkOptionDeadWindow -#define TkOptionDeadWindow(winPtr) \ - (tkIntStubsPtr->tkOptionDeadWindow)(winPtr) /* 52 */ +#define TkOptionDeadWindow \ + (tkIntStubsPtr->tkOptionDeadWindow) /* 52 */ #endif #ifndef TkOvalToArea -#define TkOvalToArea(ovalPtr, rectPtr) \ - (tkIntStubsPtr->tkOvalToArea)(ovalPtr, rectPtr) /* 53 */ +#define TkOvalToArea \ + (tkIntStubsPtr->tkOvalToArea) /* 53 */ #endif #ifndef TkOvalToPoint -#define TkOvalToPoint(ovalPtr, width, filled, pointPtr) \ - (tkIntStubsPtr->tkOvalToPoint)(ovalPtr, width, filled, pointPtr) /* 54 */ +#define TkOvalToPoint \ + (tkIntStubsPtr->tkOvalToPoint) /* 54 */ #endif #ifndef TkpChangeFocus -#define TkpChangeFocus(winPtr, force) \ - (tkIntStubsPtr->tkpChangeFocus)(winPtr, force) /* 55 */ +#define TkpChangeFocus \ + (tkIntStubsPtr->tkpChangeFocus) /* 55 */ #endif #ifndef TkpCloseDisplay -#define TkpCloseDisplay(dispPtr) \ - (tkIntStubsPtr->tkpCloseDisplay)(dispPtr) /* 56 */ +#define TkpCloseDisplay \ + (tkIntStubsPtr->tkpCloseDisplay) /* 56 */ #endif #ifndef TkpClaimFocus -#define TkpClaimFocus(topLevelPtr, force) \ - (tkIntStubsPtr->tkpClaimFocus)(topLevelPtr, force) /* 57 */ +#define TkpClaimFocus \ + (tkIntStubsPtr->tkpClaimFocus) /* 57 */ #endif #ifndef TkpDisplayWarning -#define TkpDisplayWarning(msg, title) \ - (tkIntStubsPtr->tkpDisplayWarning)(msg, title) /* 58 */ +#define TkpDisplayWarning \ + (tkIntStubsPtr->tkpDisplayWarning) /* 58 */ #endif #ifndef TkpGetAppName -#define TkpGetAppName(interp, name) \ - (tkIntStubsPtr->tkpGetAppName)(interp, name) /* 59 */ +#define TkpGetAppName \ + (tkIntStubsPtr->tkpGetAppName) /* 59 */ #endif #ifndef TkpGetOtherWindow -#define TkpGetOtherWindow(winPtr) \ - (tkIntStubsPtr->tkpGetOtherWindow)(winPtr) /* 60 */ +#define TkpGetOtherWindow \ + (tkIntStubsPtr->tkpGetOtherWindow) /* 60 */ #endif #ifndef TkpGetWrapperWindow -#define TkpGetWrapperWindow(winPtr) \ - (tkIntStubsPtr->tkpGetWrapperWindow)(winPtr) /* 61 */ +#define TkpGetWrapperWindow \ + (tkIntStubsPtr->tkpGetWrapperWindow) /* 61 */ #endif #ifndef TkpInit -#define TkpInit(interp) \ - (tkIntStubsPtr->tkpInit)(interp) /* 62 */ +#define TkpInit \ + (tkIntStubsPtr->tkpInit) /* 62 */ #endif #ifndef TkpInitializeMenuBindings -#define TkpInitializeMenuBindings(interp, bindingTable) \ - (tkIntStubsPtr->tkpInitializeMenuBindings)(interp, bindingTable) /* 63 */ +#define TkpInitializeMenuBindings \ + (tkIntStubsPtr->tkpInitializeMenuBindings) /* 63 */ #endif #ifndef TkpMakeContainer -#define TkpMakeContainer(tkwin) \ - (tkIntStubsPtr->tkpMakeContainer)(tkwin) /* 64 */ +#define TkpMakeContainer \ + (tkIntStubsPtr->tkpMakeContainer) /* 64 */ #endif #ifndef TkpMakeMenuWindow -#define TkpMakeMenuWindow(tkwin, transient) \ - (tkIntStubsPtr->tkpMakeMenuWindow)(tkwin, transient) /* 65 */ +#define TkpMakeMenuWindow \ + (tkIntStubsPtr->tkpMakeMenuWindow) /* 65 */ #endif #ifndef TkpMakeWindow -#define TkpMakeWindow(winPtr, parent) \ - (tkIntStubsPtr->tkpMakeWindow)(winPtr, parent) /* 66 */ +#define TkpMakeWindow \ + (tkIntStubsPtr->tkpMakeWindow) /* 66 */ #endif #ifndef TkpMenuNotifyToplevelCreate -#define TkpMenuNotifyToplevelCreate(interp1, menuName) \ - (tkIntStubsPtr->tkpMenuNotifyToplevelCreate)(interp1, menuName) /* 67 */ +#define TkpMenuNotifyToplevelCreate \ + (tkIntStubsPtr->tkpMenuNotifyToplevelCreate) /* 67 */ #endif #ifndef TkpOpenDisplay -#define TkpOpenDisplay(display_name) \ - (tkIntStubsPtr->tkpOpenDisplay)(display_name) /* 68 */ +#define TkpOpenDisplay \ + (tkIntStubsPtr->tkpOpenDisplay) /* 68 */ #endif #ifndef TkPointerEvent -#define TkPointerEvent(eventPtr, winPtr) \ - (tkIntStubsPtr->tkPointerEvent)(eventPtr, winPtr) /* 69 */ +#define TkPointerEvent \ + (tkIntStubsPtr->tkPointerEvent) /* 69 */ #endif #ifndef TkPolygonToArea -#define TkPolygonToArea(polyPtr, numPoints, rectPtr) \ - (tkIntStubsPtr->tkPolygonToArea)(polyPtr, numPoints, rectPtr) /* 70 */ +#define TkPolygonToArea \ + (tkIntStubsPtr->tkPolygonToArea) /* 70 */ #endif #ifndef TkPolygonToPoint -#define TkPolygonToPoint(polyPtr, numPoints, pointPtr) \ - (tkIntStubsPtr->tkPolygonToPoint)(polyPtr, numPoints, pointPtr) /* 71 */ +#define TkPolygonToPoint \ + (tkIntStubsPtr->tkPolygonToPoint) /* 71 */ #endif #ifndef TkPositionInTree -#define TkPositionInTree(winPtr, treePtr) \ - (tkIntStubsPtr->tkPositionInTree)(winPtr, treePtr) /* 72 */ +#define TkPositionInTree \ + (tkIntStubsPtr->tkPositionInTree) /* 72 */ #endif #ifndef TkpRedirectKeyEvent -#define TkpRedirectKeyEvent(winPtr, eventPtr) \ - (tkIntStubsPtr->tkpRedirectKeyEvent)(winPtr, eventPtr) /* 73 */ +#define TkpRedirectKeyEvent \ + (tkIntStubsPtr->tkpRedirectKeyEvent) /* 73 */ #endif #ifndef TkpSetMainMenubar -#define TkpSetMainMenubar(interp, tkwin, menuName) \ - (tkIntStubsPtr->tkpSetMainMenubar)(interp, tkwin, menuName) /* 74 */ +#define TkpSetMainMenubar \ + (tkIntStubsPtr->tkpSetMainMenubar) /* 74 */ #endif #ifndef TkpUseWindow -#define TkpUseWindow(interp, tkwin, string) \ - (tkIntStubsPtr->tkpUseWindow)(interp, tkwin, string) /* 75 */ +#define TkpUseWindow \ + (tkIntStubsPtr->tkpUseWindow) /* 75 */ #endif #ifndef TkpWindowWasRecentlyDeleted -#define TkpWindowWasRecentlyDeleted(win, dispPtr) \ - (tkIntStubsPtr->tkpWindowWasRecentlyDeleted)(win, dispPtr) /* 76 */ +#define TkpWindowWasRecentlyDeleted \ + (tkIntStubsPtr->tkpWindowWasRecentlyDeleted) /* 76 */ #endif #ifndef TkQueueEventForAllChildren -#define TkQueueEventForAllChildren(winPtr, eventPtr) \ - (tkIntStubsPtr->tkQueueEventForAllChildren)(winPtr, eventPtr) /* 77 */ +#define TkQueueEventForAllChildren \ + (tkIntStubsPtr->tkQueueEventForAllChildren) /* 77 */ #endif #ifndef TkReadBitmapFile -#define TkReadBitmapFile(display, d, filename, width_return, height_return, bitmap_return, x_hot_return, y_hot_return) \ - (tkIntStubsPtr->tkReadBitmapFile)(display, d, filename, width_return, height_return, bitmap_return, x_hot_return, y_hot_return) /* 78 */ +#define TkReadBitmapFile \ + (tkIntStubsPtr->tkReadBitmapFile) /* 78 */ #endif #ifndef TkScrollWindow -#define TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn) \ - (tkIntStubsPtr->tkScrollWindow)(tkwin, gc, x, y, width, height, dx, dy, damageRgn) /* 79 */ +#define TkScrollWindow \ + (tkIntStubsPtr->tkScrollWindow) /* 79 */ #endif #ifndef TkSelDeadWindow -#define TkSelDeadWindow(winPtr) \ - (tkIntStubsPtr->tkSelDeadWindow)(winPtr) /* 80 */ +#define TkSelDeadWindow \ + (tkIntStubsPtr->tkSelDeadWindow) /* 80 */ #endif #ifndef TkSelEventProc -#define TkSelEventProc(tkwin, eventPtr) \ - (tkIntStubsPtr->tkSelEventProc)(tkwin, eventPtr) /* 81 */ +#define TkSelEventProc \ + (tkIntStubsPtr->tkSelEventProc) /* 81 */ #endif #ifndef TkSelInit -#define TkSelInit(tkwin) \ - (tkIntStubsPtr->tkSelInit)(tkwin) /* 82 */ +#define TkSelInit \ + (tkIntStubsPtr->tkSelInit) /* 82 */ #endif #ifndef TkSelPropProc -#define TkSelPropProc(eventPtr) \ - (tkIntStubsPtr->tkSelPropProc)(eventPtr) /* 83 */ +#define TkSelPropProc \ + (tkIntStubsPtr->tkSelPropProc) /* 83 */ #endif #ifndef TkSetClassProcs -#define TkSetClassProcs(tkwin, procs, instanceData) \ - (tkIntStubsPtr->tkSetClassProcs)(tkwin, procs, instanceData) /* 84 */ +#define TkSetClassProcs \ + (tkIntStubsPtr->tkSetClassProcs) /* 84 */ #endif #ifndef TkSetWindowMenuBar -#define TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName) \ - (tkIntStubsPtr->tkSetWindowMenuBar)(interp, tkwin, oldMenuName, menuName) /* 85 */ +#define TkSetWindowMenuBar \ + (tkIntStubsPtr->tkSetWindowMenuBar) /* 85 */ #endif #ifndef TkStringToKeysym -#define TkStringToKeysym(name) \ - (tkIntStubsPtr->tkStringToKeysym)(name) /* 86 */ +#define TkStringToKeysym \ + (tkIntStubsPtr->tkStringToKeysym) /* 86 */ #endif #ifndef TkThickPolyLineToArea -#define TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr) \ - (tkIntStubsPtr->tkThickPolyLineToArea)(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr) /* 87 */ +#define TkThickPolyLineToArea \ + (tkIntStubsPtr->tkThickPolyLineToArea) /* 87 */ #endif #ifndef TkWmAddToColormapWindows -#define TkWmAddToColormapWindows(winPtr) \ - (tkIntStubsPtr->tkWmAddToColormapWindows)(winPtr) /* 88 */ +#define TkWmAddToColormapWindows \ + (tkIntStubsPtr->tkWmAddToColormapWindows) /* 88 */ #endif #ifndef TkWmDeadWindow -#define TkWmDeadWindow(winPtr) \ - (tkIntStubsPtr->tkWmDeadWindow)(winPtr) /* 89 */ +#define TkWmDeadWindow \ + (tkIntStubsPtr->tkWmDeadWindow) /* 89 */ #endif #ifndef TkWmFocusToplevel -#define TkWmFocusToplevel(winPtr) \ - (tkIntStubsPtr->tkWmFocusToplevel)(winPtr) /* 90 */ +#define TkWmFocusToplevel \ + (tkIntStubsPtr->tkWmFocusToplevel) /* 90 */ #endif #ifndef TkWmMapWindow -#define TkWmMapWindow(winPtr) \ - (tkIntStubsPtr->tkWmMapWindow)(winPtr) /* 91 */ +#define TkWmMapWindow \ + (tkIntStubsPtr->tkWmMapWindow) /* 91 */ #endif #ifndef TkWmNewWindow -#define TkWmNewWindow(winPtr) \ - (tkIntStubsPtr->tkWmNewWindow)(winPtr) /* 92 */ +#define TkWmNewWindow \ + (tkIntStubsPtr->tkWmNewWindow) /* 92 */ #endif #ifndef TkWmProtocolEventProc -#define TkWmProtocolEventProc(winPtr, evenvPtr) \ - (tkIntStubsPtr->tkWmProtocolEventProc)(winPtr, evenvPtr) /* 93 */ +#define TkWmProtocolEventProc \ + (tkIntStubsPtr->tkWmProtocolEventProc) /* 93 */ #endif #ifndef TkWmRemoveFromColormapWindows -#define TkWmRemoveFromColormapWindows(winPtr) \ - (tkIntStubsPtr->tkWmRemoveFromColormapWindows)(winPtr) /* 94 */ +#define TkWmRemoveFromColormapWindows \ + (tkIntStubsPtr->tkWmRemoveFromColormapWindows) /* 94 */ #endif #ifndef TkWmRestackToplevel -#define TkWmRestackToplevel(winPtr, aboveBelow, otherPtr) \ - (tkIntStubsPtr->tkWmRestackToplevel)(winPtr, aboveBelow, otherPtr) /* 95 */ +#define TkWmRestackToplevel \ + (tkIntStubsPtr->tkWmRestackToplevel) /* 95 */ #endif #ifndef TkWmSetClass -#define TkWmSetClass(winPtr) \ - (tkIntStubsPtr->tkWmSetClass)(winPtr) /* 96 */ +#define TkWmSetClass \ + (tkIntStubsPtr->tkWmSetClass) /* 96 */ #endif #ifndef TkWmUnmapWindow -#define TkWmUnmapWindow(winPtr) \ - (tkIntStubsPtr->tkWmUnmapWindow)(winPtr) /* 97 */ +#define TkWmUnmapWindow \ + (tkIntStubsPtr->tkWmUnmapWindow) /* 97 */ +#endif +#ifndef TkDebugBitmap +#define TkDebugBitmap \ + (tkIntStubsPtr->tkDebugBitmap) /* 98 */ +#endif +#ifndef TkDebugBorder +#define TkDebugBorder \ + (tkIntStubsPtr->tkDebugBorder) /* 99 */ +#endif +#ifndef TkDebugCursor +#define TkDebugCursor \ + (tkIntStubsPtr->tkDebugCursor) /* 100 */ +#endif +#ifndef TkDebugColor +#define TkDebugColor \ + (tkIntStubsPtr->tkDebugColor) /* 101 */ +#endif +#ifndef TkDebugConfig +#define TkDebugConfig \ + (tkIntStubsPtr->tkDebugConfig) /* 102 */ +#endif +#ifndef TkDebugFont +#define TkDebugFont \ + (tkIntStubsPtr->tkDebugFont) /* 103 */ +#endif +#ifndef TkFindStateNumObj +#define TkFindStateNumObj \ + (tkIntStubsPtr->tkFindStateNumObj) /* 104 */ +#endif +#ifndef TkGetBitmapPredefTable +#define TkGetBitmapPredefTable \ + (tkIntStubsPtr->tkGetBitmapPredefTable) /* 105 */ +#endif +#ifndef TkGetDisplayList +#define TkGetDisplayList \ + (tkIntStubsPtr->tkGetDisplayList) /* 106 */ +#endif +#ifndef TkGetMainInfoList +#define TkGetMainInfoList \ + (tkIntStubsPtr->tkGetMainInfoList) /* 107 */ +#endif +#ifndef TkGetWindowFromObj +#define TkGetWindowFromObj \ + (tkIntStubsPtr->tkGetWindowFromObj) /* 108 */ +#endif +#ifndef TkpGetString +#define TkpGetString \ + (tkIntStubsPtr->tkpGetString) /* 109 */ +#endif +#ifndef TkpGetSubFonts +#define TkpGetSubFonts \ + (tkIntStubsPtr->tkpGetSubFonts) /* 110 */ +#endif +#ifndef TkpGetSystemDefault +#define TkpGetSystemDefault \ + (tkIntStubsPtr->tkpGetSystemDefault) /* 111 */ +#endif +#ifndef TkpMenuThreadInit +#define TkpMenuThreadInit \ + (tkIntStubsPtr->tkpMenuThreadInit) /* 112 */ #endif #endif /* defined(USE_TK_STUBS) && !defined(USE_TK_STUB_PROCS) */ diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h index a36f7d3..a767f68 100644 --- a/generic/tkIntPlatDecls.h +++ b/generic/tkIntPlatDecls.h @@ -9,7 +9,7 @@ * Copyright (c) 1998-1999 by Scriptics Corporation. * All rights reserved. * - * RCS: @(#) $Id: tkIntPlatDecls.h,v 1.2 1999/03/10 07:04:40 stanton Exp $ + * RCS: @(#) $Id: tkIntPlatDecls.h,v 1.3 1999/04/16 01:51:16 stanton Exp $ */ #ifndef _TKINTPLATDECLS @@ -150,6 +150,17 @@ EXTERN void TkWinWmCleanup _ANSI_ARGS_((HINSTANCE hInstance)); EXTERN void TkWinXCleanup _ANSI_ARGS_((HINSTANCE hInstance)); /* 35 */ EXTERN void TkWinXInit _ANSI_ARGS_((HINSTANCE hInstance)); +/* 36 */ +EXTERN void TkWinSetForegroundWindow _ANSI_ARGS_(( + TkWindow * winPtr)); +/* 37 */ +EXTERN void TkWinDialogDebug _ANSI_ARGS_((int debug)); +/* 38 */ +EXTERN Tcl_Obj * TkWinGetMenuSystemDefault _ANSI_ARGS_(( + Tk_Window tkwin, char * dbName, + char * className)); +/* 39 */ +EXTERN int TkWinGetPlatformId _ANSI_ARGS_((void)); #endif /* __WIN32__ */ #ifdef MAC_TCL /* 0 */ @@ -389,6 +400,10 @@ typedef struct TkIntPlatStubs { void (*tkWinWmCleanup) _ANSI_ARGS_((HINSTANCE hInstance)); /* 33 */ void (*tkWinXCleanup) _ANSI_ARGS_((HINSTANCE hInstance)); /* 34 */ void (*tkWinXInit) _ANSI_ARGS_((HINSTANCE hInstance)); /* 35 */ + void (*tkWinSetForegroundWindow) _ANSI_ARGS_((TkWindow * winPtr)); /* 36 */ + void (*tkWinDialogDebug) _ANSI_ARGS_((int debug)); /* 37 */ + Tcl_Obj * (*tkWinGetMenuSystemDefault) _ANSI_ARGS_((Tk_Window tkwin, char * dbName, char * className)); /* 38 */ + int (*tkWinGetPlatformId) _ANSI_ARGS_((void)); /* 39 */ #endif /* __WIN32__ */ #ifdef MAC_TCL void (*tkClipBox) _ANSI_ARGS_((TkRegion rgn, XRectangle* rect_return)); /* 0 */ @@ -476,472 +491,488 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr; #if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ #ifndef TkCreateXEventSource -#define TkCreateXEventSource() \ - (tkIntPlatStubsPtr->tkCreateXEventSource)() /* 0 */ +#define TkCreateXEventSource \ + (tkIntPlatStubsPtr->tkCreateXEventSource) /* 0 */ #endif #ifndef TkFreeWindowId -#define TkFreeWindowId(dispPtr, w) \ - (tkIntPlatStubsPtr->tkFreeWindowId)(dispPtr, w) /* 1 */ +#define TkFreeWindowId \ + (tkIntPlatStubsPtr->tkFreeWindowId) /* 1 */ #endif #ifndef TkInitXId -#define TkInitXId(dispPtr) \ - (tkIntPlatStubsPtr->tkInitXId)(dispPtr) /* 2 */ +#define TkInitXId \ + (tkIntPlatStubsPtr->tkInitXId) /* 2 */ #endif #ifndef TkpCmapStressed -#define TkpCmapStressed(tkwin, colormap) \ - (tkIntPlatStubsPtr->tkpCmapStressed)(tkwin, colormap) /* 3 */ +#define TkpCmapStressed \ + (tkIntPlatStubsPtr->tkpCmapStressed) /* 3 */ #endif #ifndef TkpSync -#define TkpSync(display) \ - (tkIntPlatStubsPtr->tkpSync)(display) /* 4 */ +#define TkpSync \ + (tkIntPlatStubsPtr->tkpSync) /* 4 */ #endif #ifndef TkUnixContainerId -#define TkUnixContainerId(winPtr) \ - (tkIntPlatStubsPtr->tkUnixContainerId)(winPtr) /* 5 */ +#define TkUnixContainerId \ + (tkIntPlatStubsPtr->tkUnixContainerId) /* 5 */ #endif #ifndef TkUnixDoOneXEvent -#define TkUnixDoOneXEvent(timePtr) \ - (tkIntPlatStubsPtr->tkUnixDoOneXEvent)(timePtr) /* 6 */ +#define TkUnixDoOneXEvent \ + (tkIntPlatStubsPtr->tkUnixDoOneXEvent) /* 6 */ #endif #ifndef TkUnixSetMenubar -#define TkUnixSetMenubar(tkwin, menubar) \ - (tkIntPlatStubsPtr->tkUnixSetMenubar)(tkwin, menubar) /* 7 */ +#define TkUnixSetMenubar \ + (tkIntPlatStubsPtr->tkUnixSetMenubar) /* 7 */ #endif #endif /* UNIX */ #ifdef __WIN32__ #ifndef TkAlignImageData -#define TkAlignImageData(image, alignment, bitOrder) \ - (tkIntPlatStubsPtr->tkAlignImageData)(image, alignment, bitOrder) /* 0 */ +#define TkAlignImageData \ + (tkIntPlatStubsPtr->tkAlignImageData) /* 0 */ #endif #ifndef TkClipBox -#define TkClipBox(rgn, rect_return) \ - (tkIntPlatStubsPtr->tkClipBox)(rgn, rect_return) /* 1 */ +#define TkClipBox \ + (tkIntPlatStubsPtr->tkClipBox) /* 1 */ #endif #ifndef TkCreateRegion -#define TkCreateRegion() \ - (tkIntPlatStubsPtr->tkCreateRegion)() /* 2 */ +#define TkCreateRegion \ + (tkIntPlatStubsPtr->tkCreateRegion) /* 2 */ #endif #ifndef TkDestroyRegion -#define TkDestroyRegion(rgn) \ - (tkIntPlatStubsPtr->tkDestroyRegion)(rgn) /* 3 */ +#define TkDestroyRegion \ + (tkIntPlatStubsPtr->tkDestroyRegion) /* 3 */ #endif #ifndef TkGenerateActivateEvents -#define TkGenerateActivateEvents(winPtr, active) \ - (tkIntPlatStubsPtr->tkGenerateActivateEvents)(winPtr, active) /* 4 */ +#define TkGenerateActivateEvents \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 4 */ #endif #ifndef TkIntersectRegion -#define TkIntersectRegion(sra, srcb, dr_return) \ - (tkIntPlatStubsPtr->tkIntersectRegion)(sra, srcb, dr_return) /* 5 */ +#define TkIntersectRegion \ + (tkIntPlatStubsPtr->tkIntersectRegion) /* 5 */ #endif #ifndef TkpGetMS -#define TkpGetMS() \ - (tkIntPlatStubsPtr->tkpGetMS)() /* 6 */ +#define TkpGetMS \ + (tkIntPlatStubsPtr->tkpGetMS) /* 6 */ #endif #ifndef TkPointerDeadWindow -#define TkPointerDeadWindow(winPtr) \ - (tkIntPlatStubsPtr->tkPointerDeadWindow)(winPtr) /* 7 */ +#define TkPointerDeadWindow \ + (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 7 */ #endif #ifndef TkpPrintWindowId -#define TkpPrintWindowId(buf, window) \ - (tkIntPlatStubsPtr->tkpPrintWindowId)(buf, window) /* 8 */ +#define TkpPrintWindowId \ + (tkIntPlatStubsPtr->tkpPrintWindowId) /* 8 */ #endif #ifndef TkpScanWindowId -#define TkpScanWindowId(interp, string, idPtr) \ - (tkIntPlatStubsPtr->tkpScanWindowId)(interp, string, idPtr) /* 9 */ +#define TkpScanWindowId \ + (tkIntPlatStubsPtr->tkpScanWindowId) /* 9 */ #endif #ifndef TkpSetCapture -#define TkpSetCapture(winPtr) \ - (tkIntPlatStubsPtr->tkpSetCapture)(winPtr) /* 10 */ +#define TkpSetCapture \ + (tkIntPlatStubsPtr->tkpSetCapture) /* 10 */ #endif #ifndef TkpSetCursor -#define TkpSetCursor(cursor) \ - (tkIntPlatStubsPtr->tkpSetCursor)(cursor) /* 11 */ +#define TkpSetCursor \ + (tkIntPlatStubsPtr->tkpSetCursor) /* 11 */ #endif #ifndef TkpWmSetState -#define TkpWmSetState(winPtr, state) \ - (tkIntPlatStubsPtr->tkpWmSetState)(winPtr, state) /* 12 */ +#define TkpWmSetState \ + (tkIntPlatStubsPtr->tkpWmSetState) /* 12 */ #endif #ifndef TkRectInRegion -#define TkRectInRegion(rgn, x, y, width, height) \ - (tkIntPlatStubsPtr->tkRectInRegion)(rgn, x, y, width, height) /* 13 */ +#define TkRectInRegion \ + (tkIntPlatStubsPtr->tkRectInRegion) /* 13 */ #endif #ifndef TkSetPixmapColormap -#define TkSetPixmapColormap(pixmap, colormap) \ - (tkIntPlatStubsPtr->tkSetPixmapColormap)(pixmap, colormap) /* 14 */ +#define TkSetPixmapColormap \ + (tkIntPlatStubsPtr->tkSetPixmapColormap) /* 14 */ #endif #ifndef TkSetRegion -#define TkSetRegion(display, gc, rgn) \ - (tkIntPlatStubsPtr->tkSetRegion)(display, gc, rgn) /* 15 */ +#define TkSetRegion \ + (tkIntPlatStubsPtr->tkSetRegion) /* 15 */ #endif #ifndef TkUnionRectWithRegion -#define TkUnionRectWithRegion(rect, src, dr_return) \ - (tkIntPlatStubsPtr->tkUnionRectWithRegion)(rect, src, dr_return) /* 16 */ +#define TkUnionRectWithRegion \ + (tkIntPlatStubsPtr->tkUnionRectWithRegion) /* 16 */ #endif #ifndef TkWinCancelMouseTimer -#define TkWinCancelMouseTimer() \ - (tkIntPlatStubsPtr->tkWinCancelMouseTimer)() /* 17 */ +#define TkWinCancelMouseTimer \ + (tkIntPlatStubsPtr->tkWinCancelMouseTimer) /* 17 */ #endif #ifndef TkWinClipboardRender -#define TkWinClipboardRender(dispPtr, format) \ - (tkIntPlatStubsPtr->tkWinClipboardRender)(dispPtr, format) /* 18 */ +#define TkWinClipboardRender \ + (tkIntPlatStubsPtr->tkWinClipboardRender) /* 18 */ #endif #ifndef TkWinEmbeddedEventProc -#define TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) \ - (tkIntPlatStubsPtr->tkWinEmbeddedEventProc)(hwnd, message, wParam, lParam) /* 19 */ +#define TkWinEmbeddedEventProc \ + (tkIntPlatStubsPtr->tkWinEmbeddedEventProc) /* 19 */ #endif #ifndef TkWinFillRect -#define TkWinFillRect(dc, x, y, width, height, pixel) \ - (tkIntPlatStubsPtr->tkWinFillRect)(dc, x, y, width, height, pixel) /* 20 */ +#define TkWinFillRect \ + (tkIntPlatStubsPtr->tkWinFillRect) /* 20 */ #endif #ifndef TkWinGetBorderPixels -#define TkWinGetBorderPixels(tkwin, border, which) \ - (tkIntPlatStubsPtr->tkWinGetBorderPixels)(tkwin, border, which) /* 21 */ +#define TkWinGetBorderPixels \ + (tkIntPlatStubsPtr->tkWinGetBorderPixels) /* 21 */ #endif #ifndef TkWinGetDrawableDC -#define TkWinGetDrawableDC(display, d, state) \ - (tkIntPlatStubsPtr->tkWinGetDrawableDC)(display, d, state) /* 22 */ +#define TkWinGetDrawableDC \ + (tkIntPlatStubsPtr->tkWinGetDrawableDC) /* 22 */ #endif #ifndef TkWinGetModifierState -#define TkWinGetModifierState() \ - (tkIntPlatStubsPtr->tkWinGetModifierState)() /* 23 */ +#define TkWinGetModifierState \ + (tkIntPlatStubsPtr->tkWinGetModifierState) /* 23 */ #endif #ifndef TkWinGetSystemPalette -#define TkWinGetSystemPalette() \ - (tkIntPlatStubsPtr->tkWinGetSystemPalette)() /* 24 */ +#define TkWinGetSystemPalette \ + (tkIntPlatStubsPtr->tkWinGetSystemPalette) /* 24 */ #endif #ifndef TkWinGetWrapperWindow -#define TkWinGetWrapperWindow(tkwin) \ - (tkIntPlatStubsPtr->tkWinGetWrapperWindow)(tkwin) /* 25 */ +#define TkWinGetWrapperWindow \ + (tkIntPlatStubsPtr->tkWinGetWrapperWindow) /* 25 */ #endif #ifndef TkWinHandleMenuEvent -#define TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) \ - (tkIntPlatStubsPtr->tkWinHandleMenuEvent)(phwnd, pMessage, pwParam, plParam, plResult) /* 26 */ +#define TkWinHandleMenuEvent \ + (tkIntPlatStubsPtr->tkWinHandleMenuEvent) /* 26 */ #endif #ifndef TkWinIndexOfColor -#define TkWinIndexOfColor(colorPtr) \ - (tkIntPlatStubsPtr->tkWinIndexOfColor)(colorPtr) /* 27 */ +#define TkWinIndexOfColor \ + (tkIntPlatStubsPtr->tkWinIndexOfColor) /* 27 */ #endif #ifndef TkWinReleaseDrawableDC -#define TkWinReleaseDrawableDC(d, hdc, state) \ - (tkIntPlatStubsPtr->tkWinReleaseDrawableDC)(d, hdc, state) /* 28 */ +#define TkWinReleaseDrawableDC \ + (tkIntPlatStubsPtr->tkWinReleaseDrawableDC) /* 28 */ #endif #ifndef TkWinResendEvent -#define TkWinResendEvent(wndproc, hwnd, eventPtr) \ - (tkIntPlatStubsPtr->tkWinResendEvent)(wndproc, hwnd, eventPtr) /* 29 */ +#define TkWinResendEvent \ + (tkIntPlatStubsPtr->tkWinResendEvent) /* 29 */ #endif #ifndef TkWinSelectPalette -#define TkWinSelectPalette(dc, colormap) \ - (tkIntPlatStubsPtr->tkWinSelectPalette)(dc, colormap) /* 30 */ +#define TkWinSelectPalette \ + (tkIntPlatStubsPtr->tkWinSelectPalette) /* 30 */ #endif #ifndef TkWinSetMenu -#define TkWinSetMenu(tkwin, hMenu) \ - (tkIntPlatStubsPtr->tkWinSetMenu)(tkwin, hMenu) /* 31 */ +#define TkWinSetMenu \ + (tkIntPlatStubsPtr->tkWinSetMenu) /* 31 */ #endif #ifndef TkWinSetWindowPos -#define TkWinSetWindowPos(hwnd, siblingHwnd, pos) \ - (tkIntPlatStubsPtr->tkWinSetWindowPos)(hwnd, siblingHwnd, pos) /* 32 */ +#define TkWinSetWindowPos \ + (tkIntPlatStubsPtr->tkWinSetWindowPos) /* 32 */ #endif #ifndef TkWinWmCleanup -#define TkWinWmCleanup(hInstance) \ - (tkIntPlatStubsPtr->tkWinWmCleanup)(hInstance) /* 33 */ +#define TkWinWmCleanup \ + (tkIntPlatStubsPtr->tkWinWmCleanup) /* 33 */ #endif #ifndef TkWinXCleanup -#define TkWinXCleanup(hInstance) \ - (tkIntPlatStubsPtr->tkWinXCleanup)(hInstance) /* 34 */ +#define TkWinXCleanup \ + (tkIntPlatStubsPtr->tkWinXCleanup) /* 34 */ #endif #ifndef TkWinXInit -#define TkWinXInit(hInstance) \ - (tkIntPlatStubsPtr->tkWinXInit)(hInstance) /* 35 */ +#define TkWinXInit \ + (tkIntPlatStubsPtr->tkWinXInit) /* 35 */ +#endif +#ifndef TkWinSetForegroundWindow +#define TkWinSetForegroundWindow \ + (tkIntPlatStubsPtr->tkWinSetForegroundWindow) /* 36 */ +#endif +#ifndef TkWinDialogDebug +#define TkWinDialogDebug \ + (tkIntPlatStubsPtr->tkWinDialogDebug) /* 37 */ +#endif +#ifndef TkWinGetMenuSystemDefault +#define TkWinGetMenuSystemDefault \ + (tkIntPlatStubsPtr->tkWinGetMenuSystemDefault) /* 38 */ +#endif +#ifndef TkWinGetPlatformId +#define TkWinGetPlatformId \ + (tkIntPlatStubsPtr->tkWinGetPlatformId) /* 39 */ #endif #endif /* __WIN32__ */ #ifdef MAC_TCL #ifndef TkClipBox -#define TkClipBox(rgn, rect_return) \ - (tkIntPlatStubsPtr->tkClipBox)(rgn, rect_return) /* 0 */ +#define TkClipBox \ + (tkIntPlatStubsPtr->tkClipBox) /* 0 */ #endif #ifndef TkCreateRegion -#define TkCreateRegion() \ - (tkIntPlatStubsPtr->tkCreateRegion)() /* 1 */ +#define TkCreateRegion \ + (tkIntPlatStubsPtr->tkCreateRegion) /* 1 */ #endif #ifndef TkDestroyRegion -#define TkDestroyRegion(rgn) \ - (tkIntPlatStubsPtr->tkDestroyRegion)(rgn) /* 2 */ +#define TkDestroyRegion \ + (tkIntPlatStubsPtr->tkDestroyRegion) /* 2 */ #endif #ifndef TkGenerateActivateEvents -#define TkGenerateActivateEvents(winPtr, active) \ - (tkIntPlatStubsPtr->tkGenerateActivateEvents)(winPtr, active) /* 3 */ +#define TkGenerateActivateEvents \ + (tkIntPlatStubsPtr->tkGenerateActivateEvents) /* 3 */ #endif #ifndef TkIntersectRegion -#define TkIntersectRegion(sra, srcb, dr_return) \ - (tkIntPlatStubsPtr->tkIntersectRegion)(sra, srcb, dr_return) /* 4 */ +#define TkIntersectRegion \ + (tkIntPlatStubsPtr->tkIntersectRegion) /* 4 */ #endif #ifndef TkpCreateNativeBitmap -#define TkpCreateNativeBitmap(display, source) \ - (tkIntPlatStubsPtr->tkpCreateNativeBitmap)(display, source) /* 5 */ +#define TkpCreateNativeBitmap \ + (tkIntPlatStubsPtr->tkpCreateNativeBitmap) /* 5 */ #endif #ifndef TkpDefineNativeBitmaps -#define TkpDefineNativeBitmaps() \ - (tkIntPlatStubsPtr->tkpDefineNativeBitmaps)() /* 6 */ +#define TkpDefineNativeBitmaps \ + (tkIntPlatStubsPtr->tkpDefineNativeBitmaps) /* 6 */ #endif #ifndef TkpGetMS -#define TkpGetMS() \ - (tkIntPlatStubsPtr->tkpGetMS)() /* 7 */ +#define TkpGetMS \ + (tkIntPlatStubsPtr->tkpGetMS) /* 7 */ #endif #ifndef TkpGetNativeAppBitmap -#define TkpGetNativeAppBitmap(display, name, width, height) \ - (tkIntPlatStubsPtr->tkpGetNativeAppBitmap)(display, name, width, height) /* 8 */ +#define TkpGetNativeAppBitmap \ + (tkIntPlatStubsPtr->tkpGetNativeAppBitmap) /* 8 */ #endif #ifndef TkPointerDeadWindow -#define TkPointerDeadWindow(winPtr) \ - (tkIntPlatStubsPtr->tkPointerDeadWindow)(winPtr) /* 9 */ +#define TkPointerDeadWindow \ + (tkIntPlatStubsPtr->tkPointerDeadWindow) /* 9 */ #endif #ifndef TkpSetCapture -#define TkpSetCapture(winPtr) \ - (tkIntPlatStubsPtr->tkpSetCapture)(winPtr) /* 10 */ +#define TkpSetCapture \ + (tkIntPlatStubsPtr->tkpSetCapture) /* 10 */ #endif #ifndef TkpSetCursor -#define TkpSetCursor(cursor) \ - (tkIntPlatStubsPtr->tkpSetCursor)(cursor) /* 11 */ +#define TkpSetCursor \ + (tkIntPlatStubsPtr->tkpSetCursor) /* 11 */ #endif #ifndef TkpWmSetState -#define TkpWmSetState(winPtr, state) \ - (tkIntPlatStubsPtr->tkpWmSetState)(winPtr, state) /* 12 */ +#define TkpWmSetState \ + (tkIntPlatStubsPtr->tkpWmSetState) /* 12 */ #endif #ifndef TkRectInRegion -#define TkRectInRegion(rgn, x, y, width, height) \ - (tkIntPlatStubsPtr->tkRectInRegion)(rgn, x, y, width, height) /* 13 */ +#define TkRectInRegion \ + (tkIntPlatStubsPtr->tkRectInRegion) /* 13 */ #endif #ifndef TkSetRegion -#define TkSetRegion(display, gc, rgn) \ - (tkIntPlatStubsPtr->tkSetRegion)(display, gc, rgn) /* 14 */ +#define TkSetRegion \ + (tkIntPlatStubsPtr->tkSetRegion) /* 14 */ #endif #ifndef TkUnionRectWithRegion -#define TkUnionRectWithRegion(rect, src, dr_return) \ - (tkIntPlatStubsPtr->tkUnionRectWithRegion)(rect, src, dr_return) /* 15 */ +#define TkUnionRectWithRegion \ + (tkIntPlatStubsPtr->tkUnionRectWithRegion) /* 15 */ #endif #ifndef HandleWMEvent -#define HandleWMEvent(theEvent) \ - (tkIntPlatStubsPtr->handleWMEvent)(theEvent) /* 16 */ +#define HandleWMEvent \ + (tkIntPlatStubsPtr->handleWMEvent) /* 16 */ #endif #ifndef TkAboutDlg -#define TkAboutDlg() \ - (tkIntPlatStubsPtr->tkAboutDlg)() /* 17 */ +#define TkAboutDlg \ + (tkIntPlatStubsPtr->tkAboutDlg) /* 17 */ #endif #ifndef TkCreateMacEventSource -#define TkCreateMacEventSource() \ - (tkIntPlatStubsPtr->tkCreateMacEventSource)() /* 18 */ +#define TkCreateMacEventSource \ + (tkIntPlatStubsPtr->tkCreateMacEventSource) /* 18 */ #endif #ifndef TkFontList -#define TkFontList(interp, display) \ - (tkIntPlatStubsPtr->tkFontList)(interp, display) /* 19 */ +#define TkFontList \ + (tkIntPlatStubsPtr->tkFontList) /* 19 */ #endif #ifndef TkGetTransientMaster -#define TkGetTransientMaster(winPtr) \ - (tkIntPlatStubsPtr->tkGetTransientMaster)(winPtr) /* 20 */ +#define TkGetTransientMaster \ + (tkIntPlatStubsPtr->tkGetTransientMaster) /* 20 */ #endif #ifndef TkGenerateButtonEvent -#define TkGenerateButtonEvent(x, y, window, state) \ - (tkIntPlatStubsPtr->tkGenerateButtonEvent)(x, y, window, state) /* 21 */ +#define TkGenerateButtonEvent \ + (tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 21 */ #endif #ifndef TkGetCharPositions -#define TkGetCharPositions(font_struct, string, count, buffer) \ - (tkIntPlatStubsPtr->tkGetCharPositions)(font_struct, string, count, buffer) /* 22 */ +#define TkGetCharPositions \ + (tkIntPlatStubsPtr->tkGetCharPositions) /* 22 */ #endif #ifndef TkGenWMDestroyEvent -#define TkGenWMDestroyEvent(tkwin) \ - (tkIntPlatStubsPtr->tkGenWMDestroyEvent)(tkwin) /* 23 */ +#define TkGenWMDestroyEvent \ + (tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 23 */ #endif #ifndef TkGenWMConfigureEvent -#define TkGenWMConfigureEvent(tkwin, x, y, width, height, flags) \ - (tkIntPlatStubsPtr->tkGenWMConfigureEvent)(tkwin, x, y, width, height, flags) /* 24 */ +#define TkGenWMConfigureEvent \ + (tkIntPlatStubsPtr->tkGenWMConfigureEvent) /* 24 */ #endif #ifndef TkMacButtonKeyState -#define TkMacButtonKeyState() \ - (tkIntPlatStubsPtr->tkMacButtonKeyState)() /* 25 */ +#define TkMacButtonKeyState \ + (tkIntPlatStubsPtr->tkMacButtonKeyState) /* 25 */ #endif #ifndef TkMacClearMenubarActive -#define TkMacClearMenubarActive() \ - (tkIntPlatStubsPtr->tkMacClearMenubarActive)() /* 26 */ +#define TkMacClearMenubarActive \ + (tkIntPlatStubsPtr->tkMacClearMenubarActive) /* 26 */ #endif #ifndef TkMacConvertEvent -#define TkMacConvertEvent(eventPtr) \ - (tkIntPlatStubsPtr->tkMacConvertEvent)(eventPtr) /* 27 */ +#define TkMacConvertEvent \ + (tkIntPlatStubsPtr->tkMacConvertEvent) /* 27 */ #endif #ifndef TkMacDispatchMenuEvent -#define TkMacDispatchMenuEvent(menuID, index) \ - (tkIntPlatStubsPtr->tkMacDispatchMenuEvent)(menuID, index) /* 28 */ +#define TkMacDispatchMenuEvent \ + (tkIntPlatStubsPtr->tkMacDispatchMenuEvent) /* 28 */ #endif #ifndef TkMacInstallCursor -#define TkMacInstallCursor(resizeOverride) \ - (tkIntPlatStubsPtr->tkMacInstallCursor)(resizeOverride) /* 29 */ +#define TkMacInstallCursor \ + (tkIntPlatStubsPtr->tkMacInstallCursor) /* 29 */ #endif #ifndef TkMacConvertTkEvent -#define TkMacConvertTkEvent(eventPtr, window) \ - (tkIntPlatStubsPtr->tkMacConvertTkEvent)(eventPtr, window) /* 30 */ +#define TkMacConvertTkEvent \ + (tkIntPlatStubsPtr->tkMacConvertTkEvent) /* 30 */ #endif #ifndef TkMacHandleTearoffMenu -#define TkMacHandleTearoffMenu() \ - (tkIntPlatStubsPtr->tkMacHandleTearoffMenu)() /* 31 */ +#define TkMacHandleTearoffMenu \ + (tkIntPlatStubsPtr->tkMacHandleTearoffMenu) /* 31 */ #endif #ifndef tkMacInstallMWConsole -#define tkMacInstallMWConsole(interp) \ - (tkIntPlatStubsPtr->tkMacInstallMWConsole)(interp) /* 32 */ +#define tkMacInstallMWConsole \ + (tkIntPlatStubsPtr->tkMacInstallMWConsole) /* 32 */ #endif #ifndef TkMacInvalClipRgns -#define TkMacInvalClipRgns(winPtr) \ - (tkIntPlatStubsPtr->tkMacInvalClipRgns)(winPtr) /* 33 */ +#define TkMacInvalClipRgns \ + (tkIntPlatStubsPtr->tkMacInvalClipRgns) /* 33 */ #endif #ifndef TkMacDoHLEvent -#define TkMacDoHLEvent(theEvent) \ - (tkIntPlatStubsPtr->tkMacDoHLEvent)(theEvent) /* 34 */ +#define TkMacDoHLEvent \ + (tkIntPlatStubsPtr->tkMacDoHLEvent) /* 34 */ #endif #ifndef TkMacFontInfo -#define TkMacFontInfo(fontId, family, style, size) \ - (tkIntPlatStubsPtr->tkMacFontInfo)(fontId, family, style, size) /* 35 */ +#define TkMacFontInfo \ + (tkIntPlatStubsPtr->tkMacFontInfo) /* 35 */ #endif #ifndef TkMacGenerateTime -#define TkMacGenerateTime() \ - (tkIntPlatStubsPtr->tkMacGenerateTime)() /* 36 */ +#define TkMacGenerateTime \ + (tkIntPlatStubsPtr->tkMacGenerateTime) /* 36 */ #endif #ifndef TkMacGetDrawablePort -#define TkMacGetDrawablePort(drawable) \ - (tkIntPlatStubsPtr->tkMacGetDrawablePort)(drawable) /* 37 */ +#define TkMacGetDrawablePort \ + (tkIntPlatStubsPtr->tkMacGetDrawablePort) /* 37 */ #endif #ifndef TkMacGetScrollbarGrowWindow -#define TkMacGetScrollbarGrowWindow(winPtr) \ - (tkIntPlatStubsPtr->tkMacGetScrollbarGrowWindow)(winPtr) /* 38 */ +#define TkMacGetScrollbarGrowWindow \ + (tkIntPlatStubsPtr->tkMacGetScrollbarGrowWindow) /* 38 */ #endif #ifndef TkMacGetXWindow -#define TkMacGetXWindow(macWinPtr) \ - (tkIntPlatStubsPtr->tkMacGetXWindow)(macWinPtr) /* 39 */ +#define TkMacGetXWindow \ + (tkIntPlatStubsPtr->tkMacGetXWindow) /* 39 */ #endif #ifndef TkMacGrowToplevel -#define TkMacGrowToplevel(whichWindow, start) \ - (tkIntPlatStubsPtr->tkMacGrowToplevel)(whichWindow, start) /* 40 */ +#define TkMacGrowToplevel \ + (tkIntPlatStubsPtr->tkMacGrowToplevel) /* 40 */ #endif #ifndef TkMacHandleMenuSelect -#define TkMacHandleMenuSelect(mResult, optionKeyPressed) \ - (tkIntPlatStubsPtr->tkMacHandleMenuSelect)(mResult, optionKeyPressed) /* 41 */ +#define TkMacHandleMenuSelect \ + (tkIntPlatStubsPtr->tkMacHandleMenuSelect) /* 41 */ #endif #ifndef TkMacHaveAppearance -#define TkMacHaveAppearance() \ - (tkIntPlatStubsPtr->tkMacHaveAppearance)() /* 42 */ +#define TkMacHaveAppearance \ + (tkIntPlatStubsPtr->tkMacHaveAppearance) /* 42 */ #endif #ifndef TkMacInitAppleEvents -#define TkMacInitAppleEvents(interp) \ - (tkIntPlatStubsPtr->tkMacInitAppleEvents)(interp) /* 43 */ +#define TkMacInitAppleEvents \ + (tkIntPlatStubsPtr->tkMacInitAppleEvents) /* 43 */ #endif #ifndef TkMacInitMenus -#define TkMacInitMenus(interp) \ - (tkIntPlatStubsPtr->tkMacInitMenus)(interp) /* 44 */ +#define TkMacInitMenus \ + (tkIntPlatStubsPtr->tkMacInitMenus) /* 44 */ #endif #ifndef TkMacInvalidateWindow -#define TkMacInvalidateWindow(macWin, flag) \ - (tkIntPlatStubsPtr->tkMacInvalidateWindow)(macWin, flag) /* 45 */ +#define TkMacInvalidateWindow \ + (tkIntPlatStubsPtr->tkMacInvalidateWindow) /* 45 */ #endif #ifndef TkMacIsCharacterMissing -#define TkMacIsCharacterMissing(tkfont, searchChar) \ - (tkIntPlatStubsPtr->tkMacIsCharacterMissing)(tkfont, searchChar) /* 46 */ +#define TkMacIsCharacterMissing \ + (tkIntPlatStubsPtr->tkMacIsCharacterMissing) /* 46 */ #endif #ifndef TkMacMakeRealWindowExist -#define TkMacMakeRealWindowExist(winPtr) \ - (tkIntPlatStubsPtr->tkMacMakeRealWindowExist)(winPtr) /* 47 */ +#define TkMacMakeRealWindowExist \ + (tkIntPlatStubsPtr->tkMacMakeRealWindowExist) /* 47 */ #endif #ifndef TkMacMakeStippleMap -#define TkMacMakeStippleMap(d1, d2) \ - (tkIntPlatStubsPtr->tkMacMakeStippleMap)(d1, d2) /* 48 */ +#define TkMacMakeStippleMap \ + (tkIntPlatStubsPtr->tkMacMakeStippleMap) /* 48 */ #endif #ifndef TkMacMenuClick -#define TkMacMenuClick() \ - (tkIntPlatStubsPtr->tkMacMenuClick)() /* 49 */ +#define TkMacMenuClick \ + (tkIntPlatStubsPtr->tkMacMenuClick) /* 49 */ #endif #ifndef TkMacRegisterOffScreenWindow -#define TkMacRegisterOffScreenWindow(window, portPtr) \ - (tkIntPlatStubsPtr->tkMacRegisterOffScreenWindow)(window, portPtr) /* 50 */ +#define TkMacRegisterOffScreenWindow \ + (tkIntPlatStubsPtr->tkMacRegisterOffScreenWindow) /* 50 */ #endif #ifndef TkMacResizable -#define TkMacResizable(winPtr) \ - (tkIntPlatStubsPtr->tkMacResizable)(winPtr) /* 51 */ +#define TkMacResizable \ + (tkIntPlatStubsPtr->tkMacResizable) /* 51 */ #endif #ifndef TkMacSetEmbedRgn -#define TkMacSetEmbedRgn(winPtr, rgn) \ - (tkIntPlatStubsPtr->tkMacSetEmbedRgn)(winPtr, rgn) /* 52 */ +#define TkMacSetEmbedRgn \ + (tkIntPlatStubsPtr->tkMacSetEmbedRgn) /* 52 */ #endif #ifndef TkMacSetHelpMenuItemCount -#define TkMacSetHelpMenuItemCount() \ - (tkIntPlatStubsPtr->tkMacSetHelpMenuItemCount)() /* 53 */ +#define TkMacSetHelpMenuItemCount \ + (tkIntPlatStubsPtr->tkMacSetHelpMenuItemCount) /* 53 */ #endif #ifndef TkMacSetScrollbarGrow -#define TkMacSetScrollbarGrow(winPtr, flag) \ - (tkIntPlatStubsPtr->tkMacSetScrollbarGrow)(winPtr, flag) /* 54 */ +#define TkMacSetScrollbarGrow \ + (tkIntPlatStubsPtr->tkMacSetScrollbarGrow) /* 54 */ #endif #ifndef TkMacSetUpClippingRgn -#define TkMacSetUpClippingRgn(drawable) \ - (tkIntPlatStubsPtr->tkMacSetUpClippingRgn)(drawable) /* 55 */ +#define TkMacSetUpClippingRgn \ + (tkIntPlatStubsPtr->tkMacSetUpClippingRgn) /* 55 */ #endif #ifndef TkMacSetUpGraphicsPort -#define TkMacSetUpGraphicsPort(gc) \ - (tkIntPlatStubsPtr->tkMacSetUpGraphicsPort)(gc) /* 56 */ +#define TkMacSetUpGraphicsPort \ + (tkIntPlatStubsPtr->tkMacSetUpGraphicsPort) /* 56 */ #endif #ifndef TkMacUpdateClipRgn -#define TkMacUpdateClipRgn(winPtr) \ - (tkIntPlatStubsPtr->tkMacUpdateClipRgn)(winPtr) /* 57 */ +#define TkMacUpdateClipRgn \ + (tkIntPlatStubsPtr->tkMacUpdateClipRgn) /* 57 */ #endif #ifndef TkMacUnregisterMacWindow -#define TkMacUnregisterMacWindow(portPtr) \ - (tkIntPlatStubsPtr->tkMacUnregisterMacWindow)(portPtr) /* 58 */ +#define TkMacUnregisterMacWindow \ + (tkIntPlatStubsPtr->tkMacUnregisterMacWindow) /* 58 */ #endif #ifndef TkMacUseMenuID -#define TkMacUseMenuID(macID) \ - (tkIntPlatStubsPtr->tkMacUseMenuID)(macID) /* 59 */ +#define TkMacUseMenuID \ + (tkIntPlatStubsPtr->tkMacUseMenuID) /* 59 */ #endif #ifndef TkMacVisableClipRgn -#define TkMacVisableClipRgn(winPtr) \ - (tkIntPlatStubsPtr->tkMacVisableClipRgn)(winPtr) /* 60 */ +#define TkMacVisableClipRgn \ + (tkIntPlatStubsPtr->tkMacVisableClipRgn) /* 60 */ #endif #ifndef TkMacWinBounds -#define TkMacWinBounds(winPtr, geometry) \ - (tkIntPlatStubsPtr->tkMacWinBounds)(winPtr, geometry) /* 61 */ +#define TkMacWinBounds \ + (tkIntPlatStubsPtr->tkMacWinBounds) /* 61 */ #endif #ifndef TkMacWindowOffset -#define TkMacWindowOffset(wRef, xOffset, yOffset) \ - (tkIntPlatStubsPtr->tkMacWindowOffset)(wRef, xOffset, yOffset) /* 62 */ +#define TkMacWindowOffset \ + (tkIntPlatStubsPtr->tkMacWindowOffset) /* 62 */ #endif #ifndef TkResumeClipboard -#define TkResumeClipboard() \ - (tkIntPlatStubsPtr->tkResumeClipboard)() /* 63 */ +#define TkResumeClipboard \ + (tkIntPlatStubsPtr->tkResumeClipboard) /* 63 */ #endif #ifndef TkSetMacColor -#define TkSetMacColor(pixel, macColor) \ - (tkIntPlatStubsPtr->tkSetMacColor)(pixel, macColor) /* 64 */ +#define TkSetMacColor \ + (tkIntPlatStubsPtr->tkSetMacColor) /* 64 */ #endif #ifndef TkSetWMName -#define TkSetWMName(winPtr, titleUid) \ - (tkIntPlatStubsPtr->tkSetWMName)(winPtr, titleUid) /* 65 */ +#define TkSetWMName \ + (tkIntPlatStubsPtr->tkSetWMName) /* 65 */ #endif #ifndef TkSuspendClipboard -#define TkSuspendClipboard() \ - (tkIntPlatStubsPtr->tkSuspendClipboard)() /* 66 */ +#define TkSuspendClipboard \ + (tkIntPlatStubsPtr->tkSuspendClipboard) /* 66 */ #endif #ifndef TkWMGrowToplevel -#define TkWMGrowToplevel(whichWindow, start) \ - (tkIntPlatStubsPtr->tkWMGrowToplevel)(whichWindow, start) /* 67 */ +#define TkWMGrowToplevel \ + (tkIntPlatStubsPtr->tkWMGrowToplevel) /* 67 */ #endif #ifndef TkMacZoomToplevel -#define TkMacZoomToplevel(whichWindow, where, zoomPart) \ - (tkIntPlatStubsPtr->tkMacZoomToplevel)(whichWindow, where, zoomPart) /* 68 */ +#define TkMacZoomToplevel \ + (tkIntPlatStubsPtr->tkMacZoomToplevel) /* 68 */ #endif #ifndef Tk_TopCoordsToWindow -#define Tk_TopCoordsToWindow(tkwin, rootX, rootY, newX, newY) \ - (tkIntPlatStubsPtr->tk_TopCoordsToWindow)(tkwin, rootX, rootY, newX, newY) /* 69 */ +#define Tk_TopCoordsToWindow \ + (tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 69 */ #endif #ifndef TkMacContainerId -#define TkMacContainerId(winPtr) \ - (tkIntPlatStubsPtr->tkMacContainerId)(winPtr) /* 70 */ +#define TkMacContainerId \ + (tkIntPlatStubsPtr->tkMacContainerId) /* 70 */ #endif #ifndef TkMacGetHostToplevel -#define TkMacGetHostToplevel(winPtr) \ - (tkIntPlatStubsPtr->tkMacGetHostToplevel)(winPtr) /* 71 */ +#define TkMacGetHostToplevel \ + (tkIntPlatStubsPtr->tkMacGetHostToplevel) /* 71 */ #endif #endif /* MAC_TCL */ diff --git a/generic/tkIntPlatStubs.c b/generic/tkIntPlatStubs.c deleted file mode 100644 index 6650915..0000000 --- a/generic/tkIntPlatStubs.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * tkIntPlatStubs.c -- - * - * This file contains the wrapper functions for the platform dependent - * unsupported Tk API. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * All rights reserved. - * - * RCS: @(#) $Id: tkIntPlatStubs.c,v 1.2 1999/03/10 07:04:41 stanton Exp $ - */ - -#include "tkInt.h" -#include "tkPort.h" - -#ifdef __WIN32__ -#include "tkWinInt.h" -#endif - -#include "tkIntPlatDecls.h" - -/* - * WARNING: This file is automatically generated by the tools/genStubs.tcl - * script. Any modifications to the function declarations below should be made - * in the generic/tkInt.decls script. - */ - -/* !BEGIN!: Do not edit below this line. */ - -/* - * Exported stub functions: - */ - -#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */ -/* Slot 0 */ -void -TkCreateXEventSource() -{ - (tkIntPlatStubsPtr->tkCreateXEventSource)(); -} - -/* Slot 1 */ -void -TkFreeWindowId(dispPtr, w) - TkDisplay * dispPtr; - Window w; -{ - (tkIntPlatStubsPtr->tkFreeWindowId)(dispPtr, w); -} - -/* Slot 2 */ -void -TkInitXId(dispPtr) - TkDisplay * dispPtr; -{ - (tkIntPlatStubsPtr->tkInitXId)(dispPtr); -} - -/* Slot 3 */ -int -TkpCmapStressed(tkwin, colormap) - Tk_Window tkwin; - Colormap colormap; -{ - return (tkIntPlatStubsPtr->tkpCmapStressed)(tkwin, colormap); -} - -/* Slot 4 */ -void -TkpSync(display) - Display * display; -{ - (tkIntPlatStubsPtr->tkpSync)(display); -} - -/* Slot 5 */ -Window -TkUnixContainerId(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkUnixContainerId)(winPtr); -} - -/* Slot 6 */ -int -TkUnixDoOneXEvent(timePtr) - Tcl_Time * timePtr; -{ - return (tkIntPlatStubsPtr->tkUnixDoOneXEvent)(timePtr); -} - -/* Slot 7 */ -void -TkUnixSetMenubar(tkwin, menubar) - Tk_Window tkwin; - Tk_Window menubar; -{ - (tkIntPlatStubsPtr->tkUnixSetMenubar)(tkwin, menubar); -} - -#endif /* UNIX */ -#ifdef __WIN32__ -/* Slot 0 */ -char * -TkAlignImageData(image, alignment, bitOrder) - XImage * image; - int alignment; - int bitOrder; -{ - return (tkIntPlatStubsPtr->tkAlignImageData)(image, alignment, bitOrder); -} - -/* Slot 1 */ -void -TkClipBox(rgn, rect_return) - TkRegion rgn; - XRectangle* rect_return; -{ - (tkIntPlatStubsPtr->tkClipBox)(rgn, rect_return); -} - -/* Slot 2 */ -TkRegion -TkCreateRegion() -{ - return (tkIntPlatStubsPtr->tkCreateRegion)(); -} - -/* Slot 3 */ -void -TkDestroyRegion(rgn) - TkRegion rgn; -{ - (tkIntPlatStubsPtr->tkDestroyRegion)(rgn); -} - -/* Slot 4 */ -void -TkGenerateActivateEvents(winPtr, active) - TkWindow * winPtr; - int active; -{ - (tkIntPlatStubsPtr->tkGenerateActivateEvents)(winPtr, active); -} - -/* Slot 5 */ -void -TkIntersectRegion(sra, srcb, dr_return) - TkRegion sra; - TkRegion srcb; - TkRegion dr_return; -{ - (tkIntPlatStubsPtr->tkIntersectRegion)(sra, srcb, dr_return); -} - -/* Slot 6 */ -unsigned long -TkpGetMS() -{ - return (tkIntPlatStubsPtr->tkpGetMS)(); -} - -/* Slot 7 */ -void -TkPointerDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkPointerDeadWindow)(winPtr); -} - -/* Slot 8 */ -void -TkpPrintWindowId(buf, window) - char * buf; - Window window; -{ - (tkIntPlatStubsPtr->tkpPrintWindowId)(buf, window); -} - -/* Slot 9 */ -int -TkpScanWindowId(interp, string, idPtr) - Tcl_Interp * interp; - char * string; - int * idPtr; -{ - return (tkIntPlatStubsPtr->tkpScanWindowId)(interp, string, idPtr); -} - -/* Slot 10 */ -void -TkpSetCapture(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkpSetCapture)(winPtr); -} - -/* Slot 11 */ -void -TkpSetCursor(cursor) - TkpCursor cursor; -{ - (tkIntPlatStubsPtr->tkpSetCursor)(cursor); -} - -/* Slot 12 */ -void -TkpWmSetState(winPtr, state) - TkWindow * winPtr; - int state; -{ - (tkIntPlatStubsPtr->tkpWmSetState)(winPtr, state); -} - -/* Slot 13 */ -int -TkRectInRegion(rgn, x, y, width, height) - TkRegion rgn; - int x; - int y; - unsigned int width; - unsigned int height; -{ - return (tkIntPlatStubsPtr->tkRectInRegion)(rgn, x, y, width, height); -} - -/* Slot 14 */ -void -TkSetPixmapColormap(pixmap, colormap) - Pixmap pixmap; - Colormap colormap; -{ - (tkIntPlatStubsPtr->tkSetPixmapColormap)(pixmap, colormap); -} - -/* Slot 15 */ -void -TkSetRegion(display, gc, rgn) - Display* display; - GC gc; - TkRegion rgn; -{ - (tkIntPlatStubsPtr->tkSetRegion)(display, gc, rgn); -} - -/* Slot 16 */ -void -TkUnionRectWithRegion(rect, src, dr_return) - XRectangle* rect; - TkRegion src; - TkRegion dr_return; -{ - (tkIntPlatStubsPtr->tkUnionRectWithRegion)(rect, src, dr_return); -} - -/* Slot 17 */ -void -TkWinCancelMouseTimer() -{ - (tkIntPlatStubsPtr->tkWinCancelMouseTimer)(); -} - -/* Slot 18 */ -void -TkWinClipboardRender(dispPtr, format) - TkDisplay * dispPtr; - UINT format; -{ - (tkIntPlatStubsPtr->tkWinClipboardRender)(dispPtr, format); -} - -/* Slot 19 */ -LRESULT -TkWinEmbeddedEventProc(hwnd, message, wParam, lParam) - HWND hwnd; - UINT message; - WPARAM wParam; - LPARAM lParam; -{ - return (tkIntPlatStubsPtr->tkWinEmbeddedEventProc)(hwnd, message, wParam, lParam); -} - -/* Slot 20 */ -void -TkWinFillRect(dc, x, y, width, height, pixel) - HDC dc; - int x; - int y; - int width; - int height; - int pixel; -{ - (tkIntPlatStubsPtr->tkWinFillRect)(dc, x, y, width, height, pixel); -} - -/* Slot 21 */ -COLORREF -TkWinGetBorderPixels(tkwin, border, which) - Tk_Window tkwin; - Tk_3DBorder border; - int which; -{ - return (tkIntPlatStubsPtr->tkWinGetBorderPixels)(tkwin, border, which); -} - -/* Slot 22 */ -HDC -TkWinGetDrawableDC(display, d, state) - Display * display; - Drawable d; - TkWinDCState* state; -{ - return (tkIntPlatStubsPtr->tkWinGetDrawableDC)(display, d, state); -} - -/* Slot 23 */ -int -TkWinGetModifierState() -{ - return (tkIntPlatStubsPtr->tkWinGetModifierState)(); -} - -/* Slot 24 */ -HPALETTE -TkWinGetSystemPalette() -{ - return (tkIntPlatStubsPtr->tkWinGetSystemPalette)(); -} - -/* Slot 25 */ -HWND -TkWinGetWrapperWindow(tkwin) - Tk_Window tkwin; -{ - return (tkIntPlatStubsPtr->tkWinGetWrapperWindow)(tkwin); -} - -/* Slot 26 */ -int -TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) - HWND * phwnd; - UINT * pMessage; - WPARAM * pwParam; - LPARAM * plParam; - LRESULT * plResult; -{ - return (tkIntPlatStubsPtr->tkWinHandleMenuEvent)(phwnd, pMessage, pwParam, plParam, plResult); -} - -/* Slot 27 */ -int -TkWinIndexOfColor(colorPtr) - XColor * colorPtr; -{ - return (tkIntPlatStubsPtr->tkWinIndexOfColor)(colorPtr); -} - -/* Slot 28 */ -void -TkWinReleaseDrawableDC(d, hdc, state) - Drawable d; - HDC hdc; - TkWinDCState* state; -{ - (tkIntPlatStubsPtr->tkWinReleaseDrawableDC)(d, hdc, state); -} - -/* Slot 29 */ -LRESULT -TkWinResendEvent(wndproc, hwnd, eventPtr) - WNDPROC wndproc; - HWND hwnd; - XEvent * eventPtr; -{ - return (tkIntPlatStubsPtr->tkWinResendEvent)(wndproc, hwnd, eventPtr); -} - -/* Slot 30 */ -HPALETTE -TkWinSelectPalette(dc, colormap) - HDC dc; - Colormap colormap; -{ - return (tkIntPlatStubsPtr->tkWinSelectPalette)(dc, colormap); -} - -/* Slot 31 */ -void -TkWinSetMenu(tkwin, hMenu) - Tk_Window tkwin; - HMENU hMenu; -{ - (tkIntPlatStubsPtr->tkWinSetMenu)(tkwin, hMenu); -} - -/* Slot 32 */ -void -TkWinSetWindowPos(hwnd, siblingHwnd, pos) - HWND hwnd; - HWND siblingHwnd; - int pos; -{ - (tkIntPlatStubsPtr->tkWinSetWindowPos)(hwnd, siblingHwnd, pos); -} - -/* Slot 33 */ -void -TkWinWmCleanup(hInstance) - HINSTANCE hInstance; -{ - (tkIntPlatStubsPtr->tkWinWmCleanup)(hInstance); -} - -/* Slot 34 */ -void -TkWinXCleanup(hInstance) - HINSTANCE hInstance; -{ - (tkIntPlatStubsPtr->tkWinXCleanup)(hInstance); -} - -/* Slot 35 */ -void -TkWinXInit(hInstance) - HINSTANCE hInstance; -{ - (tkIntPlatStubsPtr->tkWinXInit)(hInstance); -} - -#endif /* __WIN32__ */ -#ifdef MAC_TCL -/* Slot 0 */ -void -TkClipBox(rgn, rect_return) - TkRegion rgn; - XRectangle* rect_return; -{ - (tkIntPlatStubsPtr->tkClipBox)(rgn, rect_return); -} - -/* Slot 1 */ -TkRegion -TkCreateRegion() -{ - return (tkIntPlatStubsPtr->tkCreateRegion)(); -} - -/* Slot 2 */ -void -TkDestroyRegion(rgn) - TkRegion rgn; -{ - (tkIntPlatStubsPtr->tkDestroyRegion)(rgn); -} - -/* Slot 3 */ -void -TkGenerateActivateEvents(winPtr, active) - TkWindow * winPtr; - int active; -{ - (tkIntPlatStubsPtr->tkGenerateActivateEvents)(winPtr, active); -} - -/* Slot 4 */ -void -TkIntersectRegion(sra, srcb, dr_return) - TkRegion sra; - TkRegion srcb; - TkRegion dr_return; -{ - (tkIntPlatStubsPtr->tkIntersectRegion)(sra, srcb, dr_return); -} - -/* Slot 5 */ -Pixmap -TkpCreateNativeBitmap(display, source) - Display * display; - char * source; -{ - return (tkIntPlatStubsPtr->tkpCreateNativeBitmap)(display, source); -} - -/* Slot 6 */ -void -TkpDefineNativeBitmaps() -{ - (tkIntPlatStubsPtr->tkpDefineNativeBitmaps)(); -} - -/* Slot 7 */ -unsigned long -TkpGetMS() -{ - return (tkIntPlatStubsPtr->tkpGetMS)(); -} - -/* Slot 8 */ -Pixmap -TkpGetNativeAppBitmap(display, name, width, height) - Display * display; - char * name; - int * width; - int * height; -{ - return (tkIntPlatStubsPtr->tkpGetNativeAppBitmap)(display, name, width, height); -} - -/* Slot 9 */ -void -TkPointerDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkPointerDeadWindow)(winPtr); -} - -/* Slot 10 */ -void -TkpSetCapture(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkpSetCapture)(winPtr); -} - -/* Slot 11 */ -void -TkpSetCursor(cursor) - TkpCursor cursor; -{ - (tkIntPlatStubsPtr->tkpSetCursor)(cursor); -} - -/* Slot 12 */ -void -TkpWmSetState(winPtr, state) - TkWindow * winPtr; - int state; -{ - (tkIntPlatStubsPtr->tkpWmSetState)(winPtr, state); -} - -/* Slot 13 */ -int -TkRectInRegion(rgn, x, y, width, height) - TkRegion rgn; - int x; - int y; - unsigned int width; - unsigned int height; -{ - return (tkIntPlatStubsPtr->tkRectInRegion)(rgn, x, y, width, height); -} - -/* Slot 14 */ -void -TkSetRegion(display, gc, rgn) - Display* display; - GC gc; - TkRegion rgn; -{ - (tkIntPlatStubsPtr->tkSetRegion)(display, gc, rgn); -} - -/* Slot 15 */ -void -TkUnionRectWithRegion(rect, src, dr_return) - XRectangle* rect; - TkRegion src; - TkRegion dr_return; -{ - (tkIntPlatStubsPtr->tkUnionRectWithRegion)(rect, src, dr_return); -} - -/* Slot 16 */ -int -HandleWMEvent(theEvent) - EventRecord * theEvent; -{ - return (tkIntPlatStubsPtr->handleWMEvent)(theEvent); -} - -/* Slot 17 */ -void -TkAboutDlg() -{ - (tkIntPlatStubsPtr->tkAboutDlg)(); -} - -/* Slot 18 */ -void -TkCreateMacEventSource() -{ - (tkIntPlatStubsPtr->tkCreateMacEventSource)(); -} - -/* Slot 19 */ -void -TkFontList(interp, display) - Tcl_Interp * interp; - Display * display; -{ - (tkIntPlatStubsPtr->tkFontList)(interp, display); -} - -/* Slot 20 */ -Window -TkGetTransientMaster(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkGetTransientMaster)(winPtr); -} - -/* Slot 21 */ -int -TkGenerateButtonEvent(x, y, window, state) - int x; - int y; - Window window; - unsigned int state; -{ - return (tkIntPlatStubsPtr->tkGenerateButtonEvent)(x, y, window, state); -} - -/* Slot 22 */ -int -TkGetCharPositions(font_struct, string, count, buffer) - XFontStruct * font_struct; - char * string; - int count; - short * buffer; -{ - return (tkIntPlatStubsPtr->tkGetCharPositions)(font_struct, string, count, buffer); -} - -/* Slot 23 */ -void -TkGenWMDestroyEvent(tkwin) - Tk_Window tkwin; -{ - (tkIntPlatStubsPtr->tkGenWMDestroyEvent)(tkwin); -} - -/* Slot 24 */ -void -TkGenWMConfigureEvent(tkwin, x, y, width, height, flags) - Tk_Window tkwin; - int x; - int y; - int width; - int height; - int flags; -{ - (tkIntPlatStubsPtr->tkGenWMConfigureEvent)(tkwin, x, y, width, height, flags); -} - -/* Slot 25 */ -unsigned int -TkMacButtonKeyState() -{ - return (tkIntPlatStubsPtr->tkMacButtonKeyState)(); -} - -/* Slot 26 */ -void -TkMacClearMenubarActive() -{ - (tkIntPlatStubsPtr->tkMacClearMenubarActive)(); -} - -/* Slot 27 */ -int -TkMacConvertEvent(eventPtr) - EventRecord * eventPtr; -{ - return (tkIntPlatStubsPtr->tkMacConvertEvent)(eventPtr); -} - -/* Slot 28 */ -int -TkMacDispatchMenuEvent(menuID, index) - int menuID; - int index; -{ - return (tkIntPlatStubsPtr->tkMacDispatchMenuEvent)(menuID, index); -} - -/* Slot 29 */ -void -TkMacInstallCursor(resizeOverride) - int resizeOverride; -{ - (tkIntPlatStubsPtr->tkMacInstallCursor)(resizeOverride); -} - -/* Slot 30 */ -int -TkMacConvertTkEvent(eventPtr, window) - EventRecord * eventPtr; - Window window; -{ - return (tkIntPlatStubsPtr->tkMacConvertTkEvent)(eventPtr, window); -} - -/* Slot 31 */ -void -TkMacHandleTearoffMenu() -{ - (tkIntPlatStubsPtr->tkMacHandleTearoffMenu)(); -} - -/* Slot 32 */ -void -tkMacInstallMWConsole(interp) - Tcl_Interp * interp; -{ - (tkIntPlatStubsPtr->tkMacInstallMWConsole)(interp); -} - -/* Slot 33 */ -void -TkMacInvalClipRgns(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkMacInvalClipRgns)(winPtr); -} - -/* Slot 34 */ -void -TkMacDoHLEvent(theEvent) - EventRecord * theEvent; -{ - (tkIntPlatStubsPtr->tkMacDoHLEvent)(theEvent); -} - -/* Slot 35 */ -void -TkMacFontInfo(fontId, family, style, size) - Font fontId; - short * family; - short * style; - short * size; -{ - (tkIntPlatStubsPtr->tkMacFontInfo)(fontId, family, style, size); -} - -/* Slot 36 */ -Time -TkMacGenerateTime() -{ - return (tkIntPlatStubsPtr->tkMacGenerateTime)(); -} - -/* Slot 37 */ -GWorldPtr -TkMacGetDrawablePort(drawable) - Drawable drawable; -{ - return (tkIntPlatStubsPtr->tkMacGetDrawablePort)(drawable); -} - -/* Slot 38 */ -TkWindow * -TkMacGetScrollbarGrowWindow(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkMacGetScrollbarGrowWindow)(winPtr); -} - -/* Slot 39 */ -Window -TkMacGetXWindow(macWinPtr) - WindowRef macWinPtr; -{ - return (tkIntPlatStubsPtr->tkMacGetXWindow)(macWinPtr); -} - -/* Slot 40 */ -int -TkMacGrowToplevel(whichWindow, start) - WindowRef whichWindow; - Point start; -{ - return (tkIntPlatStubsPtr->tkMacGrowToplevel)(whichWindow, start); -} - -/* Slot 41 */ -void -TkMacHandleMenuSelect(mResult, optionKeyPressed) - long mResult; - int optionKeyPressed; -{ - (tkIntPlatStubsPtr->tkMacHandleMenuSelect)(mResult, optionKeyPressed); -} - -/* Slot 42 */ -int -TkMacHaveAppearance() -{ - return (tkIntPlatStubsPtr->tkMacHaveAppearance)(); -} - -/* Slot 43 */ -void -TkMacInitAppleEvents(interp) - Tcl_Interp * interp; -{ - (tkIntPlatStubsPtr->tkMacInitAppleEvents)(interp); -} - -/* Slot 44 */ -void -TkMacInitMenus(interp) - Tcl_Interp * interp; -{ - (tkIntPlatStubsPtr->tkMacInitMenus)(interp); -} - -/* Slot 45 */ -void -TkMacInvalidateWindow(macWin, flag) - MacDrawable * macWin; - int flag; -{ - (tkIntPlatStubsPtr->tkMacInvalidateWindow)(macWin, flag); -} - -/* Slot 46 */ -int -TkMacIsCharacterMissing(tkfont, searchChar) - Tk_Font tkfont; - unsigned int searchChar; -{ - return (tkIntPlatStubsPtr->tkMacIsCharacterMissing)(tkfont, searchChar); -} - -/* Slot 47 */ -void -TkMacMakeRealWindowExist(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkMacMakeRealWindowExist)(winPtr); -} - -/* Slot 48 */ -BitMapPtr -TkMacMakeStippleMap(d1, d2) - Drawable d1; - Drawable d2; -{ - return (tkIntPlatStubsPtr->tkMacMakeStippleMap)(d1, d2); -} - -/* Slot 49 */ -void -TkMacMenuClick() -{ - (tkIntPlatStubsPtr->tkMacMenuClick)(); -} - -/* Slot 50 */ -void -TkMacRegisterOffScreenWindow(window, portPtr) - Window window; - GWorldPtr portPtr; -{ - (tkIntPlatStubsPtr->tkMacRegisterOffScreenWindow)(window, portPtr); -} - -/* Slot 51 */ -int -TkMacResizable(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkMacResizable)(winPtr); -} - -/* Slot 52 */ -void -TkMacSetEmbedRgn(winPtr, rgn) - TkWindow * winPtr; - RgnHandle rgn; -{ - (tkIntPlatStubsPtr->tkMacSetEmbedRgn)(winPtr, rgn); -} - -/* Slot 53 */ -void -TkMacSetHelpMenuItemCount() -{ - (tkIntPlatStubsPtr->tkMacSetHelpMenuItemCount)(); -} - -/* Slot 54 */ -void -TkMacSetScrollbarGrow(winPtr, flag) - TkWindow * winPtr; - int flag; -{ - (tkIntPlatStubsPtr->tkMacSetScrollbarGrow)(winPtr, flag); -} - -/* Slot 55 */ -void -TkMacSetUpClippingRgn(drawable) - Drawable drawable; -{ - (tkIntPlatStubsPtr->tkMacSetUpClippingRgn)(drawable); -} - -/* Slot 56 */ -void -TkMacSetUpGraphicsPort(gc) - GC gc; -{ - (tkIntPlatStubsPtr->tkMacSetUpGraphicsPort)(gc); -} - -/* Slot 57 */ -void -TkMacUpdateClipRgn(winPtr) - TkWindow * winPtr; -{ - (tkIntPlatStubsPtr->tkMacUpdateClipRgn)(winPtr); -} - -/* Slot 58 */ -void -TkMacUnregisterMacWindow(portPtr) - GWorldPtr portPtr; -{ - (tkIntPlatStubsPtr->tkMacUnregisterMacWindow)(portPtr); -} - -/* Slot 59 */ -int -TkMacUseMenuID(macID) - short macID; -{ - return (tkIntPlatStubsPtr->tkMacUseMenuID)(macID); -} - -/* Slot 60 */ -RgnHandle -TkMacVisableClipRgn(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkMacVisableClipRgn)(winPtr); -} - -/* Slot 61 */ -void -TkMacWinBounds(winPtr, geometry) - TkWindow * winPtr; - Rect * geometry; -{ - (tkIntPlatStubsPtr->tkMacWinBounds)(winPtr, geometry); -} - -/* Slot 62 */ -void -TkMacWindowOffset(wRef, xOffset, yOffset) - WindowRef wRef; - int * xOffset; - int * yOffset; -{ - (tkIntPlatStubsPtr->tkMacWindowOffset)(wRef, xOffset, yOffset); -} - -/* Slot 63 */ -void -TkResumeClipboard() -{ - (tkIntPlatStubsPtr->tkResumeClipboard)(); -} - -/* Slot 64 */ -int -TkSetMacColor(pixel, macColor) - unsigned long pixel; - RGBColor * macColor; -{ - return (tkIntPlatStubsPtr->tkSetMacColor)(pixel, macColor); -} - -/* Slot 65 */ -void -TkSetWMName(winPtr, titleUid) - TkWindow * winPtr; - Tk_Uid titleUid; -{ - (tkIntPlatStubsPtr->tkSetWMName)(winPtr, titleUid); -} - -/* Slot 66 */ -void -TkSuspendClipboard() -{ - (tkIntPlatStubsPtr->tkSuspendClipboard)(); -} - -/* Slot 67 */ -int -TkWMGrowToplevel(whichWindow, start) - WindowRef whichWindow; - Point start; -{ - return (tkIntPlatStubsPtr->tkWMGrowToplevel)(whichWindow, start); -} - -/* Slot 68 */ -int -TkMacZoomToplevel(whichWindow, where, zoomPart) - WindowPtr whichWindow; - Point where; - short zoomPart; -{ - return (tkIntPlatStubsPtr->tkMacZoomToplevel)(whichWindow, where, zoomPart); -} - -/* Slot 69 */ -Tk_Window -Tk_TopCoordsToWindow(tkwin, rootX, rootY, newX, newY) - Tk_Window tkwin; - int rootX; - int rootY; - int * newX; - int * newY; -{ - return (tkIntPlatStubsPtr->tk_TopCoordsToWindow)(tkwin, rootX, rootY, newX, newY); -} - -/* Slot 70 */ -MacDrawable * -TkMacContainerId(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkMacContainerId)(winPtr); -} - -/* Slot 71 */ -MacDrawable * -TkMacGetHostToplevel(winPtr) - TkWindow * winPtr; -{ - return (tkIntPlatStubsPtr->tkMacGetHostToplevel)(winPtr); -} - -#endif /* MAC_TCL */ - -/* !END!: Do not edit above this line. */ diff --git a/generic/tkIntStubs.c b/generic/tkIntStubs.c deleted file mode 100644 index 1c33059..0000000 --- a/generic/tkIntStubs.c +++ /dev/null @@ -1,965 +0,0 @@ -/* - * tkIntStubs.c -- - * - * This file contains the wrapper functions for the platform independent - * unsupported Tk API. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * All rights reserved. - * - * RCS: @(#) $Id: tkIntStubs.c,v 1.2 1999/03/10 07:04:41 stanton Exp $ - */ - -#include "tkInt.h" - -/* - * WARNING: This file is automatically generated by the tools/genStubs.tcl - * script. Any modifications to the function declarations below should be made - * in the generic/tkInt.decls script. - */ - -/* !BEGIN!: Do not edit below this line. */ - -/* - * Exported stub functions: - */ - -/* Slot 0 */ -TkWindow * -TkAllocWindow(dispPtr, screenNum, parentPtr) - TkDisplay * dispPtr; - int screenNum; - TkWindow * parentPtr; -{ - return (tkIntStubsPtr->tkAllocWindow)(dispPtr, screenNum, parentPtr); -} - -/* Slot 1 */ -void -TkBezierPoints(control, numSteps, coordPtr) - double control[]; - int numSteps; - double * coordPtr; -{ - (tkIntStubsPtr->tkBezierPoints)(control, numSteps, coordPtr); -} - -/* Slot 2 */ -void -TkBezierScreenPoints(canvas, control, numSteps, xPointPtr) - Tk_Canvas canvas; - double control[]; - int numSteps; - XPoint * xPointPtr; -{ - (tkIntStubsPtr->tkBezierScreenPoints)(canvas, control, numSteps, xPointPtr); -} - -/* Slot 3 */ -void -TkBindDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkBindDeadWindow)(winPtr); -} - -/* Slot 4 */ -void -TkBindEventProc(winPtr, eventPtr) - TkWindow * winPtr; - XEvent * eventPtr; -{ - (tkIntStubsPtr->tkBindEventProc)(winPtr, eventPtr); -} - -/* Slot 5 */ -void -TkBindFree(mainPtr) - TkMainInfo * mainPtr; -{ - (tkIntStubsPtr->tkBindFree)(mainPtr); -} - -/* Slot 6 */ -void -TkBindInit(mainPtr) - TkMainInfo * mainPtr; -{ - (tkIntStubsPtr->tkBindInit)(mainPtr); -} - -/* Slot 7 */ -void -TkChangeEventWindow(eventPtr, winPtr) - XEvent * eventPtr; - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkChangeEventWindow)(eventPtr, winPtr); -} - -/* Slot 8 */ -int -TkClipInit(interp, dispPtr) - Tcl_Interp * interp; - TkDisplay * dispPtr; -{ - return (tkIntStubsPtr->tkClipInit)(interp, dispPtr); -} - -/* Slot 9 */ -void -TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr) - Tk_Anchor anchor; - Tk_Window tkwin; - int padX; - int padY; - int innerWidth; - int innerHeight; - int * xPtr; - int * yPtr; -{ - (tkIntStubsPtr->tkComputeAnchor)(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr); -} - -/* Slot 10 */ -int -TkCopyAndGlobalEval(interp, script) - Tcl_Interp * interp; - char * script; -{ - return (tkIntStubsPtr->tkCopyAndGlobalEval)(interp, script); -} - -/* Slot 11 */ -unsigned long -TkCreateBindingProcedure(interp, bindingTable, object, eventString, evalProc, freeProc, clientData) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; - ClientData object; - char * eventString; - TkBindEvalProc * evalProc; - TkBindFreeProc * freeProc; - ClientData clientData; -{ - return (tkIntStubsPtr->tkCreateBindingProcedure)(interp, bindingTable, object, eventString, evalProc, freeProc, clientData); -} - -/* Slot 12 */ -TkCursor * -TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot, fg, bg) - Tk_Window tkwin; - char * source; - char * mask; - int width; - int height; - int xHot; - int yHot; - XColor fg; - XColor bg; -{ - return (tkIntStubsPtr->tkCreateCursorFromData)(tkwin, source, mask, width, height, xHot, yHot, fg, bg); -} - -/* Slot 13 */ -int -TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) - ClientData clientData; - Tcl_Interp * interp; - int argc; - char ** argv; - int toplevel; - char * appName; -{ - return (tkIntStubsPtr->tkCreateFrame)(clientData, interp, argc, argv, toplevel, appName); -} - -/* Slot 14 */ -Tk_Window -TkCreateMainWindow(interp, screenName, baseName) - Tcl_Interp * interp; - char * screenName; - char * baseName; -{ - return (tkIntStubsPtr->tkCreateMainWindow)(interp, screenName, baseName); -} - -/* Slot 15 */ -Time -TkCurrentTime(dispPtr) - TkDisplay * dispPtr; -{ - return (tkIntStubsPtr->tkCurrentTime)(dispPtr); -} - -/* Slot 16 */ -void -TkDeleteAllImages(mainPtr) - TkMainInfo * mainPtr; -{ - (tkIntStubsPtr->tkDeleteAllImages)(mainPtr); -} - -/* Slot 17 */ -void -TkDoConfigureNotify(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkDoConfigureNotify)(winPtr); -} - -/* Slot 18 */ -void -TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, padding) - Tk_Window tkwin; - GC gc; - int width; - Drawable drawable; - int padding; -{ - (tkIntStubsPtr->tkDrawInsetFocusHighlight)(tkwin, gc, width, drawable, padding); -} - -/* Slot 19 */ -void -TkEventDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkEventDeadWindow)(winPtr); -} - -/* Slot 20 */ -void -TkFillPolygon(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC) - Tk_Canvas canvas; - double * coordPtr; - int numPoints; - Display * display; - Drawable drawable; - GC gc; - GC outlineGC; -{ - (tkIntStubsPtr->tkFillPolygon)(canvas, coordPtr, numPoints, display, drawable, gc, outlineGC); -} - -/* Slot 21 */ -int -TkFindStateNum(interp, option, mapPtr, strKey) - Tcl_Interp * interp; - CONST char * option; - CONST TkStateMap * mapPtr; - CONST char * strKey; -{ - return (tkIntStubsPtr->tkFindStateNum)(interp, option, mapPtr, strKey); -} - -/* Slot 22 */ -char * -TkFindStateString(mapPtr, numKey) - CONST TkStateMap * mapPtr; - int numKey; -{ - return (tkIntStubsPtr->tkFindStateString)(mapPtr, numKey); -} - -/* Slot 23 */ -void -TkFocusDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkFocusDeadWindow)(winPtr); -} - -/* Slot 24 */ -int -TkFocusFilterEvent(winPtr, eventPtr) - TkWindow * winPtr; - XEvent * eventPtr; -{ - return (tkIntStubsPtr->tkFocusFilterEvent)(winPtr, eventPtr); -} - -/* Slot 25 */ -TkWindow * -TkFocusKeyEvent(winPtr, eventPtr) - TkWindow * winPtr; - XEvent * eventPtr; -{ - return (tkIntStubsPtr->tkFocusKeyEvent)(winPtr, eventPtr); -} - -/* Slot 26 */ -void -TkFontPkgInit(mainPtr) - TkMainInfo * mainPtr; -{ - (tkIntStubsPtr->tkFontPkgInit)(mainPtr); -} - -/* Slot 27 */ -void -TkFontPkgFree(mainPtr) - TkMainInfo * mainPtr; -{ - (tkIntStubsPtr->tkFontPkgFree)(mainPtr); -} - -/* Slot 28 */ -void -TkFreeBindingTags(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkFreeBindingTags)(winPtr); -} - -/* Slot 29 */ -void -TkFreeCursor(cursorPtr) - TkCursor * cursorPtr; -{ - (tkIntStubsPtr->tkFreeCursor)(cursorPtr); -} - -/* Slot 30 */ -char * -TkGetBitmapData(interp, string, fileName, widthPtr, heightPtr, hotXPtr, hotYPtr) - Tcl_Interp * interp; - char * string; - char * fileName; - int * widthPtr; - int * heightPtr; - int * hotXPtr; - int * hotYPtr; -{ - return (tkIntStubsPtr->tkGetBitmapData)(interp, string, fileName, widthPtr, heightPtr, hotXPtr, hotYPtr); -} - -/* Slot 31 */ -void -TkGetButtPoints(p1, p2, width, project, m1, m2) - double p1[]; - double p2[]; - double width; - int project; - double m1[]; - double m2[]; -{ - (tkIntStubsPtr->tkGetButtPoints)(p1, p2, width, project, m1, m2); -} - -/* Slot 32 */ -TkCursor * -TkGetCursorByName(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_Uid string; -{ - return (tkIntStubsPtr->tkGetCursorByName)(interp, tkwin, string); -} - -/* Slot 33 */ -char * -TkGetDefaultScreenName(interp, screenName) - Tcl_Interp * interp; - char * screenName; -{ - return (tkIntStubsPtr->tkGetDefaultScreenName)(interp, screenName); -} - -/* Slot 34 */ -TkDisplay * -TkGetDisplay(display) - Display * display; -{ - return (tkIntStubsPtr->tkGetDisplay)(display); -} - -/* Slot 35 */ -int -TkGetDisplayOf(interp, objc, objv, tkwinPtr) - Tcl_Interp * interp; - int objc; - Tcl_Obj *CONST objv[]; - Tk_Window * tkwinPtr; -{ - return (tkIntStubsPtr->tkGetDisplayOf)(interp, objc, objv, tkwinPtr); -} - -/* Slot 36 */ -TkWindow * -TkGetFocusWin(winPtr) - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkGetFocusWin)(winPtr); -} - -/* Slot 37 */ -int -TkGetInterpNames(interp, tkwin) - Tcl_Interp * interp; - Tk_Window tkwin; -{ - return (tkIntStubsPtr->tkGetInterpNames)(interp, tkwin); -} - -/* Slot 38 */ -int -TkGetMiterPoints(p1, p2, p3, width, m1, m2) - double p1[]; - double p2[]; - double p3[]; - double width; - double m1[]; - double m2[]; -{ - return (tkIntStubsPtr->tkGetMiterPoints)(p1, p2, p3, width, m1, m2); -} - -/* Slot 39 */ -void -TkGetPointerCoords(tkwin, xPtr, yPtr) - Tk_Window tkwin; - int * xPtr; - int * yPtr; -{ - (tkIntStubsPtr->tkGetPointerCoords)(tkwin, xPtr, yPtr); -} - -/* Slot 40 */ -void -TkGetServerInfo(interp, tkwin) - Tcl_Interp * interp; - Tk_Window tkwin; -{ - (tkIntStubsPtr->tkGetServerInfo)(interp, tkwin); -} - -/* Slot 41 */ -void -TkGrabDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkGrabDeadWindow)(winPtr); -} - -/* Slot 42 */ -int -TkGrabState(winPtr) - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkGrabState)(winPtr); -} - -/* Slot 43 */ -void -TkIncludePoint(itemPtr, pointPtr) - Tk_Item * itemPtr; - double * pointPtr; -{ - (tkIntStubsPtr->tkIncludePoint)(itemPtr, pointPtr); -} - -/* Slot 44 */ -void -TkInOutEvents(eventPtr, sourcePtr, destPtr, leaveType, enterType, position) - XEvent * eventPtr; - TkWindow * sourcePtr; - TkWindow * destPtr; - int leaveType; - int enterType; - Tcl_QueuePosition position; -{ - (tkIntStubsPtr->tkInOutEvents)(eventPtr, sourcePtr, destPtr, leaveType, enterType, position); -} - -/* Slot 45 */ -void -TkInstallFrameMenu(tkwin) - Tk_Window tkwin; -{ - (tkIntStubsPtr->tkInstallFrameMenu)(tkwin); -} - -/* Slot 46 */ -char * -TkKeysymToString(keysym) - KeySym keysym; -{ - return (tkIntStubsPtr->tkKeysymToString)(keysym); -} - -/* Slot 47 */ -int -TkLineToArea(end1Ptr, end2Ptr, rectPtr) - TkDouble2 end1Ptr; - TkDouble2 end2Ptr; - TkDouble4 rectPtr; -{ - return (tkIntStubsPtr->tkLineToArea)(end1Ptr, end2Ptr, rectPtr); -} - -/* Slot 48 */ -double -TkLineToPoint(end1Ptr, end2Ptr, pointPtr) - double end1Ptr[]; - TkDouble2 end2Ptr; - TkDouble2 pointPtr; -{ - return (tkIntStubsPtr->tkLineToPoint)(end1Ptr, end2Ptr, pointPtr); -} - -/* Slot 49 */ -int -TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) - Tk_Canvas canvas; - double * pointPtr; - int numPoints; - int numSteps; - XPoint xPoints[]; - double dblPoints[]; -{ - return (tkIntStubsPtr->tkMakeBezierCurve)(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints); -} - -/* Slot 50 */ -void -TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints) - Tcl_Interp * interp; - Tk_Canvas canvas; - double * pointPtr; - int numPoints; -{ - (tkIntStubsPtr->tkMakeBezierPostscript)(interp, canvas, pointPtr, numPoints); -} - -/* Slot 51 */ -void -TkOptionClassChanged(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkOptionClassChanged)(winPtr); -} - -/* Slot 52 */ -void -TkOptionDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkOptionDeadWindow)(winPtr); -} - -/* Slot 53 */ -int -TkOvalToArea(ovalPtr, rectPtr) - double * ovalPtr; - double * rectPtr; -{ - return (tkIntStubsPtr->tkOvalToArea)(ovalPtr, rectPtr); -} - -/* Slot 54 */ -double -TkOvalToPoint(ovalPtr, width, filled, pointPtr) - TkDouble4 ovalPtr; - double width; - int filled; - TkDouble2 pointPtr; -{ - return (tkIntStubsPtr->tkOvalToPoint)(ovalPtr, width, filled, pointPtr); -} - -/* Slot 55 */ -int -TkpChangeFocus(winPtr, force) - TkWindow * winPtr; - int force; -{ - return (tkIntStubsPtr->tkpChangeFocus)(winPtr, force); -} - -/* Slot 56 */ -void -TkpCloseDisplay(dispPtr) - TkDisplay * dispPtr; -{ - (tkIntStubsPtr->tkpCloseDisplay)(dispPtr); -} - -/* Slot 57 */ -void -TkpClaimFocus(topLevelPtr, force) - TkWindow * topLevelPtr; - int force; -{ - (tkIntStubsPtr->tkpClaimFocus)(topLevelPtr, force); -} - -/* Slot 58 */ -void -TkpDisplayWarning(msg, title) - char * msg; - char * title; -{ - (tkIntStubsPtr->tkpDisplayWarning)(msg, title); -} - -/* Slot 59 */ -void -TkpGetAppName(interp, name) - Tcl_Interp * interp; - Tcl_DString * name; -{ - (tkIntStubsPtr->tkpGetAppName)(interp, name); -} - -/* Slot 60 */ -TkWindow * -TkpGetOtherWindow(winPtr) - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkpGetOtherWindow)(winPtr); -} - -/* Slot 61 */ -TkWindow * -TkpGetWrapperWindow(winPtr) - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkpGetWrapperWindow)(winPtr); -} - -/* Slot 62 */ -int -TkpInit(interp) - Tcl_Interp * interp; -{ - return (tkIntStubsPtr->tkpInit)(interp); -} - -/* Slot 63 */ -void -TkpInitializeMenuBindings(interp, bindingTable) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; -{ - (tkIntStubsPtr->tkpInitializeMenuBindings)(interp, bindingTable); -} - -/* Slot 64 */ -void -TkpMakeContainer(tkwin) - Tk_Window tkwin; -{ - (tkIntStubsPtr->tkpMakeContainer)(tkwin); -} - -/* Slot 65 */ -void -TkpMakeMenuWindow(tkwin, transient) - Tk_Window tkwin; - int transient; -{ - (tkIntStubsPtr->tkpMakeMenuWindow)(tkwin, transient); -} - -/* Slot 66 */ -Window -TkpMakeWindow(winPtr, parent) - TkWindow * winPtr; - Window parent; -{ - return (tkIntStubsPtr->tkpMakeWindow)(winPtr, parent); -} - -/* Slot 67 */ -void -TkpMenuNotifyToplevelCreate(interp1, menuName) - Tcl_Interp * interp1; - char * menuName; -{ - (tkIntStubsPtr->tkpMenuNotifyToplevelCreate)(interp1, menuName); -} - -/* Slot 68 */ -TkDisplay * -TkpOpenDisplay(display_name) - char * display_name; -{ - return (tkIntStubsPtr->tkpOpenDisplay)(display_name); -} - -/* Slot 69 */ -int -TkPointerEvent(eventPtr, winPtr) - XEvent * eventPtr; - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkPointerEvent)(eventPtr, winPtr); -} - -/* Slot 70 */ -int -TkPolygonToArea(polyPtr, numPoints, rectPtr) - double * polyPtr; - int numPoints; - double * rectPtr; -{ - return (tkIntStubsPtr->tkPolygonToArea)(polyPtr, numPoints, rectPtr); -} - -/* Slot 71 */ -double -TkPolygonToPoint(polyPtr, numPoints, pointPtr) - double * polyPtr; - int numPoints; - double * pointPtr; -{ - return (tkIntStubsPtr->tkPolygonToPoint)(polyPtr, numPoints, pointPtr); -} - -/* Slot 72 */ -int -TkPositionInTree(winPtr, treePtr) - TkWindow * winPtr; - TkWindow * treePtr; -{ - return (tkIntStubsPtr->tkPositionInTree)(winPtr, treePtr); -} - -/* Slot 73 */ -void -TkpRedirectKeyEvent(winPtr, eventPtr) - TkWindow * winPtr; - XEvent * eventPtr; -{ - (tkIntStubsPtr->tkpRedirectKeyEvent)(winPtr, eventPtr); -} - -/* Slot 74 */ -void -TkpSetMainMenubar(interp, tkwin, menuName) - Tcl_Interp * interp; - Tk_Window tkwin; - char * menuName; -{ - (tkIntStubsPtr->tkpSetMainMenubar)(interp, tkwin, menuName); -} - -/* Slot 75 */ -int -TkpUseWindow(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - char * string; -{ - return (tkIntStubsPtr->tkpUseWindow)(interp, tkwin, string); -} - -/* Slot 76 */ -int -TkpWindowWasRecentlyDeleted(win, dispPtr) - Window win; - TkDisplay * dispPtr; -{ - return (tkIntStubsPtr->tkpWindowWasRecentlyDeleted)(win, dispPtr); -} - -/* Slot 77 */ -void -TkQueueEventForAllChildren(winPtr, eventPtr) - TkWindow * winPtr; - XEvent * eventPtr; -{ - (tkIntStubsPtr->tkQueueEventForAllChildren)(winPtr, eventPtr); -} - -/* Slot 78 */ -int -TkReadBitmapFile(display, d, filename, width_return, height_return, bitmap_return, x_hot_return, y_hot_return) - Display* display; - Drawable d; - CONST char* filename; - unsigned int* width_return; - unsigned int* height_return; - Pixmap* bitmap_return; - int* x_hot_return; - int* y_hot_return; -{ - return (tkIntStubsPtr->tkReadBitmapFile)(display, d, filename, width_return, height_return, bitmap_return, x_hot_return, y_hot_return); -} - -/* Slot 79 */ -int -TkScrollWindow(tkwin, gc, x, y, width, height, dx, dy, damageRgn) - Tk_Window tkwin; - GC gc; - int x; - int y; - int width; - int height; - int dx; - int dy; - TkRegion damageRgn; -{ - return (tkIntStubsPtr->tkScrollWindow)(tkwin, gc, x, y, width, height, dx, dy, damageRgn); -} - -/* Slot 80 */ -void -TkSelDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkSelDeadWindow)(winPtr); -} - -/* Slot 81 */ -void -TkSelEventProc(tkwin, eventPtr) - Tk_Window tkwin; - XEvent * eventPtr; -{ - (tkIntStubsPtr->tkSelEventProc)(tkwin, eventPtr); -} - -/* Slot 82 */ -void -TkSelInit(tkwin) - Tk_Window tkwin; -{ - (tkIntStubsPtr->tkSelInit)(tkwin); -} - -/* Slot 83 */ -void -TkSelPropProc(eventPtr) - XEvent * eventPtr; -{ - (tkIntStubsPtr->tkSelPropProc)(eventPtr); -} - -/* Slot 84 */ -void -TkSetClassProcs(tkwin, procs, instanceData) - Tk_Window tkwin; - TkClassProcs * procs; - ClientData instanceData; -{ - (tkIntStubsPtr->tkSetClassProcs)(tkwin, procs, instanceData); -} - -/* Slot 85 */ -void -TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName) - Tcl_Interp * interp; - Tk_Window tkwin; - char * oldMenuName; - char * menuName; -{ - (tkIntStubsPtr->tkSetWindowMenuBar)(interp, tkwin, oldMenuName, menuName); -} - -/* Slot 86 */ -KeySym -TkStringToKeysym(name) - char * name; -{ - return (tkIntStubsPtr->tkStringToKeysym)(name); -} - -/* Slot 87 */ -int -TkThickPolyLineToArea(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr) - double * coordPtr; - int numPoints; - double width; - int capStyle; - int joinStyle; - double * rectPtr; -{ - return (tkIntStubsPtr->tkThickPolyLineToArea)(coordPtr, numPoints, width, capStyle, joinStyle, rectPtr); -} - -/* Slot 88 */ -void -TkWmAddToColormapWindows(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmAddToColormapWindows)(winPtr); -} - -/* Slot 89 */ -void -TkWmDeadWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmDeadWindow)(winPtr); -} - -/* Slot 90 */ -TkWindow * -TkWmFocusToplevel(winPtr) - TkWindow * winPtr; -{ - return (tkIntStubsPtr->tkWmFocusToplevel)(winPtr); -} - -/* Slot 91 */ -void -TkWmMapWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmMapWindow)(winPtr); -} - -/* Slot 92 */ -void -TkWmNewWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmNewWindow)(winPtr); -} - -/* Slot 93 */ -void -TkWmProtocolEventProc(winPtr, evenvPtr) - TkWindow * winPtr; - XEvent * evenvPtr; -{ - (tkIntStubsPtr->tkWmProtocolEventProc)(winPtr, evenvPtr); -} - -/* Slot 94 */ -void -TkWmRemoveFromColormapWindows(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmRemoveFromColormapWindows)(winPtr); -} - -/* Slot 95 */ -void -TkWmRestackToplevel(winPtr, aboveBelow, otherPtr) - TkWindow * winPtr; - int aboveBelow; - TkWindow * otherPtr; -{ - (tkIntStubsPtr->tkWmRestackToplevel)(winPtr, aboveBelow, otherPtr); -} - -/* Slot 96 */ -void -TkWmSetClass(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmSetClass)(winPtr); -} - -/* Slot 97 */ -void -TkWmUnmapWindow(winPtr) - TkWindow * winPtr; -{ - (tkIntStubsPtr->tkWmUnmapWindow)(winPtr); -} - - -/* !END!: Do not edit above this line. */ diff --git a/generic/tkIntXlibDecls.h b/generic/tkIntXlibDecls.h index e9b9ab2..03d8209 100644 --- a/generic/tkIntXlibDecls.h +++ b/generic/tkIntXlibDecls.h @@ -9,12 +9,14 @@ * Copyright (c) 1998-1999 by Scriptics Corporation. * All rights reserved. * - * RCS: @(#) $Id: tkIntXlibDecls.h,v 1.4 1999/03/12 03:17:47 stanton Exp $ + * RCS: @(#) $Id: tkIntXlibDecls.h,v 1.5 1999/04/16 01:51:18 stanton Exp $ */ #ifndef _TKINTXLIBDECLS #define _TKINTXLIBDECLS +#include "X11/Xutil.h" + #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT @@ -277,6 +279,74 @@ EXTERN void TkPutImage _ANSI_ARGS_((unsigned long * colors, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)); +/* Slot 81 is reserved */ +/* 82 */ +EXTERN Status XParseColor _ANSI_ARGS_((Display * display, + Colormap map, _Xconst char* spec, + XColor * colorPtr)); +/* 83 */ +EXTERN GC XCreateGC _ANSI_ARGS_((Display* display, Drawable d, + unsigned long valuemask, XGCValues* values)); +/* 84 */ +EXTERN void XFreeGC _ANSI_ARGS_((Display* display, GC gc)); +/* 85 */ +EXTERN Atom XInternAtom _ANSI_ARGS_((Display* display, + _Xconst char* atom_name, Bool only_if_exists)); +/* 86 */ +EXTERN void XSetBackground _ANSI_ARGS_((Display* display, GC gc, + unsigned long foreground)); +/* 87 */ +EXTERN void XSetForeground _ANSI_ARGS_((Display* display, GC gc, + unsigned long foreground)); +/* 88 */ +EXTERN void XSetClipMask _ANSI_ARGS_((Display* display, GC gc, + Pixmap pixmap)); +/* 89 */ +EXTERN void XSetClipOrigin _ANSI_ARGS_((Display* display, GC gc, + int clip_x_origin, int clip_y_origin)); +/* 90 */ +EXTERN void XSetTSOrigin _ANSI_ARGS_((Display* display, GC gc, + int ts_x_origin, int ts_y_origin)); +/* 91 */ +EXTERN void XChangeGC _ANSI_ARGS_((Display * d, GC gc, + unsigned long mask, XGCValues * values)); +/* 92 */ +EXTERN void XSetFont _ANSI_ARGS_((Display * display, GC gc, + Font font)); +/* 93 */ +EXTERN void XSetArcMode _ANSI_ARGS_((Display * display, GC gc, + int arc_mode)); +/* 94 */ +EXTERN void XSetStipple _ANSI_ARGS_((Display * display, GC gc, + Pixmap stipple)); +/* 95 */ +EXTERN void XSetFillRule _ANSI_ARGS_((Display * display, GC gc, + int fill_rule)); +/* 96 */ +EXTERN void XSetFillStyle _ANSI_ARGS_((Display * display, GC gc, + int fill_style)); +/* 97 */ +EXTERN void XSetFunction _ANSI_ARGS_((Display * display, GC gc, + int function)); +/* 98 */ +EXTERN void XSetLineAttributes _ANSI_ARGS_((Display * display, + GC gc, unsigned int line_width, + int line_style, int cap_style, + int join_style)); +/* 99 */ +EXTERN int _XInitImageFuncPtrs _ANSI_ARGS_((XImage * image)); +/* 100 */ +EXTERN XIC XCreateIC _ANSI_ARGS_((void)); +/* 101 */ +EXTERN XVisualInfo * XGetVisualInfo _ANSI_ARGS_((Display* display, + long vinfo_mask, XVisualInfo* vinfo_template, + int* nitems_return)); +/* 102 */ +EXTERN void XSetWMClientMachine _ANSI_ARGS_((Display* display, + Window w, XTextProperty* text_prop)); +/* 103 */ +EXTERN Status XStringListToTextProperty _ANSI_ARGS_((char** list, + int count, XTextProperty* text_prop_return)); #endif /* __WIN32__ */ #ifdef MAC_TCL /* Slot 0 is reserved */ @@ -457,6 +527,73 @@ EXTERN void TkPutImage _ANSI_ARGS_((unsigned long * colors, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)); +/* 58 */ +EXTERN Status XParseColor _ANSI_ARGS_((Display * display, + Colormap map, _Xconst char* spec, + XColor * colorPtr)); +/* 59 */ +EXTERN GC XCreateGC _ANSI_ARGS_((Display* display, Drawable d, + unsigned long valuemask, XGCValues* values)); +/* 60 */ +EXTERN void XFreeGC _ANSI_ARGS_((Display* display, GC gc)); +/* 61 */ +EXTERN Atom XInternAtom _ANSI_ARGS_((Display* display, + _Xconst char* atom_name, Bool only_if_exists)); +/* 62 */ +EXTERN void XSetBackground _ANSI_ARGS_((Display* display, GC gc, + unsigned long foreground)); +/* 63 */ +EXTERN void XSetForeground _ANSI_ARGS_((Display* display, GC gc, + unsigned long foreground)); +/* 64 */ +EXTERN void XSetClipMask _ANSI_ARGS_((Display* display, GC gc, + Pixmap pixmap)); +/* 65 */ +EXTERN void XSetClipOrigin _ANSI_ARGS_((Display* display, GC gc, + int clip_x_origin, int clip_y_origin)); +/* 66 */ +EXTERN void XSetTSOrigin _ANSI_ARGS_((Display* display, GC gc, + int ts_x_origin, int ts_y_origin)); +/* 67 */ +EXTERN void XChangeGC _ANSI_ARGS_((Display * d, GC gc, + unsigned long mask, XGCValues * values)); +/* 68 */ +EXTERN void XSetFont _ANSI_ARGS_((Display * display, GC gc, + Font font)); +/* 69 */ +EXTERN void XSetArcMode _ANSI_ARGS_((Display * display, GC gc, + int arc_mode)); +/* 70 */ +EXTERN void XSetStipple _ANSI_ARGS_((Display * display, GC gc, + Pixmap stipple)); +/* 71 */ +EXTERN void XSetFillRule _ANSI_ARGS_((Display * display, GC gc, + int fill_rule)); +/* 72 */ +EXTERN void XSetFillStyle _ANSI_ARGS_((Display * display, GC gc, + int fill_style)); +/* 73 */ +EXTERN void XSetFunction _ANSI_ARGS_((Display * display, GC gc, + int function)); +/* 74 */ +EXTERN void XSetLineAttributes _ANSI_ARGS_((Display * display, + GC gc, unsigned int line_width, + int line_style, int cap_style, + int join_style)); +/* 75 */ +EXTERN int _XInitImageFuncPtrs _ANSI_ARGS_((XImage * image)); +/* 76 */ +EXTERN XIC XCreateIC _ANSI_ARGS_((void)); +/* 77 */ +EXTERN XVisualInfo * XGetVisualInfo _ANSI_ARGS_((Display* display, + long vinfo_mask, XVisualInfo* vinfo_template, + int* nitems_return)); +/* 78 */ +EXTERN void XSetWMClientMachine _ANSI_ARGS_((Display* display, + Window w, XTextProperty* text_prop)); +/* 79 */ +EXTERN Status XStringListToTextProperty _ANSI_ARGS_((char** list, + int count, XTextProperty* text_prop_return)); #endif /* MAC_TCL */ typedef struct TkIntXlibStubs { @@ -545,6 +682,29 @@ typedef struct TkIntXlibStubs { Bool (*xFilterEvent) _ANSI_ARGS_((XEvent* x, Window w)); /* 78 */ int (*xmbLookupString) _ANSI_ARGS_((XIC xi, XKeyPressedEvent* xk, char* c, int i, KeySym* k, Status* s)); /* 79 */ void (*tkPutImage) _ANSI_ARGS_((unsigned long * colors, int ncolors, Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)); /* 80 */ + void *reserved81; + Status (*xParseColor) _ANSI_ARGS_((Display * display, Colormap map, _Xconst char* spec, XColor * colorPtr)); /* 82 */ + GC (*xCreateGC) _ANSI_ARGS_((Display* display, Drawable d, unsigned long valuemask, XGCValues* values)); /* 83 */ + void (*xFreeGC) _ANSI_ARGS_((Display* display, GC gc)); /* 84 */ + Atom (*xInternAtom) _ANSI_ARGS_((Display* display, _Xconst char* atom_name, Bool only_if_exists)); /* 85 */ + void (*xSetBackground) _ANSI_ARGS_((Display* display, GC gc, unsigned long foreground)); /* 86 */ + void (*xSetForeground) _ANSI_ARGS_((Display* display, GC gc, unsigned long foreground)); /* 87 */ + void (*xSetClipMask) _ANSI_ARGS_((Display* display, GC gc, Pixmap pixmap)); /* 88 */ + void (*xSetClipOrigin) _ANSI_ARGS_((Display* display, GC gc, int clip_x_origin, int clip_y_origin)); /* 89 */ + void (*xSetTSOrigin) _ANSI_ARGS_((Display* display, GC gc, int ts_x_origin, int ts_y_origin)); /* 90 */ + void (*xChangeGC) _ANSI_ARGS_((Display * d, GC gc, unsigned long mask, XGCValues * values)); /* 91 */ + void (*xSetFont) _ANSI_ARGS_((Display * display, GC gc, Font font)); /* 92 */ + void (*xSetArcMode) _ANSI_ARGS_((Display * display, GC gc, int arc_mode)); /* 93 */ + void (*xSetStipple) _ANSI_ARGS_((Display * display, GC gc, Pixmap stipple)); /* 94 */ + void (*xSetFillRule) _ANSI_ARGS_((Display * display, GC gc, int fill_rule)); /* 95 */ + void (*xSetFillStyle) _ANSI_ARGS_((Display * display, GC gc, int fill_style)); /* 96 */ + void (*xSetFunction) _ANSI_ARGS_((Display * display, GC gc, int function)); /* 97 */ + void (*xSetLineAttributes) _ANSI_ARGS_((Display * display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style)); /* 98 */ + int (*_XInitImageFuncPtrs) _ANSI_ARGS_((XImage * image)); /* 99 */ + XIC (*xCreateIC) _ANSI_ARGS_((void)); /* 100 */ + XVisualInfo * (*xGetVisualInfo) _ANSI_ARGS_((Display* display, long vinfo_mask, XVisualInfo* vinfo_template, int* nitems_return)); /* 101 */ + void (*xSetWMClientMachine) _ANSI_ARGS_((Display* display, Window w, XTextProperty* text_prop)); /* 102 */ + Status (*xStringListToTextProperty) _ANSI_ARGS_((char** list, int count, XTextProperty* text_prop_return)); /* 103 */ #endif /* __WIN32__ */ #ifdef MAC_TCL void *reserved0; @@ -605,6 +765,28 @@ typedef struct TkIntXlibStubs { void (*xUngrabPointer) _ANSI_ARGS_((Display* d, Time t)); /* 55 */ void (*xUnmapWindow) _ANSI_ARGS_((Display* d, Window w)); /* 56 */ void (*tkPutImage) _ANSI_ARGS_((unsigned long * colors, int ncolors, Display* display, Drawable d, GC gc, XImage* image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)); /* 57 */ + Status (*xParseColor) _ANSI_ARGS_((Display * display, Colormap map, _Xconst char* spec, XColor * colorPtr)); /* 58 */ + GC (*xCreateGC) _ANSI_ARGS_((Display* display, Drawable d, unsigned long valuemask, XGCValues* values)); /* 59 */ + void (*xFreeGC) _ANSI_ARGS_((Display* display, GC gc)); /* 60 */ + Atom (*xInternAtom) _ANSI_ARGS_((Display* display, _Xconst char* atom_name, Bool only_if_exists)); /* 61 */ + void (*xSetBackground) _ANSI_ARGS_((Display* display, GC gc, unsigned long foreground)); /* 62 */ + void (*xSetForeground) _ANSI_ARGS_((Display* display, GC gc, unsigned long foreground)); /* 63 */ + void (*xSetClipMask) _ANSI_ARGS_((Display* display, GC gc, Pixmap pixmap)); /* 64 */ + void (*xSetClipOrigin) _ANSI_ARGS_((Display* display, GC gc, int clip_x_origin, int clip_y_origin)); /* 65 */ + void (*xSetTSOrigin) _ANSI_ARGS_((Display* display, GC gc, int ts_x_origin, int ts_y_origin)); /* 66 */ + void (*xChangeGC) _ANSI_ARGS_((Display * d, GC gc, unsigned long mask, XGCValues * values)); /* 67 */ + void (*xSetFont) _ANSI_ARGS_((Display * display, GC gc, Font font)); /* 68 */ + void (*xSetArcMode) _ANSI_ARGS_((Display * display, GC gc, int arc_mode)); /* 69 */ + void (*xSetStipple) _ANSI_ARGS_((Display * display, GC gc, Pixmap stipple)); /* 70 */ + void (*xSetFillRule) _ANSI_ARGS_((Display * display, GC gc, int fill_rule)); /* 71 */ + void (*xSetFillStyle) _ANSI_ARGS_((Display * display, GC gc, int fill_style)); /* 72 */ + void (*xSetFunction) _ANSI_ARGS_((Display * display, GC gc, int function)); /* 73 */ + void (*xSetLineAttributes) _ANSI_ARGS_((Display * display, GC gc, unsigned int line_width, int line_style, int cap_style, int join_style)); /* 74 */ + int (*_XInitImageFuncPtrs) _ANSI_ARGS_((XImage * image)); /* 75 */ + XIC (*xCreateIC) _ANSI_ARGS_((void)); /* 76 */ + XVisualInfo * (*xGetVisualInfo) _ANSI_ARGS_((Display* display, long vinfo_mask, XVisualInfo* vinfo_template, int* nitems_return)); /* 77 */ + void (*xSetWMClientMachine) _ANSI_ARGS_((Display* display, Window w, XTextProperty* text_prop)); /* 78 */ + Status (*xStringListToTextProperty) _ANSI_ARGS_((char** list, int count, XTextProperty* text_prop_return)); /* 79 */ #endif /* MAC_TCL */ } TkIntXlibStubs; @@ -619,555 +801,732 @@ extern TkIntXlibStubs *tkIntXlibStubsPtr; #ifdef __WIN32__ /* Slot 0 is reserved */ #ifndef XGetModifierMapping -#define XGetModifierMapping(d) \ - (tkIntXlibStubsPtr->xGetModifierMapping)(d) /* 1 */ +#define XGetModifierMapping \ + (tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */ #endif #ifndef XCreateImage -#define XCreateImage(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) \ - (tkIntXlibStubsPtr->xCreateImage)(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) /* 2 */ +#define XCreateImage \ + (tkIntXlibStubsPtr->xCreateImage) /* 2 */ #endif #ifndef XGetImage -#define XGetImage(d, dr, i1, i2, ui1, ui2, ul, i3) \ - (tkIntXlibStubsPtr->xGetImage)(d, dr, i1, i2, ui1, ui2, ul, i3) /* 3 */ +#define XGetImage \ + (tkIntXlibStubsPtr->xGetImage) /* 3 */ #endif #ifndef XGetAtomName -#define XGetAtomName(d, a) \ - (tkIntXlibStubsPtr->xGetAtomName)(d, a) /* 4 */ +#define XGetAtomName \ + (tkIntXlibStubsPtr->xGetAtomName) /* 4 */ #endif #ifndef XKeysymToString -#define XKeysymToString(k) \ - (tkIntXlibStubsPtr->xKeysymToString)(k) /* 5 */ +#define XKeysymToString \ + (tkIntXlibStubsPtr->xKeysymToString) /* 5 */ #endif #ifndef XCreateColormap -#define XCreateColormap(d, w, v, i) \ - (tkIntXlibStubsPtr->xCreateColormap)(d, w, v, i) /* 6 */ +#define XCreateColormap \ + (tkIntXlibStubsPtr->xCreateColormap) /* 6 */ #endif #ifndef XCreatePixmapCursor -#define XCreatePixmapCursor(d, p1, p2, x1, x2, ui1, ui2) \ - (tkIntXlibStubsPtr->xCreatePixmapCursor)(d, p1, p2, x1, x2, ui1, ui2) /* 7 */ +#define XCreatePixmapCursor \ + (tkIntXlibStubsPtr->xCreatePixmapCursor) /* 7 */ #endif #ifndef XCreateGlyphCursor -#define XCreateGlyphCursor(d, f1, f2, ui1, ui2, x1, x2) \ - (tkIntXlibStubsPtr->xCreateGlyphCursor)(d, f1, f2, ui1, ui2, x1, x2) /* 8 */ +#define XCreateGlyphCursor \ + (tkIntXlibStubsPtr->xCreateGlyphCursor) /* 8 */ #endif #ifndef XGContextFromGC -#define XGContextFromGC(g) \ - (tkIntXlibStubsPtr->xGContextFromGC)(g) /* 9 */ +#define XGContextFromGC \ + (tkIntXlibStubsPtr->xGContextFromGC) /* 9 */ #endif #ifndef XListHosts -#define XListHosts(d, i, b) \ - (tkIntXlibStubsPtr->xListHosts)(d, i, b) /* 10 */ +#define XListHosts \ + (tkIntXlibStubsPtr->xListHosts) /* 10 */ #endif #ifndef XKeycodeToKeysym -#define XKeycodeToKeysym(d, k, i) \ - (tkIntXlibStubsPtr->xKeycodeToKeysym)(d, k, i) /* 11 */ +#define XKeycodeToKeysym \ + (tkIntXlibStubsPtr->xKeycodeToKeysym) /* 11 */ #endif #ifndef XStringToKeysym -#define XStringToKeysym(c) \ - (tkIntXlibStubsPtr->xStringToKeysym)(c) /* 12 */ +#define XStringToKeysym \ + (tkIntXlibStubsPtr->xStringToKeysym) /* 12 */ #endif #ifndef XRootWindow -#define XRootWindow(d, i) \ - (tkIntXlibStubsPtr->xRootWindow)(d, i) /* 13 */ +#define XRootWindow \ + (tkIntXlibStubsPtr->xRootWindow) /* 13 */ #endif #ifndef XSetErrorHandler -#define XSetErrorHandler(x) \ - (tkIntXlibStubsPtr->xSetErrorHandler)(x) /* 14 */ +#define XSetErrorHandler \ + (tkIntXlibStubsPtr->xSetErrorHandler) /* 14 */ #endif #ifndef XIconifyWindow -#define XIconifyWindow(d, w, i) \ - (tkIntXlibStubsPtr->xIconifyWindow)(d, w, i) /* 15 */ +#define XIconifyWindow \ + (tkIntXlibStubsPtr->xIconifyWindow) /* 15 */ #endif #ifndef XWithdrawWindow -#define XWithdrawWindow(d, w, i) \ - (tkIntXlibStubsPtr->xWithdrawWindow)(d, w, i) /* 16 */ +#define XWithdrawWindow \ + (tkIntXlibStubsPtr->xWithdrawWindow) /* 16 */ #endif #ifndef XGetWMColormapWindows -#define XGetWMColormapWindows(d, w, wpp, ip) \ - (tkIntXlibStubsPtr->xGetWMColormapWindows)(d, w, wpp, ip) /* 17 */ +#define XGetWMColormapWindows \ + (tkIntXlibStubsPtr->xGetWMColormapWindows) /* 17 */ #endif #ifndef XAllocColor -#define XAllocColor(d, c, xp) \ - (tkIntXlibStubsPtr->xAllocColor)(d, c, xp) /* 18 */ +#define XAllocColor \ + (tkIntXlibStubsPtr->xAllocColor) /* 18 */ #endif #ifndef XBell -#define XBell(d, i) \ - (tkIntXlibStubsPtr->xBell)(d, i) /* 19 */ +#define XBell \ + (tkIntXlibStubsPtr->xBell) /* 19 */ #endif #ifndef XChangeProperty -#define XChangeProperty(d, w, a1, a2, i1, i2, c, i3) \ - (tkIntXlibStubsPtr->xChangeProperty)(d, w, a1, a2, i1, i2, c, i3) /* 20 */ +#define XChangeProperty \ + (tkIntXlibStubsPtr->xChangeProperty) /* 20 */ #endif #ifndef XChangeWindowAttributes -#define XChangeWindowAttributes(d, w, ul, x) \ - (tkIntXlibStubsPtr->xChangeWindowAttributes)(d, w, ul, x) /* 21 */ +#define XChangeWindowAttributes \ + (tkIntXlibStubsPtr->xChangeWindowAttributes) /* 21 */ #endif #ifndef XClearWindow -#define XClearWindow(d, w) \ - (tkIntXlibStubsPtr->xClearWindow)(d, w) /* 22 */ +#define XClearWindow \ + (tkIntXlibStubsPtr->xClearWindow) /* 22 */ #endif #ifndef XConfigureWindow -#define XConfigureWindow(d, w, i, x) \ - (tkIntXlibStubsPtr->xConfigureWindow)(d, w, i, x) /* 23 */ +#define XConfigureWindow \ + (tkIntXlibStubsPtr->xConfigureWindow) /* 23 */ #endif #ifndef XCopyArea -#define XCopyArea(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xCopyArea)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) /* 24 */ +#define XCopyArea \ + (tkIntXlibStubsPtr->xCopyArea) /* 24 */ #endif #ifndef XCopyPlane -#define XCopyPlane(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) \ - (tkIntXlibStubsPtr->xCopyPlane)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) /* 25 */ +#define XCopyPlane \ + (tkIntXlibStubsPtr->xCopyPlane) /* 25 */ #endif #ifndef XCreateBitmapFromData -#define XCreateBitmapFromData(display, d, data, width, height) \ - (tkIntXlibStubsPtr->xCreateBitmapFromData)(display, d, data, width, height) /* 26 */ +#define XCreateBitmapFromData \ + (tkIntXlibStubsPtr->xCreateBitmapFromData) /* 26 */ #endif #ifndef XDefineCursor -#define XDefineCursor(d, w, c) \ - (tkIntXlibStubsPtr->xDefineCursor)(d, w, c) /* 27 */ +#define XDefineCursor \ + (tkIntXlibStubsPtr->xDefineCursor) /* 27 */ #endif #ifndef XDeleteProperty -#define XDeleteProperty(d, w, a) \ - (tkIntXlibStubsPtr->xDeleteProperty)(d, w, a) /* 28 */ +#define XDeleteProperty \ + (tkIntXlibStubsPtr->xDeleteProperty) /* 28 */ #endif #ifndef XDestroyWindow -#define XDestroyWindow(d, w) \ - (tkIntXlibStubsPtr->xDestroyWindow)(d, w) /* 29 */ +#define XDestroyWindow \ + (tkIntXlibStubsPtr->xDestroyWindow) /* 29 */ #endif #ifndef XDrawArc -#define XDrawArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xDrawArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4) /* 30 */ +#define XDrawArc \ + (tkIntXlibStubsPtr->xDrawArc) /* 30 */ #endif #ifndef XDrawLines -#define XDrawLines(d, dr, g, x, i1, i2) \ - (tkIntXlibStubsPtr->xDrawLines)(d, dr, g, x, i1, i2) /* 31 */ +#define XDrawLines \ + (tkIntXlibStubsPtr->xDrawLines) /* 31 */ #endif #ifndef XDrawRectangle -#define XDrawRectangle(d, dr, g, i1, i2, ui1, ui2) \ - (tkIntXlibStubsPtr->xDrawRectangle)(d, dr, g, i1, i2, ui1, ui2) /* 32 */ +#define XDrawRectangle \ + (tkIntXlibStubsPtr->xDrawRectangle) /* 32 */ #endif #ifndef XFillArc -#define XFillArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xFillArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4) /* 33 */ +#define XFillArc \ + (tkIntXlibStubsPtr->xFillArc) /* 33 */ #endif #ifndef XFillPolygon -#define XFillPolygon(d, dr, g, x, i1, i2, i3) \ - (tkIntXlibStubsPtr->xFillPolygon)(d, dr, g, x, i1, i2, i3) /* 34 */ +#define XFillPolygon \ + (tkIntXlibStubsPtr->xFillPolygon) /* 34 */ #endif #ifndef XFillRectangles -#define XFillRectangles(d, dr, g, x, i) \ - (tkIntXlibStubsPtr->xFillRectangles)(d, dr, g, x, i) /* 35 */ +#define XFillRectangles \ + (tkIntXlibStubsPtr->xFillRectangles) /* 35 */ #endif #ifndef XForceScreenSaver -#define XForceScreenSaver(d, i) \ - (tkIntXlibStubsPtr->xForceScreenSaver)(d, i) /* 36 */ +#define XForceScreenSaver \ + (tkIntXlibStubsPtr->xForceScreenSaver) /* 36 */ #endif #ifndef XFreeColormap -#define XFreeColormap(d, c) \ - (tkIntXlibStubsPtr->xFreeColormap)(d, c) /* 37 */ +#define XFreeColormap \ + (tkIntXlibStubsPtr->xFreeColormap) /* 37 */ #endif #ifndef XFreeColors -#define XFreeColors(d, c, ulp, i, ul) \ - (tkIntXlibStubsPtr->xFreeColors)(d, c, ulp, i, ul) /* 38 */ +#define XFreeColors \ + (tkIntXlibStubsPtr->xFreeColors) /* 38 */ #endif #ifndef XFreeCursor -#define XFreeCursor(d, c) \ - (tkIntXlibStubsPtr->xFreeCursor)(d, c) /* 39 */ +#define XFreeCursor \ + (tkIntXlibStubsPtr->xFreeCursor) /* 39 */ #endif #ifndef XFreeModifiermap -#define XFreeModifiermap(x) \ - (tkIntXlibStubsPtr->xFreeModifiermap)(x) /* 40 */ +#define XFreeModifiermap \ + (tkIntXlibStubsPtr->xFreeModifiermap) /* 40 */ #endif #ifndef XGetGeometry -#define XGetGeometry(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) \ - (tkIntXlibStubsPtr->xGetGeometry)(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) /* 41 */ +#define XGetGeometry \ + (tkIntXlibStubsPtr->xGetGeometry) /* 41 */ #endif #ifndef XGetInputFocus -#define XGetInputFocus(d, w, i) \ - (tkIntXlibStubsPtr->xGetInputFocus)(d, w, i) /* 42 */ +#define XGetInputFocus \ + (tkIntXlibStubsPtr->xGetInputFocus) /* 42 */ #endif #ifndef XGetWindowProperty -#define XGetWindowProperty(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) \ - (tkIntXlibStubsPtr->xGetWindowProperty)(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) /* 43 */ +#define XGetWindowProperty \ + (tkIntXlibStubsPtr->xGetWindowProperty) /* 43 */ #endif #ifndef XGetWindowAttributes -#define XGetWindowAttributes(d, w, x) \ - (tkIntXlibStubsPtr->xGetWindowAttributes)(d, w, x) /* 44 */ +#define XGetWindowAttributes \ + (tkIntXlibStubsPtr->xGetWindowAttributes) /* 44 */ #endif #ifndef XGrabKeyboard -#define XGrabKeyboard(d, w, b, i1, i2, t) \ - (tkIntXlibStubsPtr->xGrabKeyboard)(d, w, b, i1, i2, t) /* 45 */ +#define XGrabKeyboard \ + (tkIntXlibStubsPtr->xGrabKeyboard) /* 45 */ #endif #ifndef XGrabPointer -#define XGrabPointer(d, w1, b, ui, i1, i2, w2, c, t) \ - (tkIntXlibStubsPtr->xGrabPointer)(d, w1, b, ui, i1, i2, w2, c, t) /* 46 */ +#define XGrabPointer \ + (tkIntXlibStubsPtr->xGrabPointer) /* 46 */ #endif #ifndef XKeysymToKeycode -#define XKeysymToKeycode(d, k) \ - (tkIntXlibStubsPtr->xKeysymToKeycode)(d, k) /* 47 */ +#define XKeysymToKeycode \ + (tkIntXlibStubsPtr->xKeysymToKeycode) /* 47 */ #endif #ifndef XLookupColor -#define XLookupColor(d, c1, c2, x1, x2) \ - (tkIntXlibStubsPtr->xLookupColor)(d, c1, c2, x1, x2) /* 48 */ +#define XLookupColor \ + (tkIntXlibStubsPtr->xLookupColor) /* 48 */ #endif #ifndef XMapWindow -#define XMapWindow(d, w) \ - (tkIntXlibStubsPtr->xMapWindow)(d, w) /* 49 */ +#define XMapWindow \ + (tkIntXlibStubsPtr->xMapWindow) /* 49 */ #endif #ifndef XMoveResizeWindow -#define XMoveResizeWindow(d, w, i1, i2, ui1, ui2) \ - (tkIntXlibStubsPtr->xMoveResizeWindow)(d, w, i1, i2, ui1, ui2) /* 50 */ +#define XMoveResizeWindow \ + (tkIntXlibStubsPtr->xMoveResizeWindow) /* 50 */ #endif #ifndef XMoveWindow -#define XMoveWindow(d, w, i1, i2) \ - (tkIntXlibStubsPtr->xMoveWindow)(d, w, i1, i2) /* 51 */ +#define XMoveWindow \ + (tkIntXlibStubsPtr->xMoveWindow) /* 51 */ #endif #ifndef XNextEvent -#define XNextEvent(d, x) \ - (tkIntXlibStubsPtr->xNextEvent)(d, x) /* 52 */ +#define XNextEvent \ + (tkIntXlibStubsPtr->xNextEvent) /* 52 */ #endif #ifndef XPutBackEvent -#define XPutBackEvent(d, x) \ - (tkIntXlibStubsPtr->xPutBackEvent)(d, x) /* 53 */ +#define XPutBackEvent \ + (tkIntXlibStubsPtr->xPutBackEvent) /* 53 */ #endif #ifndef XQueryColors -#define XQueryColors(d, c, x, i) \ - (tkIntXlibStubsPtr->xQueryColors)(d, c, x, i) /* 54 */ +#define XQueryColors \ + (tkIntXlibStubsPtr->xQueryColors) /* 54 */ #endif #ifndef XQueryPointer -#define XQueryPointer(d, w1, w2, w3, i1, i2, i3, i4, ui) \ - (tkIntXlibStubsPtr->xQueryPointer)(d, w1, w2, w3, i1, i2, i3, i4, ui) /* 55 */ +#define XQueryPointer \ + (tkIntXlibStubsPtr->xQueryPointer) /* 55 */ #endif #ifndef XQueryTree -#define XQueryTree(d, w1, w2, w3, w4, ui) \ - (tkIntXlibStubsPtr->xQueryTree)(d, w1, w2, w3, w4, ui) /* 56 */ +#define XQueryTree \ + (tkIntXlibStubsPtr->xQueryTree) /* 56 */ #endif #ifndef XRaiseWindow -#define XRaiseWindow(d, w) \ - (tkIntXlibStubsPtr->xRaiseWindow)(d, w) /* 57 */ +#define XRaiseWindow \ + (tkIntXlibStubsPtr->xRaiseWindow) /* 57 */ #endif #ifndef XRefreshKeyboardMapping -#define XRefreshKeyboardMapping(x) \ - (tkIntXlibStubsPtr->xRefreshKeyboardMapping)(x) /* 58 */ +#define XRefreshKeyboardMapping \ + (tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 58 */ #endif #ifndef XResizeWindow -#define XResizeWindow(d, w, ui1, ui2) \ - (tkIntXlibStubsPtr->xResizeWindow)(d, w, ui1, ui2) /* 59 */ +#define XResizeWindow \ + (tkIntXlibStubsPtr->xResizeWindow) /* 59 */ #endif #ifndef XSelectInput -#define XSelectInput(d, w, l) \ - (tkIntXlibStubsPtr->xSelectInput)(d, w, l) /* 60 */ +#define XSelectInput \ + (tkIntXlibStubsPtr->xSelectInput) /* 60 */ #endif #ifndef XSendEvent -#define XSendEvent(d, w, b, l, x) \ - (tkIntXlibStubsPtr->xSendEvent)(d, w, b, l, x) /* 61 */ +#define XSendEvent \ + (tkIntXlibStubsPtr->xSendEvent) /* 61 */ #endif #ifndef XSetCommand -#define XSetCommand(d, w, c, i) \ - (tkIntXlibStubsPtr->xSetCommand)(d, w, c, i) /* 62 */ +#define XSetCommand \ + (tkIntXlibStubsPtr->xSetCommand) /* 62 */ #endif #ifndef XSetIconName -#define XSetIconName(d, w, c) \ - (tkIntXlibStubsPtr->xSetIconName)(d, w, c) /* 63 */ +#define XSetIconName \ + (tkIntXlibStubsPtr->xSetIconName) /* 63 */ #endif #ifndef XSetInputFocus -#define XSetInputFocus(d, w, i, t) \ - (tkIntXlibStubsPtr->xSetInputFocus)(d, w, i, t) /* 64 */ +#define XSetInputFocus \ + (tkIntXlibStubsPtr->xSetInputFocus) /* 64 */ #endif #ifndef XSetSelectionOwner -#define XSetSelectionOwner(d, a, w, t) \ - (tkIntXlibStubsPtr->xSetSelectionOwner)(d, a, w, t) /* 65 */ +#define XSetSelectionOwner \ + (tkIntXlibStubsPtr->xSetSelectionOwner) /* 65 */ #endif #ifndef XSetWindowBackground -#define XSetWindowBackground(d, w, ul) \ - (tkIntXlibStubsPtr->xSetWindowBackground)(d, w, ul) /* 66 */ +#define XSetWindowBackground \ + (tkIntXlibStubsPtr->xSetWindowBackground) /* 66 */ #endif #ifndef XSetWindowBackgroundPixmap -#define XSetWindowBackgroundPixmap(d, w, p) \ - (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap)(d, w, p) /* 67 */ +#define XSetWindowBackgroundPixmap \ + (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 67 */ #endif #ifndef XSetWindowBorder -#define XSetWindowBorder(d, w, ul) \ - (tkIntXlibStubsPtr->xSetWindowBorder)(d, w, ul) /* 68 */ +#define XSetWindowBorder \ + (tkIntXlibStubsPtr->xSetWindowBorder) /* 68 */ #endif #ifndef XSetWindowBorderPixmap -#define XSetWindowBorderPixmap(d, w, p) \ - (tkIntXlibStubsPtr->xSetWindowBorderPixmap)(d, w, p) /* 69 */ +#define XSetWindowBorderPixmap \ + (tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 69 */ #endif #ifndef XSetWindowBorderWidth -#define XSetWindowBorderWidth(d, w, ui) \ - (tkIntXlibStubsPtr->xSetWindowBorderWidth)(d, w, ui) /* 70 */ +#define XSetWindowBorderWidth \ + (tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 70 */ #endif #ifndef XSetWindowColormap -#define XSetWindowColormap(d, w, c) \ - (tkIntXlibStubsPtr->xSetWindowColormap)(d, w, c) /* 71 */ +#define XSetWindowColormap \ + (tkIntXlibStubsPtr->xSetWindowColormap) /* 71 */ #endif #ifndef XTranslateCoordinates -#define XTranslateCoordinates(d, w1, w2, i1, i2, i3, i4, w3) \ - (tkIntXlibStubsPtr->xTranslateCoordinates)(d, w1, w2, i1, i2, i3, i4, w3) /* 72 */ +#define XTranslateCoordinates \ + (tkIntXlibStubsPtr->xTranslateCoordinates) /* 72 */ #endif #ifndef XUngrabKeyboard -#define XUngrabKeyboard(d, t) \ - (tkIntXlibStubsPtr->xUngrabKeyboard)(d, t) /* 73 */ +#define XUngrabKeyboard \ + (tkIntXlibStubsPtr->xUngrabKeyboard) /* 73 */ #endif #ifndef XUngrabPointer -#define XUngrabPointer(d, t) \ - (tkIntXlibStubsPtr->xUngrabPointer)(d, t) /* 74 */ +#define XUngrabPointer \ + (tkIntXlibStubsPtr->xUngrabPointer) /* 74 */ #endif #ifndef XUnmapWindow -#define XUnmapWindow(d, w) \ - (tkIntXlibStubsPtr->xUnmapWindow)(d, w) /* 75 */ +#define XUnmapWindow \ + (tkIntXlibStubsPtr->xUnmapWindow) /* 75 */ #endif #ifndef XWindowEvent -#define XWindowEvent(d, w, l, x) \ - (tkIntXlibStubsPtr->xWindowEvent)(d, w, l, x) /* 76 */ +#define XWindowEvent \ + (tkIntXlibStubsPtr->xWindowEvent) /* 76 */ #endif #ifndef XDestroyIC -#define XDestroyIC(x) \ - (tkIntXlibStubsPtr->xDestroyIC)(x) /* 77 */ +#define XDestroyIC \ + (tkIntXlibStubsPtr->xDestroyIC) /* 77 */ #endif #ifndef XFilterEvent -#define XFilterEvent(x, w) \ - (tkIntXlibStubsPtr->xFilterEvent)(x, w) /* 78 */ +#define XFilterEvent \ + (tkIntXlibStubsPtr->xFilterEvent) /* 78 */ #endif #ifndef XmbLookupString -#define XmbLookupString(xi, xk, c, i, k, s) \ - (tkIntXlibStubsPtr->xmbLookupString)(xi, xk, c, i, k, s) /* 79 */ +#define XmbLookupString \ + (tkIntXlibStubsPtr->xmbLookupString) /* 79 */ #endif #ifndef TkPutImage -#define TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) \ - (tkIntXlibStubsPtr->tkPutImage)(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) /* 80 */ +#define TkPutImage \ + (tkIntXlibStubsPtr->tkPutImage) /* 80 */ +#endif +/* Slot 81 is reserved */ +#ifndef XParseColor +#define XParseColor \ + (tkIntXlibStubsPtr->xParseColor) /* 82 */ +#endif +#ifndef XCreateGC +#define XCreateGC \ + (tkIntXlibStubsPtr->xCreateGC) /* 83 */ +#endif +#ifndef XFreeGC +#define XFreeGC \ + (tkIntXlibStubsPtr->xFreeGC) /* 84 */ +#endif +#ifndef XInternAtom +#define XInternAtom \ + (tkIntXlibStubsPtr->xInternAtom) /* 85 */ +#endif +#ifndef XSetBackground +#define XSetBackground \ + (tkIntXlibStubsPtr->xSetBackground) /* 86 */ +#endif +#ifndef XSetForeground +#define XSetForeground \ + (tkIntXlibStubsPtr->xSetForeground) /* 87 */ +#endif +#ifndef XSetClipMask +#define XSetClipMask \ + (tkIntXlibStubsPtr->xSetClipMask) /* 88 */ +#endif +#ifndef XSetClipOrigin +#define XSetClipOrigin \ + (tkIntXlibStubsPtr->xSetClipOrigin) /* 89 */ +#endif +#ifndef XSetTSOrigin +#define XSetTSOrigin \ + (tkIntXlibStubsPtr->xSetTSOrigin) /* 90 */ +#endif +#ifndef XChangeGC +#define XChangeGC \ + (tkIntXlibStubsPtr->xChangeGC) /* 91 */ +#endif +#ifndef XSetFont +#define XSetFont \ + (tkIntXlibStubsPtr->xSetFont) /* 92 */ +#endif +#ifndef XSetArcMode +#define XSetArcMode \ + (tkIntXlibStubsPtr->xSetArcMode) /* 93 */ +#endif +#ifndef XSetStipple +#define XSetStipple \ + (tkIntXlibStubsPtr->xSetStipple) /* 94 */ +#endif +#ifndef XSetFillRule +#define XSetFillRule \ + (tkIntXlibStubsPtr->xSetFillRule) /* 95 */ +#endif +#ifndef XSetFillStyle +#define XSetFillStyle \ + (tkIntXlibStubsPtr->xSetFillStyle) /* 96 */ +#endif +#ifndef XSetFunction +#define XSetFunction \ + (tkIntXlibStubsPtr->xSetFunction) /* 97 */ +#endif +#ifndef XSetLineAttributes +#define XSetLineAttributes \ + (tkIntXlibStubsPtr->xSetLineAttributes) /* 98 */ +#endif +#ifndef _XInitImageFuncPtrs +#define _XInitImageFuncPtrs \ + (tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 99 */ +#endif +#ifndef XCreateIC +#define XCreateIC \ + (tkIntXlibStubsPtr->xCreateIC) /* 100 */ +#endif +#ifndef XGetVisualInfo +#define XGetVisualInfo \ + (tkIntXlibStubsPtr->xGetVisualInfo) /* 101 */ +#endif +#ifndef XSetWMClientMachine +#define XSetWMClientMachine \ + (tkIntXlibStubsPtr->xSetWMClientMachine) /* 102 */ +#endif +#ifndef XStringListToTextProperty +#define XStringListToTextProperty \ + (tkIntXlibStubsPtr->xStringListToTextProperty) /* 103 */ #endif #endif /* __WIN32__ */ #ifdef MAC_TCL /* Slot 0 is reserved */ #ifndef XGetModifierMapping -#define XGetModifierMapping(d) \ - (tkIntXlibStubsPtr->xGetModifierMapping)(d) /* 1 */ +#define XGetModifierMapping \ + (tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */ #endif #ifndef XCreateImage -#define XCreateImage(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) \ - (tkIntXlibStubsPtr->xCreateImage)(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) /* 2 */ +#define XCreateImage \ + (tkIntXlibStubsPtr->xCreateImage) /* 2 */ #endif #ifndef XGetImage -#define XGetImage(d, dr, i1, i2, ui1, ui2, ul, i3) \ - (tkIntXlibStubsPtr->xGetImage)(d, dr, i1, i2, ui1, ui2, ul, i3) /* 3 */ +#define XGetImage \ + (tkIntXlibStubsPtr->xGetImage) /* 3 */ #endif #ifndef XGetAtomName -#define XGetAtomName(d, a) \ - (tkIntXlibStubsPtr->xGetAtomName)(d, a) /* 4 */ +#define XGetAtomName \ + (tkIntXlibStubsPtr->xGetAtomName) /* 4 */ #endif #ifndef XKeysymToString -#define XKeysymToString(k) \ - (tkIntXlibStubsPtr->xKeysymToString)(k) /* 5 */ +#define XKeysymToString \ + (tkIntXlibStubsPtr->xKeysymToString) /* 5 */ #endif #ifndef XCreateColormap -#define XCreateColormap(d, w, v, i) \ - (tkIntXlibStubsPtr->xCreateColormap)(d, w, v, i) /* 6 */ +#define XCreateColormap \ + (tkIntXlibStubsPtr->xCreateColormap) /* 6 */ #endif #ifndef XGContextFromGC -#define XGContextFromGC(g) \ - (tkIntXlibStubsPtr->xGContextFromGC)(g) /* 7 */ +#define XGContextFromGC \ + (tkIntXlibStubsPtr->xGContextFromGC) /* 7 */ #endif #ifndef XKeycodeToKeysym -#define XKeycodeToKeysym(d, k, i) \ - (tkIntXlibStubsPtr->xKeycodeToKeysym)(d, k, i) /* 8 */ +#define XKeycodeToKeysym \ + (tkIntXlibStubsPtr->xKeycodeToKeysym) /* 8 */ #endif #ifndef XStringToKeysym -#define XStringToKeysym(c) \ - (tkIntXlibStubsPtr->xStringToKeysym)(c) /* 9 */ +#define XStringToKeysym \ + (tkIntXlibStubsPtr->xStringToKeysym) /* 9 */ #endif #ifndef XRootWindow -#define XRootWindow(d, i) \ - (tkIntXlibStubsPtr->xRootWindow)(d, i) /* 10 */ +#define XRootWindow \ + (tkIntXlibStubsPtr->xRootWindow) /* 10 */ #endif #ifndef XSetErrorHandler -#define XSetErrorHandler(x) \ - (tkIntXlibStubsPtr->xSetErrorHandler)(x) /* 11 */ +#define XSetErrorHandler \ + (tkIntXlibStubsPtr->xSetErrorHandler) /* 11 */ #endif #ifndef XAllocColor -#define XAllocColor(d, c, xp) \ - (tkIntXlibStubsPtr->xAllocColor)(d, c, xp) /* 12 */ +#define XAllocColor \ + (tkIntXlibStubsPtr->xAllocColor) /* 12 */ #endif #ifndef XBell -#define XBell(d, i) \ - (tkIntXlibStubsPtr->xBell)(d, i) /* 13 */ +#define XBell \ + (tkIntXlibStubsPtr->xBell) /* 13 */ #endif #ifndef XChangeProperty -#define XChangeProperty(d, w, a, a, i1, i2, c, i3) \ - (tkIntXlibStubsPtr->xChangeProperty)(d, w, a, a, i1, i2, c, i3) /* 14 */ +#define XChangeProperty \ + (tkIntXlibStubsPtr->xChangeProperty) /* 14 */ #endif #ifndef XChangeWindowAttributes -#define XChangeWindowAttributes(d, w, ul, x) \ - (tkIntXlibStubsPtr->xChangeWindowAttributes)(d, w, ul, x) /* 15 */ +#define XChangeWindowAttributes \ + (tkIntXlibStubsPtr->xChangeWindowAttributes) /* 15 */ #endif #ifndef XConfigureWindow -#define XConfigureWindow(d, w, i, x) \ - (tkIntXlibStubsPtr->xConfigureWindow)(d, w, i, x) /* 16 */ +#define XConfigureWindow \ + (tkIntXlibStubsPtr->xConfigureWindow) /* 16 */ #endif #ifndef XCopyArea -#define XCopyArea(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xCopyArea)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) /* 17 */ +#define XCopyArea \ + (tkIntXlibStubsPtr->xCopyArea) /* 17 */ #endif #ifndef XCopyPlane -#define XCopyPlane(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) \ - (tkIntXlibStubsPtr->xCopyPlane)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) /* 18 */ +#define XCopyPlane \ + (tkIntXlibStubsPtr->xCopyPlane) /* 18 */ #endif #ifndef XCreateBitmapFromData -#define XCreateBitmapFromData(display, d, data, width, height) \ - (tkIntXlibStubsPtr->xCreateBitmapFromData)(display, d, data, width, height) /* 19 */ +#define XCreateBitmapFromData \ + (tkIntXlibStubsPtr->xCreateBitmapFromData) /* 19 */ #endif #ifndef XDefineCursor -#define XDefineCursor(d, w, c) \ - (tkIntXlibStubsPtr->xDefineCursor)(d, w, c) /* 20 */ +#define XDefineCursor \ + (tkIntXlibStubsPtr->xDefineCursor) /* 20 */ #endif #ifndef XDestroyWindow -#define XDestroyWindow(d, w) \ - (tkIntXlibStubsPtr->xDestroyWindow)(d, w) /* 21 */ +#define XDestroyWindow \ + (tkIntXlibStubsPtr->xDestroyWindow) /* 21 */ #endif #ifndef XDrawArc -#define XDrawArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xDrawArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4) /* 22 */ +#define XDrawArc \ + (tkIntXlibStubsPtr->xDrawArc) /* 22 */ #endif #ifndef XDrawLines -#define XDrawLines(d, dr, g, x, i1, i2) \ - (tkIntXlibStubsPtr->xDrawLines)(d, dr, g, x, i1, i2) /* 23 */ +#define XDrawLines \ + (tkIntXlibStubsPtr->xDrawLines) /* 23 */ #endif #ifndef XDrawRectangle -#define XDrawRectangle(d, dr, g, i1, i2, ui1, ui2) \ - (tkIntXlibStubsPtr->xDrawRectangle)(d, dr, g, i1, i2, ui1, ui2) /* 24 */ +#define XDrawRectangle \ + (tkIntXlibStubsPtr->xDrawRectangle) /* 24 */ #endif #ifndef XFillArc -#define XFillArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) \ - (tkIntXlibStubsPtr->xFillArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4) /* 25 */ +#define XFillArc \ + (tkIntXlibStubsPtr->xFillArc) /* 25 */ #endif #ifndef XFillPolygon -#define XFillPolygon(d, dr, g, x, i1, i2, i3) \ - (tkIntXlibStubsPtr->xFillPolygon)(d, dr, g, x, i1, i2, i3) /* 26 */ +#define XFillPolygon \ + (tkIntXlibStubsPtr->xFillPolygon) /* 26 */ #endif #ifndef XFillRectangles -#define XFillRectangles(d, dr, g, x, i) \ - (tkIntXlibStubsPtr->xFillRectangles)(d, dr, g, x, i) /* 27 */ +#define XFillRectangles \ + (tkIntXlibStubsPtr->xFillRectangles) /* 27 */ #endif #ifndef XFreeColormap -#define XFreeColormap(d, c) \ - (tkIntXlibStubsPtr->xFreeColormap)(d, c) /* 28 */ +#define XFreeColormap \ + (tkIntXlibStubsPtr->xFreeColormap) /* 28 */ #endif #ifndef XFreeColors -#define XFreeColors(d, c, ulp, i, ul) \ - (tkIntXlibStubsPtr->xFreeColors)(d, c, ulp, i, ul) /* 29 */ +#define XFreeColors \ + (tkIntXlibStubsPtr->xFreeColors) /* 29 */ #endif #ifndef XFreeModifiermap -#define XFreeModifiermap(x) \ - (tkIntXlibStubsPtr->xFreeModifiermap)(x) /* 30 */ +#define XFreeModifiermap \ + (tkIntXlibStubsPtr->xFreeModifiermap) /* 30 */ #endif #ifndef XGetGeometry -#define XGetGeometry(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) \ - (tkIntXlibStubsPtr->xGetGeometry)(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) /* 31 */ +#define XGetGeometry \ + (tkIntXlibStubsPtr->xGetGeometry) /* 31 */ #endif #ifndef XGetWindowProperty -#define XGetWindowProperty(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) \ - (tkIntXlibStubsPtr->xGetWindowProperty)(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) /* 32 */ +#define XGetWindowProperty \ + (tkIntXlibStubsPtr->xGetWindowProperty) /* 32 */ #endif #ifndef XGrabKeyboard -#define XGrabKeyboard(d, w, b, i1, i2, t) \ - (tkIntXlibStubsPtr->xGrabKeyboard)(d, w, b, i1, i2, t) /* 33 */ +#define XGrabKeyboard \ + (tkIntXlibStubsPtr->xGrabKeyboard) /* 33 */ #endif #ifndef XGrabPointer -#define XGrabPointer(d, w1, b, ui, i1, i2, w2, c, t) \ - (tkIntXlibStubsPtr->xGrabPointer)(d, w1, b, ui, i1, i2, w2, c, t) /* 34 */ +#define XGrabPointer \ + (tkIntXlibStubsPtr->xGrabPointer) /* 34 */ #endif #ifndef XKeysymToKeycode -#define XKeysymToKeycode(d, k) \ - (tkIntXlibStubsPtr->xKeysymToKeycode)(d, k) /* 35 */ +#define XKeysymToKeycode \ + (tkIntXlibStubsPtr->xKeysymToKeycode) /* 35 */ #endif #ifndef XMapWindow -#define XMapWindow(d, w) \ - (tkIntXlibStubsPtr->xMapWindow)(d, w) /* 36 */ +#define XMapWindow \ + (tkIntXlibStubsPtr->xMapWindow) /* 36 */ #endif #ifndef XMoveResizeWindow -#define XMoveResizeWindow(d, w, i1, i2, ui1, ui2) \ - (tkIntXlibStubsPtr->xMoveResizeWindow)(d, w, i1, i2, ui1, ui2) /* 37 */ +#define XMoveResizeWindow \ + (tkIntXlibStubsPtr->xMoveResizeWindow) /* 37 */ #endif #ifndef XMoveWindow -#define XMoveWindow(d, w, i1, i2) \ - (tkIntXlibStubsPtr->xMoveWindow)(d, w, i1, i2) /* 38 */ +#define XMoveWindow \ + (tkIntXlibStubsPtr->xMoveWindow) /* 38 */ #endif #ifndef XQueryPointer -#define XQueryPointer(d, w1, w2, w3, i1, i2, i3, i4, ui) \ - (tkIntXlibStubsPtr->xQueryPointer)(d, w1, w2, w3, i1, i2, i3, i4, ui) /* 39 */ +#define XQueryPointer \ + (tkIntXlibStubsPtr->xQueryPointer) /* 39 */ #endif #ifndef XRaiseWindow -#define XRaiseWindow(d, w) \ - (tkIntXlibStubsPtr->xRaiseWindow)(d, w) /* 40 */ +#define XRaiseWindow \ + (tkIntXlibStubsPtr->xRaiseWindow) /* 40 */ #endif #ifndef XRefreshKeyboardMapping -#define XRefreshKeyboardMapping(x) \ - (tkIntXlibStubsPtr->xRefreshKeyboardMapping)(x) /* 41 */ +#define XRefreshKeyboardMapping \ + (tkIntXlibStubsPtr->xRefreshKeyboardMapping) /* 41 */ #endif #ifndef XResizeWindow -#define XResizeWindow(d, w, ui1, ui2) \ - (tkIntXlibStubsPtr->xResizeWindow)(d, w, ui1, ui2) /* 42 */ +#define XResizeWindow \ + (tkIntXlibStubsPtr->xResizeWindow) /* 42 */ #endif #ifndef XSelectInput -#define XSelectInput(d, w, l) \ - (tkIntXlibStubsPtr->xSelectInput)(d, w, l) /* 43 */ +#define XSelectInput \ + (tkIntXlibStubsPtr->xSelectInput) /* 43 */ #endif #ifndef XSendEvent -#define XSendEvent(d, w, b, l, x) \ - (tkIntXlibStubsPtr->xSendEvent)(d, w, b, l, x) /* 44 */ +#define XSendEvent \ + (tkIntXlibStubsPtr->xSendEvent) /* 44 */ #endif #ifndef XSetIconName -#define XSetIconName(d, w, c) \ - (tkIntXlibStubsPtr->xSetIconName)(d, w, c) /* 45 */ +#define XSetIconName \ + (tkIntXlibStubsPtr->xSetIconName) /* 45 */ #endif #ifndef XSetInputFocus -#define XSetInputFocus(d, w, i, t) \ - (tkIntXlibStubsPtr->xSetInputFocus)(d, w, i, t) /* 46 */ +#define XSetInputFocus \ + (tkIntXlibStubsPtr->xSetInputFocus) /* 46 */ #endif #ifndef XSetSelectionOwner -#define XSetSelectionOwner(d, a, w, t) \ - (tkIntXlibStubsPtr->xSetSelectionOwner)(d, a, w, t) /* 47 */ +#define XSetSelectionOwner \ + (tkIntXlibStubsPtr->xSetSelectionOwner) /* 47 */ #endif #ifndef XSetWindowBackground -#define XSetWindowBackground(d, w, ul) \ - (tkIntXlibStubsPtr->xSetWindowBackground)(d, w, ul) /* 48 */ +#define XSetWindowBackground \ + (tkIntXlibStubsPtr->xSetWindowBackground) /* 48 */ #endif #ifndef XSetWindowBackgroundPixmap -#define XSetWindowBackgroundPixmap(d, w, p) \ - (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap)(d, w, p) /* 49 */ +#define XSetWindowBackgroundPixmap \ + (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap) /* 49 */ #endif #ifndef XSetWindowBorder -#define XSetWindowBorder(d, w, ul) \ - (tkIntXlibStubsPtr->xSetWindowBorder)(d, w, ul) /* 50 */ +#define XSetWindowBorder \ + (tkIntXlibStubsPtr->xSetWindowBorder) /* 50 */ #endif #ifndef XSetWindowBorderPixmap -#define XSetWindowBorderPixmap(d, w, p) \ - (tkIntXlibStubsPtr->xSetWindowBorderPixmap)(d, w, p) /* 51 */ +#define XSetWindowBorderPixmap \ + (tkIntXlibStubsPtr->xSetWindowBorderPixmap) /* 51 */ #endif #ifndef XSetWindowBorderWidth -#define XSetWindowBorderWidth(d, w, ui) \ - (tkIntXlibStubsPtr->xSetWindowBorderWidth)(d, w, ui) /* 52 */ +#define XSetWindowBorderWidth \ + (tkIntXlibStubsPtr->xSetWindowBorderWidth) /* 52 */ #endif #ifndef XSetWindowColormap -#define XSetWindowColormap(d, w, c) \ - (tkIntXlibStubsPtr->xSetWindowColormap)(d, w, c) /* 53 */ +#define XSetWindowColormap \ + (tkIntXlibStubsPtr->xSetWindowColormap) /* 53 */ #endif #ifndef XUngrabKeyboard -#define XUngrabKeyboard(d, t) \ - (tkIntXlibStubsPtr->xUngrabKeyboard)(d, t) /* 54 */ +#define XUngrabKeyboard \ + (tkIntXlibStubsPtr->xUngrabKeyboard) /* 54 */ #endif #ifndef XUngrabPointer -#define XUngrabPointer(d, t) \ - (tkIntXlibStubsPtr->xUngrabPointer)(d, t) /* 55 */ +#define XUngrabPointer \ + (tkIntXlibStubsPtr->xUngrabPointer) /* 55 */ #endif #ifndef XUnmapWindow -#define XUnmapWindow(d, w) \ - (tkIntXlibStubsPtr->xUnmapWindow)(d, w) /* 56 */ +#define XUnmapWindow \ + (tkIntXlibStubsPtr->xUnmapWindow) /* 56 */ #endif #ifndef TkPutImage -#define TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) \ - (tkIntXlibStubsPtr->tkPutImage)(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) /* 57 */ +#define TkPutImage \ + (tkIntXlibStubsPtr->tkPutImage) /* 57 */ +#endif +#ifndef XParseColor +#define XParseColor \ + (tkIntXlibStubsPtr->xParseColor) /* 58 */ +#endif +#ifndef XCreateGC +#define XCreateGC \ + (tkIntXlibStubsPtr->xCreateGC) /* 59 */ +#endif +#ifndef XFreeGC +#define XFreeGC \ + (tkIntXlibStubsPtr->xFreeGC) /* 60 */ +#endif +#ifndef XInternAtom +#define XInternAtom \ + (tkIntXlibStubsPtr->xInternAtom) /* 61 */ +#endif +#ifndef XSetBackground +#define XSetBackground \ + (tkIntXlibStubsPtr->xSetBackground) /* 62 */ +#endif +#ifndef XSetForeground +#define XSetForeground \ + (tkIntXlibStubsPtr->xSetForeground) /* 63 */ +#endif +#ifndef XSetClipMask +#define XSetClipMask \ + (tkIntXlibStubsPtr->xSetClipMask) /* 64 */ +#endif +#ifndef XSetClipOrigin +#define XSetClipOrigin \ + (tkIntXlibStubsPtr->xSetClipOrigin) /* 65 */ +#endif +#ifndef XSetTSOrigin +#define XSetTSOrigin \ + (tkIntXlibStubsPtr->xSetTSOrigin) /* 66 */ +#endif +#ifndef XChangeGC +#define XChangeGC \ + (tkIntXlibStubsPtr->xChangeGC) /* 67 */ +#endif +#ifndef XSetFont +#define XSetFont \ + (tkIntXlibStubsPtr->xSetFont) /* 68 */ +#endif +#ifndef XSetArcMode +#define XSetArcMode \ + (tkIntXlibStubsPtr->xSetArcMode) /* 69 */ +#endif +#ifndef XSetStipple +#define XSetStipple \ + (tkIntXlibStubsPtr->xSetStipple) /* 70 */ +#endif +#ifndef XSetFillRule +#define XSetFillRule \ + (tkIntXlibStubsPtr->xSetFillRule) /* 71 */ +#endif +#ifndef XSetFillStyle +#define XSetFillStyle \ + (tkIntXlibStubsPtr->xSetFillStyle) /* 72 */ +#endif +#ifndef XSetFunction +#define XSetFunction \ + (tkIntXlibStubsPtr->xSetFunction) /* 73 */ +#endif +#ifndef XSetLineAttributes +#define XSetLineAttributes \ + (tkIntXlibStubsPtr->xSetLineAttributes) /* 74 */ +#endif +#ifndef _XInitImageFuncPtrs +#define _XInitImageFuncPtrs \ + (tkIntXlibStubsPtr->_XInitImageFuncPtrs) /* 75 */ +#endif +#ifndef XCreateIC +#define XCreateIC \ + (tkIntXlibStubsPtr->xCreateIC) /* 76 */ +#endif +#ifndef XGetVisualInfo +#define XGetVisualInfo \ + (tkIntXlibStubsPtr->xGetVisualInfo) /* 77 */ +#endif +#ifndef XSetWMClientMachine +#define XSetWMClientMachine \ + (tkIntXlibStubsPtr->xSetWMClientMachine) /* 78 */ +#endif +#ifndef XStringListToTextProperty +#define XStringListToTextProperty \ + (tkIntXlibStubsPtr->xStringListToTextProperty) /* 79 */ #endif #endif /* MAC_TCL */ diff --git a/generic/tkIntXlibStubs.c b/generic/tkIntXlibStubs.c deleted file mode 100644 index 01906f1..0000000 --- a/generic/tkIntXlibStubs.c +++ /dev/null @@ -1,1596 +0,0 @@ -/* - * tkIntPlatStubs.c -- - * - * This file contains the wrapper functions for the platform dependent - * unsupported Tk API. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * All rights reserved. - * - * RCS: @(#) $Id: tkIntXlibStubs.c,v 1.4 1999/03/12 03:17:48 stanton Exp $ - */ - -#include "tkInt.h" -#include <X11/Xlib.h> - -/* - * WARNING: This file is automatically generated by the tools/genStubs.tcl - * script. Any modifications to the function declarations below should be made - * in the generic/tkInt.decls script. - */ - -/* !BEGIN!: Do not edit below this line. */ - -/* - * Exported stub functions: - */ - -#ifdef __WIN32__ -/* Slot 0 is reserved */ -/* Slot 1 */ -XModifierKeymap* -XGetModifierMapping(d) - Display* d; -{ - return (tkIntXlibStubsPtr->xGetModifierMapping)(d); -} - -/* Slot 2 */ -XImage * -XCreateImage(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) - Display* d; - Visual* v; - unsigned int ui1; - int i1; - int i2; - char* cp; - unsigned int ui2; - unsigned int ui3; - int i3; - int i4; -{ - return (tkIntXlibStubsPtr->xCreateImage)(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4); -} - -/* Slot 3 */ -XImage * -XGetImage(d, dr, i1, i2, ui1, ui2, ul, i3) - Display* d; - Drawable dr; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - unsigned long ul; - int i3; -{ - return (tkIntXlibStubsPtr->xGetImage)(d, dr, i1, i2, ui1, ui2, ul, i3); -} - -/* Slot 4 */ -char * -XGetAtomName(d, a) - Display* d; - Atom a; -{ - return (tkIntXlibStubsPtr->xGetAtomName)(d, a); -} - -/* Slot 5 */ -char * -XKeysymToString(k) - KeySym k; -{ - return (tkIntXlibStubsPtr->xKeysymToString)(k); -} - -/* Slot 6 */ -Colormap -XCreateColormap(d, w, v, i) - Display* d; - Window w; - Visual* v; - int i; -{ - return (tkIntXlibStubsPtr->xCreateColormap)(d, w, v, i); -} - -/* Slot 7 */ -Cursor -XCreatePixmapCursor(d, p1, p2, x1, x2, ui1, ui2) - Display* d; - Pixmap p1; - Pixmap p2; - XColor* x1; - XColor* x2; - unsigned int ui1; - unsigned int ui2; -{ - return (tkIntXlibStubsPtr->xCreatePixmapCursor)(d, p1, p2, x1, x2, ui1, ui2); -} - -/* Slot 8 */ -Cursor -XCreateGlyphCursor(d, f1, f2, ui1, ui2, x1, x2) - Display* d; - Font f1; - Font f2; - unsigned int ui1; - unsigned int ui2; - XColor* x1; - XColor* x2; -{ - return (tkIntXlibStubsPtr->xCreateGlyphCursor)(d, f1, f2, ui1, ui2, x1, x2); -} - -/* Slot 9 */ -GContext -XGContextFromGC(g) - GC g; -{ - return (tkIntXlibStubsPtr->xGContextFromGC)(g); -} - -/* Slot 10 */ -XHostAddress * -XListHosts(d, i, b) - Display* d; - int* i; - Bool* b; -{ - return (tkIntXlibStubsPtr->xListHosts)(d, i, b); -} - -/* Slot 11 */ -KeySym -XKeycodeToKeysym(d, k, i) - Display* d; - unsigned int k; - int i; -{ - return (tkIntXlibStubsPtr->xKeycodeToKeysym)(d, k, i); -} - -/* Slot 12 */ -KeySym -XStringToKeysym(c) - _Xconst char* c; -{ - return (tkIntXlibStubsPtr->xStringToKeysym)(c); -} - -/* Slot 13 */ -Window -XRootWindow(d, i) - Display* d; - int i; -{ - return (tkIntXlibStubsPtr->xRootWindow)(d, i); -} - -/* Slot 14 */ -XErrorHandler -XSetErrorHandler(x) - XErrorHandler x; -{ - return (tkIntXlibStubsPtr->xSetErrorHandler)(x); -} - -/* Slot 15 */ -Status -XIconifyWindow(d, w, i) - Display* d; - Window w; - int i; -{ - return (tkIntXlibStubsPtr->xIconifyWindow)(d, w, i); -} - -/* Slot 16 */ -Status -XWithdrawWindow(d, w, i) - Display* d; - Window w; - int i; -{ - return (tkIntXlibStubsPtr->xWithdrawWindow)(d, w, i); -} - -/* Slot 17 */ -Status -XGetWMColormapWindows(d, w, wpp, ip) - Display* d; - Window w; - Window** wpp; - int* ip; -{ - return (tkIntXlibStubsPtr->xGetWMColormapWindows)(d, w, wpp, ip); -} - -/* Slot 18 */ -Status -XAllocColor(d, c, xp) - Display* d; - Colormap c; - XColor* xp; -{ - return (tkIntXlibStubsPtr->xAllocColor)(d, c, xp); -} - -/* Slot 19 */ -void -XBell(d, i) - Display* d; - int i; -{ - (tkIntXlibStubsPtr->xBell)(d, i); -} - -/* Slot 20 */ -void -XChangeProperty(d, w, a1, a2, i1, i2, c, i3) - Display* d; - Window w; - Atom a1; - Atom a2; - int i1; - int i2; - _Xconst unsigned char* c; - int i3; -{ - (tkIntXlibStubsPtr->xChangeProperty)(d, w, a1, a2, i1, i2, c, i3); -} - -/* Slot 21 */ -void -XChangeWindowAttributes(d, w, ul, x) - Display* d; - Window w; - unsigned long ul; - XSetWindowAttributes* x; -{ - (tkIntXlibStubsPtr->xChangeWindowAttributes)(d, w, ul, x); -} - -/* Slot 22 */ -void -XClearWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xClearWindow)(d, w); -} - -/* Slot 23 */ -void -XConfigureWindow(d, w, i, x) - Display* d; - Window w; - unsigned int i; - XWindowChanges* x; -{ - (tkIntXlibStubsPtr->xConfigureWindow)(d, w, i, x); -} - -/* Slot 24 */ -void -XCopyArea(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr1; - Drawable dr2; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xCopyArea)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 25 */ -void -XCopyPlane(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) - Display* d; - Drawable dr1; - Drawable dr2; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xCopyPlane)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul); -} - -/* Slot 26 */ -Pixmap -XCreateBitmapFromData(display, d, data, width, height) - Display* display; - Drawable d; - _Xconst char* data; - unsigned int width; - unsigned int height; -{ - return (tkIntXlibStubsPtr->xCreateBitmapFromData)(display, d, data, width, height); -} - -/* Slot 27 */ -void -XDefineCursor(d, w, c) - Display* d; - Window w; - Cursor c; -{ - (tkIntXlibStubsPtr->xDefineCursor)(d, w, c); -} - -/* Slot 28 */ -void -XDeleteProperty(d, w, a) - Display* d; - Window w; - Atom a; -{ - (tkIntXlibStubsPtr->xDeleteProperty)(d, w, a); -} - -/* Slot 29 */ -void -XDestroyWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xDestroyWindow)(d, w); -} - -/* Slot 30 */ -void -XDrawArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xDrawArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 31 */ -void -XDrawLines(d, dr, g, x, i1, i2) - Display* d; - Drawable dr; - GC g; - XPoint* x; - int i1; - int i2; -{ - (tkIntXlibStubsPtr->xDrawLines)(d, dr, g, x, i1, i2); -} - -/* Slot 32 */ -void -XDrawRectangle(d, dr, g, i1, i2, ui1, ui2) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xDrawRectangle)(d, dr, g, i1, i2, ui1, ui2); -} - -/* Slot 33 */ -void -XFillArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xFillArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 34 */ -void -XFillPolygon(d, dr, g, x, i1, i2, i3) - Display* d; - Drawable dr; - GC g; - XPoint* x; - int i1; - int i2; - int i3; -{ - (tkIntXlibStubsPtr->xFillPolygon)(d, dr, g, x, i1, i2, i3); -} - -/* Slot 35 */ -void -XFillRectangles(d, dr, g, x, i) - Display* d; - Drawable dr; - GC g; - XRectangle* x; - int i; -{ - (tkIntXlibStubsPtr->xFillRectangles)(d, dr, g, x, i); -} - -/* Slot 36 */ -void -XForceScreenSaver(d, i) - Display* d; - int i; -{ - (tkIntXlibStubsPtr->xForceScreenSaver)(d, i); -} - -/* Slot 37 */ -void -XFreeColormap(d, c) - Display* d; - Colormap c; -{ - (tkIntXlibStubsPtr->xFreeColormap)(d, c); -} - -/* Slot 38 */ -void -XFreeColors(d, c, ulp, i, ul) - Display* d; - Colormap c; - unsigned long* ulp; - int i; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xFreeColors)(d, c, ulp, i, ul); -} - -/* Slot 39 */ -void -XFreeCursor(d, c) - Display* d; - Cursor c; -{ - (tkIntXlibStubsPtr->xFreeCursor)(d, c); -} - -/* Slot 40 */ -void -XFreeModifiermap(x) - XModifierKeymap* x; -{ - (tkIntXlibStubsPtr->xFreeModifiermap)(x); -} - -/* Slot 41 */ -Status -XGetGeometry(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) - Display* d; - Drawable dr; - Window* w; - int* i1; - int* i2; - unsigned int* ui1; - unsigned int* ui2; - unsigned int* ui3; - unsigned int* ui4; -{ - return (tkIntXlibStubsPtr->xGetGeometry)(d, dr, w, i1, i2, ui1, ui2, ui3, ui4); -} - -/* Slot 42 */ -void -XGetInputFocus(d, w, i) - Display* d; - Window* w; - int* i; -{ - (tkIntXlibStubsPtr->xGetInputFocus)(d, w, i); -} - -/* Slot 43 */ -int -XGetWindowProperty(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) - Display* d; - Window w; - Atom a1; - long l1; - long l2; - Bool b; - Atom a2; - Atom* ap; - int* ip; - unsigned long* ulp1; - unsigned long* ulp2; - unsigned char** cpp; -{ - return (tkIntXlibStubsPtr->xGetWindowProperty)(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp); -} - -/* Slot 44 */ -Status -XGetWindowAttributes(d, w, x) - Display* d; - Window w; - XWindowAttributes* x; -{ - return (tkIntXlibStubsPtr->xGetWindowAttributes)(d, w, x); -} - -/* Slot 45 */ -int -XGrabKeyboard(d, w, b, i1, i2, t) - Display* d; - Window w; - Bool b; - int i1; - int i2; - Time t; -{ - return (tkIntXlibStubsPtr->xGrabKeyboard)(d, w, b, i1, i2, t); -} - -/* Slot 46 */ -int -XGrabPointer(d, w1, b, ui, i1, i2, w2, c, t) - Display* d; - Window w1; - Bool b; - unsigned int ui; - int i1; - int i2; - Window w2; - Cursor c; - Time t; -{ - return (tkIntXlibStubsPtr->xGrabPointer)(d, w1, b, ui, i1, i2, w2, c, t); -} - -/* Slot 47 */ -KeyCode -XKeysymToKeycode(d, k) - Display* d; - KeySym k; -{ - return (tkIntXlibStubsPtr->xKeysymToKeycode)(d, k); -} - -/* Slot 48 */ -Status -XLookupColor(d, c1, c2, x1, x2) - Display* d; - Colormap c1; - _Xconst char* c2; - XColor* x1; - XColor* x2; -{ - return (tkIntXlibStubsPtr->xLookupColor)(d, c1, c2, x1, x2); -} - -/* Slot 49 */ -void -XMapWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xMapWindow)(d, w); -} - -/* Slot 50 */ -void -XMoveResizeWindow(d, w, i1, i2, ui1, ui2) - Display* d; - Window w; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xMoveResizeWindow)(d, w, i1, i2, ui1, ui2); -} - -/* Slot 51 */ -void -XMoveWindow(d, w, i1, i2) - Display* d; - Window w; - int i1; - int i2; -{ - (tkIntXlibStubsPtr->xMoveWindow)(d, w, i1, i2); -} - -/* Slot 52 */ -void -XNextEvent(d, x) - Display* d; - XEvent* x; -{ - (tkIntXlibStubsPtr->xNextEvent)(d, x); -} - -/* Slot 53 */ -void -XPutBackEvent(d, x) - Display* d; - XEvent* x; -{ - (tkIntXlibStubsPtr->xPutBackEvent)(d, x); -} - -/* Slot 54 */ -void -XQueryColors(d, c, x, i) - Display* d; - Colormap c; - XColor* x; - int i; -{ - (tkIntXlibStubsPtr->xQueryColors)(d, c, x, i); -} - -/* Slot 55 */ -Bool -XQueryPointer(d, w1, w2, w3, i1, i2, i3, i4, ui) - Display* d; - Window w1; - Window* w2; - Window* w3; - int* i1; - int* i2; - int* i3; - int* i4; - unsigned int* ui; -{ - return (tkIntXlibStubsPtr->xQueryPointer)(d, w1, w2, w3, i1, i2, i3, i4, ui); -} - -/* Slot 56 */ -Status -XQueryTree(d, w1, w2, w3, w4, ui) - Display* d; - Window w1; - Window* w2; - Window* w3; - Window** w4; - unsigned int* ui; -{ - return (tkIntXlibStubsPtr->xQueryTree)(d, w1, w2, w3, w4, ui); -} - -/* Slot 57 */ -void -XRaiseWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xRaiseWindow)(d, w); -} - -/* Slot 58 */ -void -XRefreshKeyboardMapping(x) - XMappingEvent* x; -{ - (tkIntXlibStubsPtr->xRefreshKeyboardMapping)(x); -} - -/* Slot 59 */ -void -XResizeWindow(d, w, ui1, ui2) - Display* d; - Window w; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xResizeWindow)(d, w, ui1, ui2); -} - -/* Slot 60 */ -void -XSelectInput(d, w, l) - Display* d; - Window w; - long l; -{ - (tkIntXlibStubsPtr->xSelectInput)(d, w, l); -} - -/* Slot 61 */ -Status -XSendEvent(d, w, b, l, x) - Display* d; - Window w; - Bool b; - long l; - XEvent* x; -{ - return (tkIntXlibStubsPtr->xSendEvent)(d, w, b, l, x); -} - -/* Slot 62 */ -void -XSetCommand(d, w, c, i) - Display* d; - Window w; - char** c; - int i; -{ - (tkIntXlibStubsPtr->xSetCommand)(d, w, c, i); -} - -/* Slot 63 */ -void -XSetIconName(d, w, c) - Display* d; - Window w; - _Xconst char* c; -{ - (tkIntXlibStubsPtr->xSetIconName)(d, w, c); -} - -/* Slot 64 */ -void -XSetInputFocus(d, w, i, t) - Display* d; - Window w; - int i; - Time t; -{ - (tkIntXlibStubsPtr->xSetInputFocus)(d, w, i, t); -} - -/* Slot 65 */ -void -XSetSelectionOwner(d, a, w, t) - Display* d; - Atom a; - Window w; - Time t; -{ - (tkIntXlibStubsPtr->xSetSelectionOwner)(d, a, w, t); -} - -/* Slot 66 */ -void -XSetWindowBackground(d, w, ul) - Display* d; - Window w; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xSetWindowBackground)(d, w, ul); -} - -/* Slot 67 */ -void -XSetWindowBackgroundPixmap(d, w, p) - Display* d; - Window w; - Pixmap p; -{ - (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap)(d, w, p); -} - -/* Slot 68 */ -void -XSetWindowBorder(d, w, ul) - Display* d; - Window w; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xSetWindowBorder)(d, w, ul); -} - -/* Slot 69 */ -void -XSetWindowBorderPixmap(d, w, p) - Display* d; - Window w; - Pixmap p; -{ - (tkIntXlibStubsPtr->xSetWindowBorderPixmap)(d, w, p); -} - -/* Slot 70 */ -void -XSetWindowBorderWidth(d, w, ui) - Display* d; - Window w; - unsigned int ui; -{ - (tkIntXlibStubsPtr->xSetWindowBorderWidth)(d, w, ui); -} - -/* Slot 71 */ -void -XSetWindowColormap(d, w, c) - Display* d; - Window w; - Colormap c; -{ - (tkIntXlibStubsPtr->xSetWindowColormap)(d, w, c); -} - -/* Slot 72 */ -Bool -XTranslateCoordinates(d, w1, w2, i1, i2, i3, i4, w3) - Display* d; - Window w1; - Window w2; - int i1; - int i2; - int* i3; - int* i4; - Window* w3; -{ - return (tkIntXlibStubsPtr->xTranslateCoordinates)(d, w1, w2, i1, i2, i3, i4, w3); -} - -/* Slot 73 */ -void -XUngrabKeyboard(d, t) - Display* d; - Time t; -{ - (tkIntXlibStubsPtr->xUngrabKeyboard)(d, t); -} - -/* Slot 74 */ -void -XUngrabPointer(d, t) - Display* d; - Time t; -{ - (tkIntXlibStubsPtr->xUngrabPointer)(d, t); -} - -/* Slot 75 */ -void -XUnmapWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xUnmapWindow)(d, w); -} - -/* Slot 76 */ -void -XWindowEvent(d, w, l, x) - Display* d; - Window w; - long l; - XEvent* x; -{ - (tkIntXlibStubsPtr->xWindowEvent)(d, w, l, x); -} - -/* Slot 77 */ -void -XDestroyIC(x) - XIC x; -{ - (tkIntXlibStubsPtr->xDestroyIC)(x); -} - -/* Slot 78 */ -Bool -XFilterEvent(x, w) - XEvent* x; - Window w; -{ - return (tkIntXlibStubsPtr->xFilterEvent)(x, w); -} - -/* Slot 79 */ -int -XmbLookupString(xi, xk, c, i, k, s) - XIC xi; - XKeyPressedEvent* xk; - char* c; - int i; - KeySym* k; - Status* s; -{ - return (tkIntXlibStubsPtr->xmbLookupString)(xi, xk, c, i, k, s); -} - -/* Slot 80 */ -void -TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) - unsigned long * colors; - int ncolors; - Display* display; - Drawable d; - GC gc; - XImage* image; - int src_x; - int src_y; - int dest_x; - int dest_y; - unsigned int width; - unsigned int height; -{ - (tkIntXlibStubsPtr->tkPutImage)(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height); -} - -#endif /* __WIN32__ */ -#ifdef MAC_TCL -/* Slot 0 is reserved */ -/* Slot 1 */ -XModifierKeymap* -XGetModifierMapping(d) - Display* d; -{ - return (tkIntXlibStubsPtr->xGetModifierMapping)(d); -} - -/* Slot 2 */ -XImage * -XCreateImage(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4) - Display* d; - Visual* v; - unsigned int ui1; - int i1; - int i2; - char* cp; - unsigned int ui2; - unsigned int ui3; - int i3; - int i4; -{ - return (tkIntXlibStubsPtr->xCreateImage)(d, v, ui1, i1, i2, cp, ui2, ui3, i3, i4); -} - -/* Slot 3 */ -XImage * -XGetImage(d, dr, i1, i2, ui1, ui2, ul, i3) - Display* d; - Drawable dr; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - unsigned long ul; - int i3; -{ - return (tkIntXlibStubsPtr->xGetImage)(d, dr, i1, i2, ui1, ui2, ul, i3); -} - -/* Slot 4 */ -char * -XGetAtomName(d, a) - Display* d; - Atom a; -{ - return (tkIntXlibStubsPtr->xGetAtomName)(d, a); -} - -/* Slot 5 */ -char * -XKeysymToString(k) - KeySym k; -{ - return (tkIntXlibStubsPtr->xKeysymToString)(k); -} - -/* Slot 6 */ -Colormap -XCreateColormap(d, w, v, i) - Display* d; - Window w; - Visual* v; - int i; -{ - return (tkIntXlibStubsPtr->xCreateColormap)(d, w, v, i); -} - -/* Slot 7 */ -GContext -XGContextFromGC(g) - GC g; -{ - return (tkIntXlibStubsPtr->xGContextFromGC)(g); -} - -/* Slot 8 */ -KeySym -XKeycodeToKeysym(d, k, i) - Display* d; - KeyCode k; - int i; -{ - return (tkIntXlibStubsPtr->xKeycodeToKeysym)(d, k, i); -} - -/* Slot 9 */ -KeySym -XStringToKeysym(c) - _Xconst char* c; -{ - return (tkIntXlibStubsPtr->xStringToKeysym)(c); -} - -/* Slot 10 */ -Window -XRootWindow(d, i) - Display* d; - int i; -{ - return (tkIntXlibStubsPtr->xRootWindow)(d, i); -} - -/* Slot 11 */ -XErrorHandler -XSetErrorHandler(x) - XErrorHandler x; -{ - return (tkIntXlibStubsPtr->xSetErrorHandler)(x); -} - -/* Slot 12 */ -Status -XAllocColor(d, c, xp) - Display* d; - Colormap c; - XColor* xp; -{ - return (tkIntXlibStubsPtr->xAllocColor)(d, c, xp); -} - -/* Slot 13 */ -void -XBell(d, i) - Display* d; - int i; -{ - (tkIntXlibStubsPtr->xBell)(d, i); -} - -/* Slot 14 */ -void -XChangeProperty(d, w, a, a, i1, i2, c, i3) - Display* d; - Window w; - Atom a; - Atom a; - int i1; - int i2; - _Xconst unsigned char* c; - int i3; -{ - (tkIntXlibStubsPtr->xChangeProperty)(d, w, a, a, i1, i2, c, i3); -} - -/* Slot 15 */ -void -XChangeWindowAttributes(d, w, ul, x) - Display* d; - Window w; - unsigned long ul; - XSetWindowAttributes* x; -{ - (tkIntXlibStubsPtr->xChangeWindowAttributes)(d, w, ul, x); -} - -/* Slot 16 */ -void -XConfigureWindow(d, w, i, x) - Display* d; - Window w; - unsigned int i; - XWindowChanges* x; -{ - (tkIntXlibStubsPtr->xConfigureWindow)(d, w, i, x); -} - -/* Slot 17 */ -void -XCopyArea(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr1; - Drawable dr2; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xCopyArea)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 18 */ -void -XCopyPlane(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul) - Display* d; - Drawable dr1; - Drawable dr2; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xCopyPlane)(d, dr1, dr2, g, i1, i2, ui1, ui2, i3, i4, ul); -} - -/* Slot 19 */ -Pixmap -XCreateBitmapFromData(display, d, data, width, height) - Display* display; - Drawable d; - _Xconst char* data; - unsigned int width; - unsigned int height; -{ - return (tkIntXlibStubsPtr->xCreateBitmapFromData)(display, d, data, width, height); -} - -/* Slot 20 */ -void -XDefineCursor(d, w, c) - Display* d; - Window w; - Cursor c; -{ - (tkIntXlibStubsPtr->xDefineCursor)(d, w, c); -} - -/* Slot 21 */ -void -XDestroyWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xDestroyWindow)(d, w); -} - -/* Slot 22 */ -void -XDrawArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xDrawArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 23 */ -void -XDrawLines(d, dr, g, x, i1, i2) - Display* d; - Drawable dr; - GC g; - XPoint* x; - int i1; - int i2; -{ - (tkIntXlibStubsPtr->xDrawLines)(d, dr, g, x, i1, i2); -} - -/* Slot 24 */ -void -XDrawRectangle(d, dr, g, i1, i2, ui1, ui2) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xDrawRectangle)(d, dr, g, i1, i2, ui1, ui2); -} - -/* Slot 25 */ -void -XFillArc(d, dr, g, i1, i2, ui1, ui2, i3, i4) - Display* d; - Drawable dr; - GC g; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; - int i3; - int i4; -{ - (tkIntXlibStubsPtr->xFillArc)(d, dr, g, i1, i2, ui1, ui2, i3, i4); -} - -/* Slot 26 */ -void -XFillPolygon(d, dr, g, x, i1, i2, i3) - Display* d; - Drawable dr; - GC g; - XPoint* x; - int i1; - int i2; - int i3; -{ - (tkIntXlibStubsPtr->xFillPolygon)(d, dr, g, x, i1, i2, i3); -} - -/* Slot 27 */ -void -XFillRectangles(d, dr, g, x, i) - Display* d; - Drawable dr; - GC g; - XRectangle* x; - int i; -{ - (tkIntXlibStubsPtr->xFillRectangles)(d, dr, g, x, i); -} - -/* Slot 28 */ -void -XFreeColormap(d, c) - Display* d; - Colormap c; -{ - (tkIntXlibStubsPtr->xFreeColormap)(d, c); -} - -/* Slot 29 */ -void -XFreeColors(d, c, ulp, i, ul) - Display* d; - Colormap c; - unsigned long* ulp; - int i; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xFreeColors)(d, c, ulp, i, ul); -} - -/* Slot 30 */ -void -XFreeModifiermap(x) - XModifierKeymap* x; -{ - (tkIntXlibStubsPtr->xFreeModifiermap)(x); -} - -/* Slot 31 */ -Status -XGetGeometry(d, dr, w, i1, i2, ui1, ui2, ui3, ui4) - Display* d; - Drawable dr; - Window* w; - int* i1; - int* i2; - unsigned int* ui1; - unsigned int* ui2; - unsigned int* ui3; - unsigned int* ui4; -{ - return (tkIntXlibStubsPtr->xGetGeometry)(d, dr, w, i1, i2, ui1, ui2, ui3, ui4); -} - -/* Slot 32 */ -int -XGetWindowProperty(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp) - Display* d; - Window w; - Atom a1; - long l1; - long l2; - Bool b; - Atom a2; - Atom* ap; - int* ip; - unsigned long* ulp1; - unsigned long* ulp2; - unsigned char** cpp; -{ - return (tkIntXlibStubsPtr->xGetWindowProperty)(d, w, a1, l1, l2, b, a2, ap, ip, ulp1, ulp2, cpp); -} - -/* Slot 33 */ -int -XGrabKeyboard(d, w, b, i1, i2, t) - Display* d; - Window w; - Bool b; - int i1; - int i2; - Time t; -{ - return (tkIntXlibStubsPtr->xGrabKeyboard)(d, w, b, i1, i2, t); -} - -/* Slot 34 */ -int -XGrabPointer(d, w1, b, ui, i1, i2, w2, c, t) - Display* d; - Window w1; - Bool b; - unsigned int ui; - int i1; - int i2; - Window w2; - Cursor c; - Time t; -{ - return (tkIntXlibStubsPtr->xGrabPointer)(d, w1, b, ui, i1, i2, w2, c, t); -} - -/* Slot 35 */ -KeyCode -XKeysymToKeycode(d, k) - Display* d; - KeySym k; -{ - return (tkIntXlibStubsPtr->xKeysymToKeycode)(d, k); -} - -/* Slot 36 */ -void -XMapWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xMapWindow)(d, w); -} - -/* Slot 37 */ -void -XMoveResizeWindow(d, w, i1, i2, ui1, ui2) - Display* d; - Window w; - int i1; - int i2; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xMoveResizeWindow)(d, w, i1, i2, ui1, ui2); -} - -/* Slot 38 */ -void -XMoveWindow(d, w, i1, i2) - Display* d; - Window w; - int i1; - int i2; -{ - (tkIntXlibStubsPtr->xMoveWindow)(d, w, i1, i2); -} - -/* Slot 39 */ -Bool -XQueryPointer(d, w1, w2, w3, i1, i2, i3, i4, ui) - Display* d; - Window w1; - Window* w2; - Window* w3; - int* i1; - int* i2; - int* i3; - int* i4; - unsigned int* ui; -{ - return (tkIntXlibStubsPtr->xQueryPointer)(d, w1, w2, w3, i1, i2, i3, i4, ui); -} - -/* Slot 40 */ -void -XRaiseWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xRaiseWindow)(d, w); -} - -/* Slot 41 */ -void -XRefreshKeyboardMapping(x) - XMappingEvent* x; -{ - (tkIntXlibStubsPtr->xRefreshKeyboardMapping)(x); -} - -/* Slot 42 */ -void -XResizeWindow(d, w, ui1, ui2) - Display* d; - Window w; - unsigned int ui1; - unsigned int ui2; -{ - (tkIntXlibStubsPtr->xResizeWindow)(d, w, ui1, ui2); -} - -/* Slot 43 */ -void -XSelectInput(d, w, l) - Display* d; - Window w; - long l; -{ - (tkIntXlibStubsPtr->xSelectInput)(d, w, l); -} - -/* Slot 44 */ -Status -XSendEvent(d, w, b, l, x) - Display* d; - Window w; - Bool b; - long l; - XEvent* x; -{ - return (tkIntXlibStubsPtr->xSendEvent)(d, w, b, l, x); -} - -/* Slot 45 */ -void -XSetIconName(d, w, c) - Display* d; - Window w; - _Xconst char* c; -{ - (tkIntXlibStubsPtr->xSetIconName)(d, w, c); -} - -/* Slot 46 */ -void -XSetInputFocus(d, w, i, t) - Display* d; - Window w; - int i; - Time t; -{ - (tkIntXlibStubsPtr->xSetInputFocus)(d, w, i, t); -} - -/* Slot 47 */ -void -XSetSelectionOwner(d, a, w, t) - Display* d; - Atom a; - Window w; - Time t; -{ - (tkIntXlibStubsPtr->xSetSelectionOwner)(d, a, w, t); -} - -/* Slot 48 */ -void -XSetWindowBackground(d, w, ul) - Display* d; - Window w; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xSetWindowBackground)(d, w, ul); -} - -/* Slot 49 */ -void -XSetWindowBackgroundPixmap(d, w, p) - Display* d; - Window w; - Pixmap p; -{ - (tkIntXlibStubsPtr->xSetWindowBackgroundPixmap)(d, w, p); -} - -/* Slot 50 */ -void -XSetWindowBorder(d, w, ul) - Display* d; - Window w; - unsigned long ul; -{ - (tkIntXlibStubsPtr->xSetWindowBorder)(d, w, ul); -} - -/* Slot 51 */ -void -XSetWindowBorderPixmap(d, w, p) - Display* d; - Window w; - Pixmap p; -{ - (tkIntXlibStubsPtr->xSetWindowBorderPixmap)(d, w, p); -} - -/* Slot 52 */ -void -XSetWindowBorderWidth(d, w, ui) - Display* d; - Window w; - unsigned int ui; -{ - (tkIntXlibStubsPtr->xSetWindowBorderWidth)(d, w, ui); -} - -/* Slot 53 */ -void -XSetWindowColormap(d, w, c) - Display* d; - Window w; - Colormap c; -{ - (tkIntXlibStubsPtr->xSetWindowColormap)(d, w, c); -} - -/* Slot 54 */ -void -XUngrabKeyboard(d, t) - Display* d; - Time t; -{ - (tkIntXlibStubsPtr->xUngrabKeyboard)(d, t); -} - -/* Slot 55 */ -void -XUngrabPointer(d, t) - Display* d; - Time t; -{ - (tkIntXlibStubsPtr->xUngrabPointer)(d, t); -} - -/* Slot 56 */ -void -XUnmapWindow(d, w) - Display* d; - Window w; -{ - (tkIntXlibStubsPtr->xUnmapWindow)(d, w); -} - -/* Slot 57 */ -void -TkPutImage(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height) - unsigned long * colors; - int ncolors; - Display* display; - Drawable d; - GC gc; - XImage* image; - int src_x; - int src_y; - int dest_x; - int dest_y; - unsigned int width; - unsigned int height; -{ - (tkIntXlibStubsPtr->tkPutImage)(colors, ncolors, display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height); -} - -#endif /* MAC_TCL */ - -/* !END!: Do not edit above this line. */ diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 34189c7..241c05b 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.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: tkListbox.c,v 1.2 1998/09/14 18:23:13 stanton Exp $ + * RCS: @(#) $Id: tkListbox.c,v 1.3 1999/04/16 01:51:19 stanton Exp $ */ #include "tkPort.h" @@ -24,7 +24,7 @@ */ typedef struct Element { - int textLength; /* # non-NULL characters in text. */ + int textLength; /* # non-NULL bytes in text string. */ int lBearing; /* Distance from first character's * origin to left edge of character. */ int pixelWidth; /* Total width of element in pixels (including @@ -428,7 +428,7 @@ Tk_ListboxCmd(clientData, interp, argc, argv) goto error; } - interp->result = Tk_PathName(listPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(listPtr->tkwin), TCL_STATIC); return TCL_OK; error: @@ -518,12 +518,14 @@ ListboxWidgetCmd(clientData, interp, argc, argv) if ((index >= listPtr->topIndex) && (index < listPtr->numElements) && (index < (listPtr->topIndex + listPtr->fullLines + listPtr->partialLine))) { + char buf[TCL_INTEGER_SPACE * 4]; + x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; y = ((index - listPtr->topIndex)*listPtr->lineHeight) + listPtr->inset + listPtr->selBorderWidth; Tk_GetFontMetrics(listPtr->tkfont, &fm); - sprintf(interp->result, "%d %d %d %d", x, y, elPtr->pixelWidth, - fm.linespace); + sprintf(buf, "%d %d %d %d", x, y, elPtr->pixelWidth, fm.linespace); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) && (length >= 2)) { @@ -550,7 +552,6 @@ ListboxWidgetCmd(clientData, interp, argc, argv) } else if ((c == 'c') && (strncmp(argv[1], "curselection", length) == 0) && (length >= 2)) { int i, count; - char index[20]; Element *elPtr; if (argc != 2) { @@ -563,6 +564,8 @@ ListboxWidgetCmd(clientData, interp, argc, argv) for (i = 0, elPtr = listPtr->firstPtr; elPtr != NULL; i++, elPtr = elPtr->nextPtr) { if (elPtr->selected) { + char index[TCL_INTEGER_SPACE]; + sprintf(index, "%d", i); Tcl_AppendElement(interp, index); count++; @@ -609,8 +612,10 @@ ListboxWidgetCmd(clientData, interp, argc, argv) if (GetListboxIndex(interp, listPtr, argv[2], 0, &first) != TCL_OK) { goto error; } - if ((argc == 4) && (GetListboxIndex(interp, listPtr, argv[3], - 0, &last) != TCL_OK)) { + last = first; + if ((argc == 4) + && (GetListboxIndex(interp, listPtr, argv[3], 0, + &last) != TCL_OK)) { goto error; } if (first >= listPtr->numElements) { @@ -627,7 +632,7 @@ ListboxWidgetCmd(clientData, interp, argc, argv) if (elPtr != NULL) { if (argc == 3) { if (first >= 0) { - interp->result = elPtr->text; + Tcl_SetResult(interp, elPtr->text, TCL_STATIC); } } else { for ( ; i <= last; i++, elPtr = elPtr->nextPtr) { @@ -638,6 +643,7 @@ ListboxWidgetCmd(clientData, interp, argc, argv) } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) && (length >= 3)) { int index; + char buf[TCL_INTEGER_SPACE]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -649,7 +655,8 @@ ListboxWidgetCmd(clientData, interp, argc, argv) != TCL_OK) { goto error; } - sprintf(interp->result, "%d", index); + sprintf(buf, "%d", index); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) && (length >= 3)) { int index; @@ -667,6 +674,7 @@ ListboxWidgetCmd(clientData, interp, argc, argv) InsertEls(listPtr, index, argc-3, argv+3); } else if ((c == 'n') && (strncmp(argv[1], "nearest", length) == 0)) { int index, y; + char buf[TCL_INTEGER_SPACE]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -677,7 +685,8 @@ ListboxWidgetCmd(clientData, interp, argc, argv) goto error; } index = NearestListboxElement(listPtr, y); - sprintf(interp->result, "%d", index); + sprintf(buf, "%d", index); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 's') && (length >= 2) && (strncmp(argv[1], "scan", length) == 0)) { int x, y; @@ -788,7 +797,7 @@ ListboxWidgetCmd(clientData, interp, argc, argv) goto error; } if ((first < 0) || (first >= listPtr->numElements)) { - interp->result = "0"; + Tcl_SetResult(interp, "0", TCL_STATIC); goto done; } for (elPtr = listPtr->firstPtr, i = 0; i < first; @@ -796,9 +805,9 @@ ListboxWidgetCmd(clientData, interp, argc, argv) /* Empty loop body. */ } if (elPtr->selected) { - interp->result = "1"; + Tcl_SetResult(interp, "1", TCL_STATIC); } else { - interp->result = "0"; + Tcl_SetResult(interp, "0", TCL_STATIC); } } else if ((c == 's') && (strncmp(argv[2], "set", length) == 0)) { ListboxSelect(listPtr, first, last, 1); @@ -810,12 +819,15 @@ ListboxWidgetCmd(clientData, interp, argc, argv) } } else if ((c == 's') && (length >= 2) && (strncmp(argv[1], "size", length) == 0)) { + char buf[TCL_INTEGER_SPACE]; + if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " size\"", (char *) NULL); goto error; } - sprintf(interp->result, "%d", listPtr->numElements); + sprintf(buf, "%d", listPtr->numElements); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { int index, count, type, windowWidth, windowUnits; int offset = 0; /* Initialized to stop gcc warnings. */ @@ -825,15 +837,18 @@ ListboxWidgetCmd(clientData, interp, argc, argv) - 2*(listPtr->inset + listPtr->selBorderWidth); if (argc == 2) { if (listPtr->maxWidth == 0) { - interp->result = "0 1"; + Tcl_SetResult(interp, "0 1", TCL_STATIC); } else { + char buf[TCL_DOUBLE_SPACE * 2]; + fraction = listPtr->xOffset/((double) listPtr->maxWidth); fraction2 = (listPtr->xOffset + windowWidth) /((double) listPtr->maxWidth); if (fraction2 > 1.0) { fraction2 = 1.0; } - sprintf(interp->result, "%g %g", fraction, fraction2); + sprintf(buf, "%g %g", fraction, fraction2); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if (argc == 3) { if (Tcl_GetInt(interp, argv[2], &index) != TCL_OK) { @@ -869,15 +884,18 @@ ListboxWidgetCmd(clientData, interp, argc, argv) if (argc == 2) { if (listPtr->numElements == 0) { - interp->result = "0 1"; + Tcl_SetResult(interp, "0 1", TCL_STATIC); } else { + char buf[TCL_DOUBLE_SPACE * 2]; + fraction = listPtr->topIndex/((double) listPtr->numElements); fraction2 = (listPtr->topIndex+listPtr->fullLines) /((double) listPtr->numElements); if (fraction2 > 1.0) { fraction2 = 1.0; } - sprintf(interp->result, "%g %g", fraction, fraction2); + sprintf(buf, "%g %g", fraction, fraction2); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if (argc == 3) { if (GetListboxIndex(interp, listPtr, argv[2], 0, &index) @@ -986,7 +1004,7 @@ DestroyListbox(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, @@ -1718,7 +1736,7 @@ ListboxCmdDeletedProc(clientData) * Results: * A standard Tcl result. If all went well, then *indexPtr is * filled in with the index (into listPtr) corresponding to - * string. Otherwise an error message is left in interp->result. + * string. Otherwise an error message is left in the interp's result. * * Side effects: * None. diff --git a/generic/tkMacWinMenu.c b/generic/tkMacWinMenu.c index 6453a5f..ca77c45 100644 --- a/generic/tkMacWinMenu.c +++ b/generic/tkMacWinMenu.c @@ -9,12 +9,16 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacWinMenu.c,v 1.2 1998/09/14 18:23:14 stanton Exp $ + * RCS: @(#) $Id: tkMacWinMenu.c,v 1.3 1999/04/16 01:51:19 stanton Exp $ */ #include "tkMenu.h" -static int postCommandGeneration; +typedef struct ThreadSpecificData { + int postCommandGeneration; +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + static int PreprocessMenu _ANSI_ARGS_((TkMenu *menuPtr)); @@ -43,6 +47,8 @@ PreprocessMenu(menuPtr) { int index, result, finished; TkMenu *cascadeMenuPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_Preserve((ClientData) menuPtr); @@ -67,16 +73,16 @@ PreprocessMenu(menuPtr) finished = 1; for (index = 0; index < menuPtr->numEntries; index++) { if ((menuPtr->entries[index]->type == CASCADE_ENTRY) - && (menuPtr->entries[index]->name != NULL)) { + && (menuPtr->entries[index]->namePtr != NULL)) { if ((menuPtr->entries[index]->childMenuRefPtr != NULL) && (menuPtr->entries[index]->childMenuRefPtr->menuPtr != NULL)) { cascadeMenuPtr = menuPtr->entries[index]->childMenuRefPtr->menuPtr; if (cascadeMenuPtr->postCommandGeneration != - postCommandGeneration) { + tsdPtr->postCommandGeneration) { cascadeMenuPtr->postCommandGeneration = - postCommandGeneration; + tsdPtr->postCommandGeneration; result = PreprocessMenu(cascadeMenuPtr); if (result != TCL_OK) { goto done; @@ -128,7 +134,10 @@ int TkPreprocessMenu(menuPtr) TkMenu *menuPtr; { - postCommandGeneration++; - menuPtr->postCommandGeneration = postCommandGeneration; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + tsdPtr->postCommandGeneration++; + menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration; return PreprocessMenu(menuPtr); } diff --git a/generic/tkMain.c b/generic/tkMain.c index d55f920..9502926 100644 --- a/generic/tkMain.c +++ b/generic/tkMain.c @@ -8,12 +8,12 @@ * for Tk applications. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMain.c,v 1.3 1999/03/10 07:04:42 stanton Exp $ + * RCS: @(#) $Id: tkMain.c,v 1.4 1999/04/16 01:51:19 stanton Exp $ */ #include <ctype.h> @@ -27,6 +27,22 @@ #else # include <stdlib.h> #endif +#ifdef __WIN32__ +#include "tkWinInt.h" +#endif + + +typedef struct ThreadSpecificData { + Tcl_Interp *interp; /* Interpreter for this thread. */ + Tcl_DString command; /* Used to assemble lines of terminal input + * into Tcl commands. */ + Tcl_DString line; /* Used to read the next line from the + * terminal input. */ + int tty; /* Non-zero means standard input is a + * terminal-like device. Zero means it's + * a file. */ +} ThreadSpecificData; +Tcl_ThreadDataKey dataKey; /* * Declarations for various library procedures and variables (don't want @@ -37,8 +53,6 @@ * some systems. */ -void TkConsoleCreate_ _ANSI_ARGS_((void)); - #if !defined(__WIN32__) && !defined(_WIN32) extern int isatty _ANSI_ARGS_((int fd)); extern char * strrchr _ANSI_ARGS_((CONST char *string, int c)); @@ -46,18 +60,7 @@ extern char * strrchr _ANSI_ARGS_((CONST char *string, int c)); extern void TkpDisplayWarning _ANSI_ARGS_((char *msg, char *title)); -/* - * Global variables used by the main program: - */ - -static Tcl_Interp *interp; /* Interpreter for this application. */ -static Tcl_DString command; /* Used to assemble lines of terminal input - * into Tcl commands. */ -static Tcl_DString line; /* Used to read the next line from the - * terminal input. */ -static int tty; /* Non-zero means standard input is a - * terminal-like device. Zero means it's - * a file. */ +extern void TkConsoleCreate_ _ANSI_ARGS_((void)); /* * Forward declarations for procedures defined later in this file. @@ -70,7 +73,7 @@ static void StdinProc _ANSI_ARGS_((ClientData clientData, /* *---------------------------------------------------------------------- * - * Tk_Main, Tk_MainEx -- + * TkMainEx -- * * Main program for Wish and most other Tk-based applications. * @@ -85,19 +88,6 @@ static void StdinProc _ANSI_ARGS_((ClientData clientData, * *---------------------------------------------------------------------- */ - -void -Tk_Main(argc, argv, appInitProc) - int argc; /* Number of arguments. */ - char **argv; /* Array of argument strings. */ - Tcl_AppInitProc *appInitProc; /* Application-specific initialization - * procedure to call after most - * initialization but before starting - * to execute commands. */ -{ - Tk_MainEx(argc, argv, appInitProc, Tcl_CreateInterp()); -} - void Tk_MainEx(argc, argv, appInitProc, interp) int argc; /* Number of arguments. */ @@ -106,25 +96,33 @@ Tk_MainEx(argc, argv, appInitProc, interp) * procedure to call after most * initialization but before starting * to execute commands. */ - Tcl_Interp *interp; /* Application interpreter. */ + Tcl_Interp *interp; { char *args, *fileName; - char buf[20]; + char buf[TCL_INTEGER_SPACE]; int code; size_t length; Tcl_Channel inChannel, outChannel; + Tcl_DString argString; + ThreadSpecificData *tsdPtr; +#ifdef __WIN32__ + HANDLE handle; +#endif /* - * Make sure that Tcl is present. If using stubs this will initialize the - * stub table pointers. (for 8.1, noop in 8.0.x) + * Ensure that we are getting the matching version of Tcl. This is + * really only an issue when Tk is loaded dynamically. */ if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { abort(); } + + tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_FindExecutable(argv[0]); - + tsdPtr->interp = interp; #if (defined(__WIN32__) || defined(MAC_TCL)) TkConsoleCreate_(); @@ -161,12 +159,19 @@ Tk_MainEx(argc, argv, appInitProc, interp) */ args = Tcl_Merge(argc-1, argv+1); - Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); + Tcl_ExternalToUtfDString(NULL, args, -1, &argString); + Tcl_SetVar(interp, "argv", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); + Tcl_DStringFree(&argString); ckfree(args); sprintf(buf, "%d", argc-1); + + if (fileName == NULL) { + Tcl_ExternalToUtfDString(NULL, argv[0], -1, &argString); + } else { + fileName = Tcl_ExternalToUtfDString(NULL, fileName, -1, &argString); + } Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0], - TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "argv0", Tcl_DStringValue(&argString), TCL_GLOBAL_ONLY); /* * Set the "tcl_interactive" variable. @@ -180,19 +185,39 @@ Tk_MainEx(argc, argv, appInitProc, interp) */ #ifdef __WIN32__ - tty = 1; + handle = GetStdHandle(STD_INPUT_HANDLE); + + if ((handle == INVALID_HANDLE_VALUE) || (handle == 0) + || (GetFileType(handle) == FILE_TYPE_UNKNOWN)) { + /* + * If it's a bad or closed handle, then it's been connected + * to a wish console window. + */ + + tsdPtr->tty = 1; + } else if (GetFileType(handle) == FILE_TYPE_CHAR) { + /* + * A character file handle is a tty by definition. + */ + + tsdPtr->tty = 1; + } else { + tsdPtr->tty = 0; + } + #else - tty = isatty(0); + tsdPtr->tty = isatty(0); #endif Tcl_SetVar(interp, "tcl_interactive", - ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY); + ((fileName == NULL) && tsdPtr->tty) ? "1" : "0", TCL_GLOBAL_ONLY); /* * Invoke application-specific initialization. */ if ((*appInitProc)(interp) != TCL_OK) { - TkpDisplayWarning(interp->result, "Application initialization failed"); + TkpDisplayWarning(Tcl_GetStringResult(interp), + "Application initialization failed"); } /* @@ -200,6 +225,7 @@ Tk_MainEx(argc, argv, appInitProc, interp) */ if (fileName != NULL) { + Tcl_ResetResult(interp); code = Tcl_EvalFile(interp, fileName); if (code != TCL_OK) { /* @@ -213,7 +239,7 @@ Tk_MainEx(argc, argv, appInitProc, interp) Tcl_DeleteInterp(interp); Tcl_Exit(1); } - tty = 0; + tsdPtr->tty = 0; } else { /* @@ -231,17 +257,18 @@ Tk_MainEx(argc, argv, appInitProc, interp) Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc, (ClientData) inChannel); } - if (tty) { + if (tsdPtr->tty) { Prompt(interp, 0); } } + Tcl_DStringFree(&argString); outChannel = Tcl_GetStdChannel(TCL_STDOUT); if (outChannel) { Tcl_Flush(outChannel); } - Tcl_DStringInit(&command); - Tcl_DStringInit(&line); + Tcl_DStringInit(&tsdPtr->command); + Tcl_DStringInit(&tsdPtr->line); Tcl_ResetResult(interp); /* @@ -284,12 +311,15 @@ StdinProc(clientData, mask) char *cmd; int code, count; Tcl_Channel chan = (Tcl_Channel) clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_Interp *interp = tsdPtr->interp; - count = Tcl_Gets(chan, &line); + count = Tcl_Gets(chan, &tsdPtr->line); if (count < 0) { if (!gotPartial) { - if (tty) { + if (tsdPtr->tty) { Tcl_Exit(0); } else { Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan); @@ -298,9 +328,10 @@ StdinProc(clientData, mask) } } - (void) Tcl_DStringAppend(&command, Tcl_DStringValue(&line), -1); - cmd = Tcl_DStringAppend(&command, "\n", -1); - Tcl_DStringFree(&line); + (void) Tcl_DStringAppend(&tsdPtr->command, Tcl_DStringValue( + &tsdPtr->line), -1); + cmd = Tcl_DStringAppend(&tsdPtr->command, "\n", -1); + Tcl_DStringFree(&tsdPtr->line); if (!Tcl_CommandComplete(cmd)) { gotPartial = 1; goto prompt; @@ -323,17 +354,14 @@ StdinProc(clientData, mask) Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc, (ClientData) chan); } - Tcl_DStringFree(&command); - if (*interp->result != 0) { - if ((code != TCL_OK) || (tty)) { - /* - * The statement below used to call "printf", but that resulted - * in core dumps under Solaris 2.3 if the result was very long. - * - * NOTE: This probably will not work under Windows either. - */ - - puts(interp->result); + Tcl_DStringFree(&tsdPtr->command); + if (Tcl_GetStringResult(interp)[0] != '\0') { + if ((code != TCL_OK) || (tsdPtr->tty)) { + chan = Tcl_GetStdChannel(TCL_STDOUT); + if (chan) { + Tcl_WriteObj(chan, Tcl_GetObjResult(interp)); + Tcl_WriteChars(chan, "\n", 1); + } } } @@ -342,7 +370,7 @@ StdinProc(clientData, mask) */ prompt: - if (tty) { + if (tsdPtr->tty) { Prompt(interp, gotPartial); } Tcl_ResetResult(interp); @@ -391,7 +419,7 @@ defaultPrompt: outChannel = Tcl_GetChannel(interp, "stdout", NULL); if (outChannel != (Tcl_Channel) NULL) { - Tcl_Write(outChannel, "% ", 2); + Tcl_WriteChars(outChannel, "% ", 2); } } } else { @@ -407,8 +435,8 @@ defaultPrompt: errChannel = Tcl_GetChannel(interp, "stderr", NULL); if (errChannel != (Tcl_Channel) NULL) { - Tcl_Write(errChannel, interp->result, -1); - Tcl_Write(errChannel, "\n", 1); + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); } goto defaultPrompt; } diff --git a/generic/tkMenu.c b/generic/tkMenu.c index cbcdcb8..5a3de18 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -7,12 +7,12 @@ * and drawing code for menus is in the file tkMenuDraw.c * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenu.c,v 1.2 1998/09/14 18:23:14 stanton Exp $ + * RCS: @(#) $Id: tkMenu.c,v 1.3 1999/04/16 01:51:19 stanton Exp $ */ /* @@ -68,174 +68,247 @@ * */ +#if 0 + +/* + * used only to test for old config code + */ + +#define __NO_OLD_CONFIG +#endif + #include "tkPort.h" #include "tkMenu.h" #define MENU_HASH_KEY "tkMenus" -static int menusInitialized; /* Whether or not the hash tables, etc., have - * been setup */ +typedef struct ThreadSpecificData { + int menusInitialized; /* Flag indicates whether thread-specific + * elements of the Windows Menu module + * have been initialized. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* + * The following flag indicates whether the process-wide state for + * the Menu module has been intialized. The Mutex protects access to + * that flag. + */ + +static int menusInitialized; +TCL_DECLARE_MUTEX(menuMutex) /* * Configuration specs for individual menu entries. If this changes, be sure * to update code in TkpMenuInit that changes the font string entry. */ -Tk_ConfigSpec tkMenuEntryConfigSpecs[] = { - {TK_CONFIG_BORDER, "-activebackground", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorder), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-activeforeground", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_ACTIVE_FG, Tk_Offset(TkMenuEntry, activeFg), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-accelerator", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_ACCELERATOR, Tk_Offset(TkMenuEntry, accel), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_BORDER, "-background", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_BG, Tk_Offset(TkMenuEntry, border), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |SEPARATOR_MASK|TEAROFF_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_BITMAP, "-bitmap", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_BITMAP, Tk_Offset(TkMenuEntry, bitmap), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-columnbreak", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_COLUMN_BREAK, Tk_Offset(TkMenuEntry, columnBreak), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK}, - {TK_CONFIG_STRING, "-command", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_COMMAND, Tk_Offset(TkMenuEntry, command), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_FONT, Tk_Offset(TkMenuEntry, tkfont), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-foreground", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_FG, Tk_Offset(TkMenuEntry, fg), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-hidemargin", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_HIDE_MARGIN, Tk_Offset(TkMenuEntry, hideMargin), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |SEPARATOR_MASK|TEAROFF_MASK}, - {TK_CONFIG_STRING, "-image", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_IMAGE, Tk_Offset(TkMenuEntry, imageString), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_INDICATOR, Tk_Offset(TkMenuEntry, indicatorOn), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_DONT_SET_DEFAULT}, - {TK_CONFIG_STRING, "-label", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_LABEL, Tk_Offset(TkMenuEntry, label), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK}, - {TK_CONFIG_STRING, "-menu", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_MENU, Tk_Offset(TkMenuEntry, name), - CASCADE_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-offvalue", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_OFF_VALUE, Tk_Offset(TkMenuEntry, offValue), - CHECK_BUTTON_MASK}, - {TK_CONFIG_STRING, "-onvalue", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_ON_VALUE, Tk_Offset(TkMenuEntry, onValue), - CHECK_BUTTON_MASK}, - {TK_CONFIG_COLOR, "-selectcolor", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_SELECT, Tk_Offset(TkMenuEntry, indicatorFg), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-selectimage", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_SELECT_IMAGE, Tk_Offset(TkMenuEntry, selectImageString), - CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_UID, "-state", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_STATE, Tk_Offset(TkMenuEntry, state), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TEAROFF_MASK|TK_CONFIG_DONT_SET_DEFAULT}, - {TK_CONFIG_STRING, "-value", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_VALUE, Tk_Offset(TkMenuEntry, onValue), - RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-variable", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_CHECK_VARIABLE, Tk_Offset(TkMenuEntry, name), - CHECK_BUTTON_MASK|TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-variable", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_RADIO_VARIABLE, Tk_Offset(TkMenuEntry, name), - RADIO_BUTTON_MASK}, - {TK_CONFIG_INT, "-underline", (char *) NULL, (char *) NULL, - DEF_MENU_ENTRY_UNDERLINE, Tk_Offset(TkMenuEntry, underline), - COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK - |TK_CONFIG_DONT_SET_DEFAULT}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} +char *tkMenuStateStrings[] = {"active", "normal", "disabled", (char *) NULL}; + +static char *menuEntryTypeStrings[] = {"cascade", "checkbutton", "command", + "radiobutton", "separator", (char *) NULL}; + +Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1, + TK_OPTION_NULL_OK}, + {TK_OPTION_COLOR, "-activeforeground", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_ACTIVE_FG, + Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-accelerator", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_ACCELERATOR, + Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_BG, + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_BITMAP, "-bitmap", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_BITMAP, + Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_BOOLEAN, "-columnbreak", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_COLUMN_BREAK, + -1, Tk_Offset(TkMenuEntry, columnBreak)}, + {TK_OPTION_STRING, "-command", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_COMMAND, + Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_FONT, "-font", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_FONT, + Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_COLOR, "-foreground", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_FG, + Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_BOOLEAN, "-hidemargin", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_HIDE_MARGIN, + -1, Tk_Offset(TkMenuEntry, hideMargin)}, + {TK_OPTION_STRING, "-image", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_IMAGE, + Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-label", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_LABEL, + Tk_Offset(TkMenuEntry, labelPtr), -1, 0}, + {TK_OPTION_STRING_TABLE, "-state", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_STATE, + -1, Tk_Offset(TkMenuEntry, state), 0, + (ClientData) tkMenuStateStrings}, + {TK_OPTION_INT, "-underline", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(TkMenuEntry, underline)}, + {TK_OPTION_END} +}; + +Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = { + {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_BG, + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_END} +}; + +Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = { + {TK_OPTION_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_INDICATOR, + -1, Tk_Offset(TkMenuEntry, indicatorOn)}, + {TK_OPTION_STRING, "-offvalue", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_OFF_VALUE, + Tk_Offset(TkMenuEntry, offValuePtr), -1}, + {TK_OPTION_STRING, "-onvalue", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_ON_VALUE, + Tk_Offset(TkMenuEntry, onValuePtr), -1}, + {TK_OPTION_COLOR, "-selectcolor", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_SELECT, + Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-selectimage", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_SELECT_IMAGE, + Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-variable", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_CHECK_VARIABLE, + Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} +}; + +Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = { + {TK_OPTION_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_INDICATOR, + -1, Tk_Offset(TkMenuEntry, indicatorOn)}, + {TK_OPTION_COLOR, "-selectcolor", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_SELECT, + Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-selectimage", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_SELECT_IMAGE, + Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-value", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_VALUE, + Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-variable", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_RADIO_VARIABLE, + Tk_Offset(TkMenuEntry, namePtr), -1, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} }; +Tk_OptionSpec tkCascadeEntryConfigSpecs[] = { + {TK_OPTION_STRING, "-menu", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_MENU, + Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) tkBasicMenuEntryConfigSpecs} +}; + +Tk_OptionSpec tkTearoffEntryConfigSpecs[] = { + {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_BG, + Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING_TABLE, "-state", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state), 0, + (ClientData) tkMenuStateStrings}, + {TK_OPTION_END} +}; + +static Tk_OptionSpec *specsArray[] = { + tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs, + tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs, + tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs}; + /* - * Configuration specs valid for the menu as a whole. If this changes, be sure - * to update code in TkpMenuInit that changes the font string entry. + * Menu type strings for use with Tcl_GetIndexFromObj. */ -Tk_ConfigSpec tkMenuConfigSpecs[] = { - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_MENU_ACTIVE_BG_COLOR, Tk_Offset(TkMenu, activeBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_MENU_ACTIVE_BG_MONO, Tk_Offset(TkMenu, activeBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_PIXELS, "-activeborderwidth", "activeBorderWidth", +static char *menuTypeStrings[] = {"normal", "tearoff", "menubar", + (char *) NULL}; + +Tk_OptionSpec tkMenuConfigSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", + "Foreground", DEF_MENU_ACTIVE_BG_COLOR, + Tk_Offset(TkMenu, activeBorderPtr), -1, 0, + (ClientData) DEF_MENU_ACTIVE_BG_MONO}, + {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth", "BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH, - Tk_Offset(TkMenu, activeBorderWidth), 0}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_MENU_ACTIVE_FG_COLOR, Tk_Offset(TkMenu, activeFg), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_MENU_ACTIVE_FG_MONO, Tk_Offset(TkMenu, activeFg), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, border), TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_MENU_BG_MONO, Tk_Offset(TkMenu, border), TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_MENU_BORDER_WIDTH, Tk_Offset(TkMenu, borderWidth), 0}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_MENU_CURSOR, Tk_Offset(TkMenu, cursor), TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", + Tk_Offset(TkMenu, activeBorderWidthPtr), -1}, + {TK_OPTION_COLOR, "-activeforeground", "activeForeground", + "Background", DEF_MENU_ACTIVE_FG_COLOR, + Tk_Offset(TkMenu, activeFgPtr), -1, 0, + (ClientData) DEF_MENU_ACTIVE_FG_MONO}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0, + (ClientData) DEF_MENU_BG_MONO}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth"}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background"}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_MENU_BORDER_WIDTH, + Tk_Offset(TkMenu, borderWidthPtr), -1, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_MENU_CURSOR, + Tk_Offset(TkMenu, cursorPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_MENU_DISABLED_FG_COLOR, - Tk_Offset(TkMenu, disabledFg), TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", - "DisabledForeground", DEF_MENU_DISABLED_FG_MONO, - Tk_Offset(TkMenu, disabledFg), TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_FONT, "-font", "font", "Font", - DEF_MENU_FONT, Tk_Offset(TkMenu, tkfont), 0}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_MENU_FG, Tk_Offset(TkMenu, fg), 0}, - {TK_CONFIG_STRING, "-postcommand", "postCommand", "Command", - DEF_MENU_POST_COMMAND, Tk_Offset(TkMenu, postCommand), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_MENU_RELIEF, Tk_Offset(TkMenu, relief), 0}, - {TK_CONFIG_COLOR, "-selectcolor", "selectColor", "Background", - DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFg), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-selectcolor", "selectColor", "Background", - DEF_MENU_SELECT_MONO, Tk_Offset(TkMenu, indicatorFg), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_MENU_TAKE_FOCUS, Tk_Offset(TkMenu, takeFocus), TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-tearoff", "tearOff", "TearOff", - DEF_MENU_TEAROFF, Tk_Offset(TkMenu, tearOff), 0}, - {TK_CONFIG_STRING, "-tearoffcommand", "tearOffCommand", "TearOffCommand", - DEF_MENU_TEAROFF_CMD, Tk_Offset(TkMenu, tearOffCommand), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-title", "title", "Title", - DEF_MENU_TITLE, Tk_Offset(TkMenu, title), TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-type", "type", "Type", - DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypeName), TK_CONFIG_NULL_OK}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} + Tk_Offset(TkMenu, disabledFgPtr), -1, TK_OPTION_NULL_OK, + (ClientData) DEF_MENU_DISABLED_FG_MONO}, + {TK_OPTION_SYNONYM, "-fg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground"}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_MENU_FONT, Tk_Offset(TkMenu, fontPtr), -1}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_MENU_FG, Tk_Offset(TkMenu, fgPtr), -1}, + {TK_OPTION_STRING, "-postcommand", "postCommand", "Command", + DEF_MENU_POST_COMMAND, + Tk_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1}, + {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background", + DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFgPtr), -1, 0, + (ClientData) DEF_MENU_SELECT_MONO}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_MENU_TAKE_FOCUS, + Tk_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff", + DEF_MENU_TEAROFF, -1, Tk_Offset(TkMenu, tearoff)}, + {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand", + "TearOffCommand", DEF_MENU_TEAROFF_CMD, + Tk_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK}, + {TK_OPTION_STRING, "-title", "title", "Title", + DEF_MENU_TITLE, Tk_Offset(TkMenu, titlePtr), -1, + TK_OPTION_NULL_OK}, + {TK_OPTION_STRING_TABLE, "-type", "type", "Type", + DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1, TK_OPTION_NULL_OK, + (ClientData) menuTypeStrings}, + {TK_OPTION_END} +}; + +/* + * Command line options. Put here because MenuCmd has to look at them + * along with MenuWidgetObjCmd. + */ + +static char *menuOptions[] = { + "activate", "add", "cget", "clone", "configure", "delete", "entrycget", + "entryconfigure", "index", "insert", "invoke", "post", "postcascade", + "type", "unpost", "yposition", (char *) NULL +}; +enum options { + MENU_ACTIVATE, MENU_ADD, MENU_CGET, MENU_CLONE, MENU_CONFIGURE, + MENU_DELETE, MENU_ENTRYCGET, MENU_ENTRYCONFIGURE, MENU_INDEX, + MENU_INSERT, MENU_INVOKE, MENU_POST, MENU_POSTCASCADE, MENU_TYPE, + MENU_UNPOST, MENU_YPOSITION }; /* @@ -243,15 +316,14 @@ Tk_ConfigSpec tkMenuConfigSpecs[] = { */ static int CloneMenu _ANSI_ARGS_((TkMenu *menuPtr, - char *newMenuName, char *newMenuTypeString)); + Tcl_Obj *newMenuName, Tcl_Obj *newMenuTypeString)); static int ConfigureMenu _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuPtr, int argc, char **argv, - int flags)); + TkMenu *menuPtr, int objc, Tcl_Obj *CONST objv[])); static int ConfigureMenuCloneEntries _ANSI_ARGS_(( Tcl_Interp *interp, TkMenu *menuPtr, int index, - int argc, char **argv, int flags)); + int objc, Tcl_Obj *CONST objv[])); static int ConfigureMenuEntry _ANSI_ARGS_((TkMenuEntry *mePtr, - int argc, char **argv, int flags)); + int objc, Tcl_Obj *CONST objv[])); static void DeleteMenuCloneEntries _ANSI_ARGS_((TkMenu *menuPtr, int first, int last)); static void DestroyMenuHashTable _ANSI_ARGS_(( @@ -262,10 +334,13 @@ static int GetIndexFromCoords _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuPtr, char *string, int *indexPtr)); static int MenuDoYPosition _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuPtr, char *arg)); + TkMenu *menuPtr, Tcl_Obj *objPtr)); static int MenuAddOrInsert _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuPtr, char *indexString, int argc, - char **argv)); + TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc, + Tcl_Obj *CONST objv[])); +static int MenuCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static void MenuCmdDeletedProc _ANSI_ARGS_(( ClientData clientData)); static TkMenuEntry * MenuNewEntry _ANSI_ARGS_((TkMenu *menuPtr, int index, @@ -273,10 +348,12 @@ static TkMenuEntry * MenuNewEntry _ANSI_ARGS_((TkMenu *menuPtr, int index, static char * MenuVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); -static int MenuWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +static int MenuWidgetObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static void MenuWorldChanged _ANSI_ARGS_(( ClientData instanceData)); +static int PostProcessEntry _ANSI_ARGS_((TkMenuEntry *mePtr)); static void RecursivelyDeleteMenu _ANSI_ARGS_((TkMenu *menuPtr)); static void UnhookCascadeEntry _ANSI_ARGS_((TkMenuEntry *mePtr)); @@ -290,13 +367,61 @@ static TkClassProcs menuClass = { NULL, /* createProc. */ MenuWorldChanged /* geometryProc. */ }; + +/* + *-------------------------------------------------------------- + * + * Tk_CreateMenuCmd -- + * + * Called by Tk at initialization time to create the menu + * command. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ +int +TkCreateMenuCmd(interp) + Tcl_Interp *interp; /* Interpreter we are creating the + * command in. */ +{ + TkMenuOptionTables *optionTablesPtr = + (TkMenuOptionTables *) ckalloc(sizeof(TkMenuOptionTables)); + + optionTablesPtr->menuOptionTable = + Tk_CreateOptionTable(interp, tkMenuConfigSpecs); + optionTablesPtr->entryOptionTables[TEAROFF_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[TEAROFF_ENTRY]); + optionTablesPtr->entryOptionTables[COMMAND_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[COMMAND_ENTRY]); + optionTablesPtr->entryOptionTables[CASCADE_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[CASCADE_ENTRY]); + optionTablesPtr->entryOptionTables[SEPARATOR_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[SEPARATOR_ENTRY]); + optionTablesPtr->entryOptionTables[RADIO_BUTTON_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[RADIO_BUTTON_ENTRY]); + optionTablesPtr->entryOptionTables[CHECK_BUTTON_ENTRY] = + Tk_CreateOptionTable(interp, specsArray[CHECK_BUTTON_ENTRY]); + + Tcl_CreateObjCommand(interp, "menu", MenuCmd, + (ClientData) optionTablesPtr, NULL); + + if (Tcl_IsSafe(interp)) { + Tcl_HideCommand(interp, "menu", "menu"); + } + return TCL_OK; +} /* *-------------------------------------------------------------- * - * Tk_MenuCmd -- + * MenuCmd -- * * This procedure is invoked to process the "menu" Tcl * command. See the user documentation for details on @@ -311,48 +436,45 @@ static TkClassProcs menuClass = { *-------------------------------------------------------------- */ -int -Tk_MenuCmd(clientData, interp, argc, argv) +static int +MenuCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument strings. */ { - Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window tkwin = Tk_MainWindow(interp); Tk_Window new; register TkMenu *menuPtr; TkMenuReferences *menuRefPtr; - int i, len; - char *arg, c; + int i, index; int toplevel; + char *windowName; + static char *typeStringList[] = {"-type", (char *) NULL}; + TkMenuOptionTables *optionTablesPtr = (TkMenuOptionTables *) clientData; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } TkMenuInit(); toplevel = 1; - for (i = 2; i < argc; i += 2) { - arg = argv[i]; - len = strlen(arg); - if (len < 2) { - continue; - } - c = arg[1]; - if ((c == 't') && (strncmp(arg, "-type", strlen(arg)) == 0) - && (len >= 3)) { - if (strcmp(argv[i + 1], "menubar") == 0) { + for (i = 2; i < (objc - 1); i++) { + if (Tcl_GetIndexFromObj(NULL, objv[i], typeStringList, NULL, 0, &index) + != TCL_ERROR) { + if ((Tcl_GetIndexFromObj(NULL, objv[i + 1], menuTypeStrings, NULL, + 0, &index) == TCL_OK) && (index == MENUBAR)) { toplevel = 0; } break; } } - new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], toplevel ? "" + windowName = Tcl_GetStringFromObj(objv[1], NULL); + new = Tk_CreateWindowFromPath(interp, tkwin, windowName, toplevel ? "" : NULL); if (new == NULL) { return TCL_ERROR; @@ -366,27 +488,27 @@ Tk_MenuCmd(clientData, interp, argc, argv) menuPtr->tkwin = new; menuPtr->display = Tk_Display(new); menuPtr->interp = interp; - menuPtr->widgetCmd = Tcl_CreateCommand(interp, - Tk_PathName(menuPtr->tkwin), MenuWidgetCmd, + menuPtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, (ClientData) menuPtr, MenuCmdDeletedProc); menuPtr->entries = NULL; menuPtr->numEntries = 0; menuPtr->active = -1; - menuPtr->border = NULL; - menuPtr->borderWidth = 0; - menuPtr->relief = TK_RELIEF_FLAT; - menuPtr->activeBorder = NULL; - menuPtr->activeBorderWidth = 0; - menuPtr->tkfont = NULL; - menuPtr->fg = NULL; - menuPtr->disabledFg = NULL; - menuPtr->activeFg = NULL; - menuPtr->indicatorFg = NULL; - menuPtr->tearOff = 1; - menuPtr->tearOffCommand = NULL; - menuPtr->cursor = None; - menuPtr->takeFocus = NULL; - menuPtr->postCommand = NULL; + menuPtr->borderPtr = NULL; + menuPtr->borderWidthPtr = NULL; + menuPtr->reliefPtr = NULL; + menuPtr->activeBorderPtr = NULL; + menuPtr->activeBorderWidthPtr = NULL; + menuPtr->fontPtr = NULL; + menuPtr->fgPtr = NULL; + menuPtr->disabledFgPtr = NULL; + menuPtr->activeFgPtr = NULL; + menuPtr->indicatorFgPtr = NULL; + menuPtr->tearoff = 0; + menuPtr->tearoffCommandPtr = NULL; + menuPtr->cursorPtr = None; + menuPtr->takeFocusPtr = NULL; + menuPtr->postCommandPtr = NULL; menuPtr->postCommandGeneration = 0; menuPtr->postedCascade = NULL; menuPtr->nextInstancePtr = NULL; @@ -394,24 +516,38 @@ Tk_MenuCmd(clientData, interp, argc, argv) menuPtr->menuType = UNKNOWN_TYPE; menuPtr->menuFlags = 0; menuPtr->parentTopLevelPtr = NULL; - menuPtr->menuTypeName = NULL; - menuPtr->title = NULL; + menuPtr->menuTypePtr = NULL; + menuPtr->titlePtr = NULL; + menuPtr->errorStructPtr = NULL; + menuPtr->optionTablesPtr = optionTablesPtr; TkMenuInitializeDrawingFields(menuPtr); + Tk_SetClass(menuPtr->tkwin, "Menu"); + TkSetClassProcs(menuPtr->tkwin, &menuClass, (ClientData) menuPtr); + if (Tk_InitOptions(interp, (char *) menuPtr, + menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin) + != TCL_OK) { + Tk_DestroyWindow(menuPtr->tkwin); + ckfree((char *) menuPtr); + return TCL_ERROR; + } + + menuRefPtr = TkCreateMenuReferences(menuPtr->interp, Tk_PathName(menuPtr->tkwin)); menuRefPtr->menuPtr = menuPtr; menuPtr->menuRefPtr = menuRefPtr; if (TCL_OK != TkpNewMenu(menuPtr)) { - goto error; + Tk_DestroyWindow(menuPtr->tkwin); + ckfree((char *) menuPtr); + return TCL_ERROR; } - Tk_SetClass(menuPtr->tkwin, "Menu"); - TkSetClassProcs(menuPtr->tkwin, &menuClass, (ClientData) menuPtr); Tk_CreateEventHandler(new, ExposureMask|StructureNotifyMask|ActivateMask, TkMenuEventProc, (ClientData) menuPtr); - if (ConfigureMenu(interp, menuPtr, argc-2, argv+2, 0) != TCL_OK) { - goto error; + if (ConfigureMenu(interp, menuPtr, objc - 2, objv + 2) != TCL_OK) { + Tk_DestroyWindow(menuPtr->tkwin); + return TCL_ERROR; } /* @@ -434,8 +570,8 @@ Tk_MenuCmd(clientData, interp, argc, argv) if (menuRefPtr->parentEntryPtr != NULL) { TkMenuEntry *cascadeListPtr = menuRefPtr->parentEntryPtr; TkMenuEntry *nextCascadePtr; - char *newMenuName; - char *newArgv[2]; + Tcl_Obj *newMenuName; + Tcl_Obj *newObjv[2]; while (cascadeListPtr != NULL) { @@ -454,28 +590,38 @@ Tk_MenuCmd(clientData, interp, argc, argv) || ((menuPtr->masterMenuPtr == menuPtr) && ((cascadeListPtr->menuPtr->masterMenuPtr == cascadeListPtr->menuPtr)))) { - newArgv[0] = "-menu"; - newArgv[1] = Tk_PathName(menuPtr->tkwin); - ConfigureMenuEntry(cascadeListPtr, 2, newArgv, - TK_CONFIG_ARGV_ONLY); + newObjv[0] = Tcl_NewStringObj("-menu", -1); + newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1); + Tcl_IncrRefCount(newObjv[0]); + Tcl_IncrRefCount(newObjv[1]); + ConfigureMenuEntry(cascadeListPtr, 2, newObjv); + Tcl_DecrRefCount(newObjv[0]); + Tcl_DecrRefCount(newObjv[1]); } else { + Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1); + Tcl_Obj *windowNamePtr = Tcl_NewStringObj( + Tk_PathName(cascadeListPtr->menuPtr->tkwin), -1); + + Tcl_IncrRefCount(normalPtr); + Tcl_IncrRefCount(windowNamePtr); newMenuName = TkNewMenuName(menuPtr->interp, - Tk_PathName(cascadeListPtr->menuPtr->tkwin), - menuPtr); - CloneMenu(menuPtr, newMenuName, "normal"); + windowNamePtr, menuPtr); + Tcl_IncrRefCount(newMenuName); + CloneMenu(menuPtr, newMenuName, normalPtr); /* * Now we can set the new menu instance to be the cascade entry * of the parent's instance. */ - newArgv[0] = "-menu"; - newArgv[1] = newMenuName; - ConfigureMenuEntry(cascadeListPtr, 2, newArgv, - TK_CONFIG_ARGV_ONLY); - if (newMenuName != NULL) { - ckfree(newMenuName); - } + newObjv[0] = Tcl_NewStringObj("-menu", -1); + newObjv[1] = newMenuName; + Tcl_IncrRefCount(newObjv[0]); + ConfigureMenuEntry(cascadeListPtr, 2, newObjv); + Tcl_DecrRefCount(normalPtr); + Tcl_DecrRefCount(newObjv[0]); + Tcl_DecrRefCount(newObjv[1]); + Tcl_DecrRefCount(windowNamePtr); } cascadeListPtr = nextCascadePtr; } @@ -507,18 +653,14 @@ Tk_MenuCmd(clientData, interp, argc, argv) } } - interp->result = Tk_PathName(menuPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(menuPtr->tkwin), TCL_STATIC); return TCL_OK; - - error: - Tk_DestroyWindow(menuPtr->tkwin); - return TCL_ERROR; } /* *-------------------------------------------------------------- * - * MenuWidgetCmd -- + * MenuWidgetObjCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. @@ -534,317 +676,351 @@ Tk_MenuCmd(clientData, interp, argc, argv) */ static int -MenuWidgetCmd(clientData, interp, argc, argv) +MenuWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about menu widget. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument strings. */ { register TkMenu *menuPtr = (TkMenu *) clientData; register TkMenuEntry *mePtr; int result = TCL_OK; - size_t length; - int c; + int option; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], menuOptions, "option", 0, + &option) != TCL_OK) { return TCL_ERROR; } Tcl_Preserve((ClientData) menuPtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'a') && (strncmp(argv[1], "activate", length) == 0) - && (length >= 2)) { - int index; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " activate index\"", (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (menuPtr->active == index) { - goto done; - } - if (index >= 0) { - if ((menuPtr->entries[index]->type == SEPARATOR_ENTRY) - || (menuPtr->entries[index]->state == tkDisabledUid)) { + + switch ((enum options) option) { + case MENU_ACTIVATE: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "activate index"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if (menuPtr->active == index) { + goto done; + } + if ((index >= 0) + && ((menuPtr->entries[index]->type == SEPARATOR_ENTRY) + || (menuPtr->entries[index]->state + == ENTRY_DISABLED))) { index = -1; } + result = TkActivateMenuEntry(menuPtr, index); + break; } - result = TkActivateMenuEntry(menuPtr, index); - } else if ((c == 'a') && (strncmp(argv[1], "add", length) == 0) - && (length >= 2)) { - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " add type ?options?\"", (char *) NULL); - goto error; + case MENU_ADD: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "add type ?options?"); + goto error; + } + + if (MenuAddOrInsert(interp, menuPtr, (Tcl_Obj *) NULL, + objc - 2, objv + 2) != TCL_OK) { + goto error; + } + break; + case MENU_CGET: { + Tcl_Obj *resultPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); + goto error; + } + resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr, + menuPtr->optionTablesPtr->menuOptionTable, objv[2], + menuPtr->tkwin); + if (resultPtr == NULL) { + goto error; + } + Tcl_SetObjResult(interp, resultPtr); + break; } - if (MenuAddOrInsert(interp, menuPtr, (char *) NULL, - argc-2, argv+2) != TCL_OK) { - goto error; + case MENU_CLONE: + if ((objc < 3) || (objc > 4)) { + Tcl_WrongNumArgs(interp, 1, objv, + "clone newMenuName ?menuType?"); + goto error; + } + result = CloneMenu(menuPtr, objv[2], (objc == 3) ? NULL : objv[3]); + break; + case MENU_CONFIGURE: { + Tcl_Obj *resultPtr; + + if (objc == 2) { + resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, + menuPtr->optionTablesPtr->menuOptionTable, + (Tcl_Obj *) NULL, menuPtr->tkwin); + if (resultPtr == NULL) { + result = TCL_ERROR; + } else { + result = TCL_OK; + Tcl_SetObjResult(interp, resultPtr); + } + } else if (objc == 3) { + resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, + menuPtr->optionTablesPtr->menuOptionTable, + objv[2], menuPtr->tkwin); + if (resultPtr == NULL) { + result = TCL_ERROR; + } else { + result = TCL_OK; + Tcl_SetObjResult(interp, resultPtr); + } + } else { + result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2); + } + if (result != TCL_OK) { + goto error; + } + break; } - } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - goto error; + case MENU_DELETE: { + int first, last; + + if ((objc != 3) && (objc != 4)) { + Tcl_WrongNumArgs(interp, 1, objv, "delete first ?last?"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &first) + != TCL_OK) { + goto error; + } + if (objc == 3) { + last = first; + } else { + if (TkGetMenuIndex(interp, menuPtr, objv[3], 0, &last) + != TCL_OK) { + goto error; + } + } + if (menuPtr->tearoff && (first == 0)) { + + /* + * Sorry, can't delete the tearoff entry; must reconfigure + * the menu. + */ + + first = 1; + } + if ((first < 0) || (last < first)) { + goto done; + } + DeleteMenuCloneEntries(menuPtr, first, last); + break; } - result = Tk_ConfigureValue(interp, menuPtr->tkwin, tkMenuConfigSpecs, - (char *) menuPtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "clone", length) == 0) - && (length >=2)) { - if ((argc < 3) || (argc > 4)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " clone newMenuName ?menuType?\"", - (char *) NULL); - goto error; - } - result = CloneMenu(menuPtr, argv[2], (argc == 3) ? NULL : argv[3]); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, menuPtr->tkwin, - tkMenuConfigSpecs, (char *) menuPtr, (char *) NULL, 0); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, menuPtr->tkwin, - tkMenuConfigSpecs, (char *) menuPtr, argv[2], 0); - } else { - result = ConfigureMenu(interp, menuPtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); + case MENU_ENTRYCGET: { + int index; + Tcl_Obj *resultPtr; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "entrycget index option"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if (index < 0) { + goto done; + } + mePtr = menuPtr->entries[index]; + Tcl_Preserve((ClientData) mePtr); + resultPtr = Tk_GetOptionValue(interp, (char *) mePtr, + mePtr->optionTable, objv[3], menuPtr->tkwin); + Tcl_Release((ClientData) mePtr); + if (resultPtr == NULL) { + goto error; + } + Tcl_SetObjResult(interp, resultPtr); + break; } - } else if ((c == 'd') && (strncmp(argv[1], "delete", length) == 0)) { - int first, last; + case MENU_ENTRYCONFIGURE: { + int index; + Tcl_Obj *resultPtr; - if ((argc != 3) && (argc != 4)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " delete first ?last?\"", (char *) NULL); - goto error; + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, + "entryconfigure index ?option value ...?"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if (index < 0) { + goto done; + } + mePtr = menuPtr->entries[index]; + Tcl_Preserve((ClientData) mePtr); + if (objc == 3) { + resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr, + mePtr->optionTable, (Tcl_Obj *) NULL, menuPtr->tkwin); + if (resultPtr == NULL) { + result = TCL_ERROR; + } else { + result = TCL_OK; + Tcl_SetObjResult(interp, resultPtr); + } + } else if (objc == 4) { + resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr, + mePtr->optionTable, objv[3], menuPtr->tkwin); + if (resultPtr == NULL) { + result = TCL_ERROR; + } else { + result = TCL_OK; + Tcl_SetObjResult(interp, resultPtr); + } + } else { + result = ConfigureMenuCloneEntries(interp, menuPtr, index, + objc - 3, objv + 3); + } + Tcl_Release((ClientData) mePtr); + break; } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &first) != TCL_OK) { - goto error; + case MENU_INDEX: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "index string"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if (index < 0) { + Tcl_SetResult(interp, "none", TCL_STATIC); + } else { + Tcl_SetIntObj(Tcl_GetObjResult(interp), index); + } + break; } - if (argc == 3) { - last = first; - } else { - if (TkGetMenuIndex(interp, menuPtr, argv[3], 0, &last) != TCL_OK) { - goto error; + case MENU_INSERT: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "insert index type ?options?"); + goto error; + } + if (MenuAddOrInsert(interp, menuPtr, objv[2], objc - 3, + objv + 3) != TCL_OK) { + goto error; + } + break; + case MENU_INVOKE: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "invoke index"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; } + if (index < 0) { + goto done; + } + result = TkInvokeMenu(interp, menuPtr, index); + break; } - if (menuPtr->tearOff && (first == 0)) { + case MENU_POST: { + int x, y; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "post x y"); + goto error; + } + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { + goto error; + } /* - * Sorry, can't delete the tearoff entry; must reconfigure - * the menu. + * Tearoff menus are posted differently on Mac and Windows than + * non-tearoffs. TkpPostMenu does not actually map the menu's + * window on those platforms, and popup menus have to be + * handled specially. */ - first = 1; - } - if ((first < 0) || (last < first)) { - goto done; - } - DeleteMenuCloneEntries(menuPtr, first, last); - } else if ((c == 'e') && (length >= 7) - && (strncmp(argv[1], "entrycget", length) == 0)) { - int index; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " entrycget index option\"", - (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (index < 0) { - goto done; - } - mePtr = menuPtr->entries[index]; - Tcl_Preserve((ClientData) mePtr); - result = Tk_ConfigureValue(interp, menuPtr->tkwin, - tkMenuEntryConfigSpecs, (char *) mePtr, argv[3], - COMMAND_MASK << mePtr->type); - Tcl_Release((ClientData) mePtr); - } else if ((c == 'e') && (length >= 7) - && (strncmp(argv[1], "entryconfigure", length) == 0)) { - int index; - - if (argc < 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " entryconfigure index ?option value ...?\"", - (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (index < 0) { - goto done; - } - mePtr = menuPtr->entries[index]; - Tcl_Preserve((ClientData) mePtr); - if (argc == 3) { - result = Tk_ConfigureInfo(interp, menuPtr->tkwin, - tkMenuEntryConfigSpecs, (char *) mePtr, (char *) NULL, - COMMAND_MASK << mePtr->type); - } else if (argc == 4) { - result = Tk_ConfigureInfo(interp, menuPtr->tkwin, - tkMenuEntryConfigSpecs, (char *) mePtr, argv[3], - COMMAND_MASK << mePtr->type); - } else { - result = ConfigureMenuCloneEntries(interp, menuPtr, index, - argc-3, argv+3, - TK_CONFIG_ARGV_ONLY | COMMAND_MASK << mePtr->type); - } - Tcl_Release((ClientData) mePtr); - } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) - && (length >= 3)) { - int index; - - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " index string\"", (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (index < 0) { - interp->result = "none"; - } else { - sprintf(interp->result, "%d", index); - } - } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) - && (length >= 3)) { - if (argc < 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " insert index type ?options?\"", (char *) NULL); - goto error; - } - if (MenuAddOrInsert(interp, menuPtr, argv[2], - argc-3, argv+3) != TCL_OK) { - goto error; + if (menuPtr->menuType != TEAROFF_MENU) { + result = TkpPostMenu(interp, menuPtr, x, y); + } else { + result = TkPostTearoffMenu(interp, menuPtr, x, y); + } + break; } - } else if ((c == 'i') && (strncmp(argv[1], "invoke", length) == 0) - && (length >= 3)) { - int index; + case MENU_POSTCASCADE: { + int index; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " invoke index\"", (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (index < 0) { - goto done; - } - result = TkInvokeMenu(interp, menuPtr, index); - } else if ((c == 'p') && (strncmp(argv[1], "post", length) == 0) - && (length == 4)) { - int x, y; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " post x y\"", (char *) NULL); - goto error; - } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { - goto error; - } + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "postcascade index"); + goto error; + } - /* - * Tearoff menus are posted differently on Mac and Windows than - * non-tearoffs. TkpPostMenu does not actually map the menu's - * window on those platforms, and popup menus have to be - * handled specially. - */ - - if (menuPtr->menuType != TEAROFF_MENU) { - result = TkpPostMenu(interp, menuPtr, x, y); - } else { - result = TkPostTearoffMenu(interp, menuPtr, x, y); - } - } else if ((c == 'p') && (strncmp(argv[1], "postcascade", length) == 0) - && (length > 4)) { - int index; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " postcascade index\"", (char *) NULL); - goto error; + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if ((index < 0) || (menuPtr->entries[index]->type + != CASCADE_ENTRY)) { + result = TkPostSubmenu(interp, menuPtr, (TkMenuEntry *) NULL); + } else { + result = TkPostSubmenu(interp, menuPtr, + menuPtr->entries[index]); + } + break; } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; + case MENU_TYPE: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "type index"); + goto error; + } + if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) + != TCL_OK) { + goto error; + } + if (index < 0) { + goto done; + } + if (menuPtr->entries[index]->type == TEAROFF_ENTRY) { + Tcl_SetResult(interp, "tearoff", TCL_STATIC); + } else { + Tcl_SetResult(interp, + menuEntryTypeStrings[menuPtr->entries[index]->type], + TCL_STATIC); + } + break; } - if ((index < 0) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) { + case MENU_UNPOST: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "unpost"); + goto error; + } + Tk_UnmapWindow(menuPtr->tkwin); result = TkPostSubmenu(interp, menuPtr, (TkMenuEntry *) NULL); - } else { - result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]); - } - } else if ((c == 't') && (strncmp(argv[1], "type", length) == 0)) { - int index; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " type index\"", (char *) NULL); - goto error; - } - if (TkGetMenuIndex(interp, menuPtr, argv[2], 0, &index) != TCL_OK) { - goto error; - } - if (index < 0) { - goto done; - } - mePtr = menuPtr->entries[index]; - switch (mePtr->type) { - case COMMAND_ENTRY: - interp->result = "command"; - break; - case SEPARATOR_ENTRY: - interp->result = "separator"; - break; - case CHECK_BUTTON_ENTRY: - interp->result = "checkbutton"; - break; - case RADIO_BUTTON_ENTRY: - interp->result = "radiobutton"; - break; - case CASCADE_ENTRY: - interp->result = "cascade"; - break; - case TEAROFF_ENTRY: - interp->result = "tearoff"; - break; - } - } else if ((c == 'u') && (strncmp(argv[1], "unpost", length) == 0)) { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " unpost\"", (char *) NULL); - goto error; - } - Tk_UnmapWindow(menuPtr->tkwin); - result = TkPostSubmenu(interp, menuPtr, (TkMenuEntry *) NULL); - } else if ((c == 'y') && (strncmp(argv[1], "yposition", length) == 0)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " yposition index\"", (char *) NULL); - goto error; - } - result = MenuDoYPosition(interp, menuPtr, argv[2]); - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be activate, add, cget, clone, configure, delete, ", - "entrycget, entryconfigure, index, insert, invoke, ", - "post, postcascade, type, unpost, or yposition", - (char *) NULL); - goto error; + break; + case MENU_YPOSITION: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "yposition index"); + goto error; + } + result = MenuDoYPosition(interp, menuPtr, objv[2]); + break; } done: Tcl_Release((ClientData) menuPtr); @@ -854,7 +1030,6 @@ MenuWidgetCmd(clientData, interp, argc, argv) Tcl_Release((ClientData) menuPtr); return TCL_ERROR; } - /* *---------------------------------------------------------------------- @@ -888,45 +1063,60 @@ TkInvokeMenu(interp, menuPtr, index) goto done; } mePtr = menuPtr->entries[index]; - if (mePtr->state == tkDisabledUid) { + if (mePtr->state == ENTRY_DISABLED) { goto done; } Tcl_Preserve((ClientData) mePtr); if (mePtr->type == TEAROFF_ENTRY) { - Tcl_DString commandDString; - - Tcl_DStringInit(&commandDString); - Tcl_DStringAppendElement(&commandDString, "tkTearOffMenu"); - Tcl_DStringAppendElement(&commandDString, Tk_PathName(menuPtr->tkwin)); - result = Tcl_Eval(interp, Tcl_DStringValue(&commandDString)); - Tcl_DStringFree(&commandDString); - } else if (mePtr->type == CHECK_BUTTON_ENTRY) { + Tcl_DString ds; + Tcl_DStringInit(&ds); + Tcl_DStringAppend(&ds, "tkTearOffMenu ", -1); + Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->tkwin), -1); + result = Tcl_Eval(interp, Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + } else if ((mePtr->type == CHECK_BUTTON_ENTRY) + && (mePtr->namePtr != NULL)) { + Tcl_Obj *valuePtr; + if (mePtr->entryFlags & ENTRY_SELECTED) { - if (Tcl_SetVar(interp, mePtr->name, mePtr->offValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; - } + valuePtr = mePtr->offValuePtr; } else { - if (Tcl_SetVar(interp, mePtr->name, mePtr->onValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; - } + valuePtr = mePtr->onValuePtr; + } + if (valuePtr == NULL) { + valuePtr = Tcl_NewObj(); + } + Tcl_IncrRefCount(valuePtr); + if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + result = TCL_ERROR; + } + Tcl_DecrRefCount(valuePtr); + } else if ((mePtr->type == RADIO_BUTTON_ENTRY) + && (mePtr->namePtr != NULL)) { + Tcl_Obj *valuePtr = mePtr->onValuePtr; + + if (valuePtr == NULL) { + valuePtr = Tcl_NewObj(); } - } else if (mePtr->type == RADIO_BUTTON_ENTRY) { - if (Tcl_SetVar(interp, mePtr->name, mePtr->onValue, + Tcl_IncrRefCount(valuePtr); + if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { result = TCL_ERROR; } + Tcl_DecrRefCount(valuePtr); } - if ((result == TCL_OK) && (mePtr->command != NULL)) { - result = TkCopyAndGlobalEval(interp, mePtr->command); + if ((result == TCL_OK) && (mePtr->commandPtr != NULL)) { + Tcl_Obj *commandPtr = mePtr->commandPtr; + + Tcl_IncrRefCount(commandPtr); + result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL); + Tcl_DecrRefCount(commandPtr); } Tcl_Release((ClientData) mePtr); done: return result; } - - /* *---------------------------------------------------------------------- @@ -951,13 +1141,12 @@ static void DestroyMenuInstance(menuPtr) TkMenu *menuPtr; /* Info about menu widget. */ { - int i, numEntries = menuPtr->numEntries; + int i; TkMenu *menuInstancePtr; TkMenuEntry *cascadePtr, *nextCascadePtr; - char *newArgv[2]; + Tcl_Obj *newObjv[2]; TkMenu *parentMasterMenuPtr; TkMenuEntry *parentMasterEntryPtr; - TkMenu *parentMenuPtr; /* * If the menu has any cascade menu entries pointing to it, the cascade @@ -979,18 +1168,23 @@ DestroyMenuInstance(menuPtr) TkFreeMenuReferences(menuPtr->menuRefPtr); for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) { - parentMenuPtr = cascadePtr->menuPtr; nextCascadePtr = cascadePtr->nextCascadePtr; if (menuPtr->masterMenuPtr != menuPtr) { + Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1); + parentMasterMenuPtr = cascadePtr->menuPtr->masterMenuPtr; parentMasterEntryPtr = parentMasterMenuPtr->entries[cascadePtr->index]; - newArgv[0] = "-menu"; - newArgv[1] = parentMasterEntryPtr->name; - ConfigureMenuEntry(cascadePtr, 2, newArgv, TK_CONFIG_ARGV_ONLY); + newObjv[0] = menuNamePtr; + newObjv[1] = parentMasterEntryPtr->namePtr; + Tcl_IncrRefCount(newObjv[0]); + Tcl_IncrRefCount(newObjv[1]); + ConfigureMenuEntry(cascadePtr, 2, newObjv); + Tcl_DecrRefCount(newObjv[0]); + Tcl_DecrRefCount(newObjv[1]); } else { - ConfigureMenuEntry(cascadePtr, 0, (char **) NULL, 0); + ConfigureMenuEntry(cascadePtr, 0, (Tcl_Obj **) NULL); } } @@ -1010,20 +1204,27 @@ DestroyMenuInstance(menuPtr) /* * Free up all the stuff that requires special handling, then - * let Tk_FreeOptions handle all the standard option-related + * let Tk_FreeConfigurationOptions handle all the standard option-related * stuff. */ - for (i = numEntries - 1; i >= 0; i--) { + for (i = menuPtr->numEntries; --i >= 0; ) { + /* + * As each menu entry is deleted from the end of the array of + * entries, decrement menuPtr->numEntries. Otherwise, the act of + * deleting menu entry i will dereference freed memory attempting + * to queue a redraw for menu entries (i+1)...numEntries. + */ + DestroyMenuEntry((char *) menuPtr->entries[i]); + menuPtr->numEntries = i; } if (menuPtr->entries != NULL) { ckfree((char *) menuPtr->entries); } TkMenuFreeDrawOptions(menuPtr); - Tk_FreeOptions(tkMenuConfigSpecs, (char *) menuPtr, menuPtr->display, 0); - - Tcl_EventuallyFree((ClientData) menuPtr, TCL_DYNAMIC); + Tk_FreeConfigOptions((char *) menuPtr, + menuPtr->optionTablesPtr->menuOptionTable, menuPtr->tkwin); } /* @@ -1202,7 +1403,7 @@ DestroyMenuEntry(memPtr) /* * Free up all the stuff that requires special handling, then - * let Tk_FreeOptions handle all the standard option-related + * let Tk_FreeConfigurationOptions handle all the standard option-related * stuff. */ @@ -1215,15 +1416,17 @@ DestroyMenuEntry(memPtr) if (mePtr->selectImage != NULL) { Tk_FreeImage(mePtr->selectImage); } - if (mePtr->name != NULL) { - Tcl_UntraceVar(menuPtr->interp, mePtr->name, + if (((mePtr->type == CHECK_BUTTON_ENTRY) + || (mePtr->type == RADIO_BUTTON_ENTRY)) + && (mePtr->namePtr != NULL)) { + char *varName = Tcl_GetStringFromObj(mePtr->namePtr, NULL); + Tcl_UntraceVar(menuPtr->interp, varName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuVarProc, (ClientData) mePtr); } TkpDestroyMenuEntry(mePtr); TkMenuEntryFreeDrawOptions(mePtr); - Tk_FreeOptions(tkMenuEntryConfigSpecs, (char *) mePtr, menuPtr->display, - (COMMAND_MASK << mePtr->type)); + Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, menuPtr->tkwin); ckfree((char *) mePtr); } @@ -1259,7 +1462,6 @@ MenuWorldChanged(instanceData) TkpConfigureMenuEntry(menuPtr->entries[i]); } } - /* *---------------------------------------------------------------------- @@ -1272,7 +1474,7 @@ MenuWorldChanged(instanceData) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, font, etc. get set @@ -1282,23 +1484,32 @@ MenuWorldChanged(instanceData) */ static int -ConfigureMenu(interp, menuPtr, argc, argv, flags) +ConfigureMenu(interp, menuPtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ register TkMenu *menuPtr; /* Information about widget; may or may * not already have values for some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Flags to pass to Tk_ConfigureWidget. */ + int objc; /* Number of valid entries in argv. */ + Tcl_Obj *CONST objv[]; /* Arguments. */ { int i; - TkMenu* menuListPtr; + TkMenu *menuListPtr, *cleanupPtr; + int result; for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL; menuListPtr = menuListPtr->nextInstancePtr) { - - if (Tk_ConfigureWidget(interp, menuListPtr->tkwin, - tkMenuConfigSpecs, argc, argv, (char *) menuListPtr, - flags) != TCL_OK) { + menuListPtr->errorStructPtr = (Tk_SavedOptions *) + ckalloc(sizeof(Tk_SavedOptions)); + result = Tk_SetOptions(interp, (char *) menuListPtr, + menuListPtr->optionTablesPtr->menuOptionTable, objc, objv, + menuListPtr->tkwin, menuListPtr->errorStructPtr, (int *) NULL); + if (result != TCL_OK) { + for (cleanupPtr = menuPtr->masterMenuPtr; + cleanupPtr != menuListPtr; + cleanupPtr = cleanupPtr->nextInstancePtr) { + Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr); + ckfree((char *) cleanupPtr->errorStructPtr); + cleanupPtr->errorStructPtr = NULL; + } return TCL_ERROR; } @@ -1310,33 +1521,57 @@ ConfigureMenu(interp, menuPtr, argc, argv, flags) */ if (menuListPtr->menuType == UNKNOWN_TYPE) { - if (strcmp(menuListPtr->menuTypeName, "menubar") == 0) { - menuListPtr->menuType = MENUBAR; - } else if (strcmp(menuListPtr->menuTypeName, "tearoff") == 0) { - menuListPtr->menuType = TEAROFF_MENU; - } else { - menuListPtr->menuType = MASTER_MENU; + Tcl_GetIndexFromObj(NULL, menuListPtr->menuTypePtr, + menuTypeStrings, NULL, 0, &menuListPtr->menuType); + + /* + * Configure the new window to be either a pop-up menu + * or a tear-off menu. + * We don't do this for menubars since they are not toplevel + * windows. Also, since this gets called before CloneMenu has + * a chance to set the menuType field, we have to look at the + * menuTypeName field to tell that this is a menu bar. + */ + + if (menuListPtr->menuType == MASTER_MENU) { + TkpMakeMenuWindow(menuListPtr->tkwin, 1); + } else if (menuListPtr->menuType == TEAROFF_MENU) { + TkpMakeMenuWindow(menuListPtr->tkwin, 0); } } - + + /* * Depending on the -tearOff option, make sure that there is or * isn't an initial tear-off entry at the beginning of the menu. */ - if (menuListPtr->tearOff) { + if (menuListPtr->tearoff) { if ((menuListPtr->numEntries == 0) || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) { if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) { + if (menuListPtr->errorStructPtr != NULL) { + for (cleanupPtr = menuPtr->masterMenuPtr; + cleanupPtr != menuListPtr; + cleanupPtr = cleanupPtr->nextInstancePtr) { + Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr); + ckfree((char *) cleanupPtr->errorStructPtr); + cleanupPtr->errorStructPtr = NULL; + } + Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr); + ckfree((char *) cleanupPtr->errorStructPtr); + cleanupPtr->errorStructPtr = NULL; + } return TCL_ERROR; } } } else if ((menuListPtr->numEntries > 0) && (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) { int i; - + Tcl_EventuallyFree((ClientData) menuListPtr->entries[0], DestroyMenuEntry); + for (i = 0; i < menuListPtr->numEntries - 1; i++) { menuListPtr->entries[i] = menuListPtr->entries[i + 1]; menuListPtr->entries[i]->index = i; @@ -1349,21 +1584,6 @@ ConfigureMenu(interp, menuPtr, argc, argv, flags) } TkMenuConfigureDrawOptions(menuListPtr); - - /* - * Configure the new window to be either a pop-up menu - * or a tear-off menu. - * We don't do this for menubars since they are not toplevel - * windows. Also, since this gets called before CloneMenu has - * a chance to set the menuType field, we have to look at the - * menuTypeName field to tell that this is a menu bar. - */ - - if (strcmp(menuListPtr->menuTypeName, "normal") == 0) { - TkpMakeMenuWindow(menuListPtr->tkwin, 1); - } else if (strcmp(menuListPtr->menuTypeName, "tearoff") == 0) { - TkpMakeMenuWindow(menuListPtr->tkwin, 0); - } /* * After reconfiguring a menu, we need to reconfigure all of the @@ -1376,28 +1596,35 @@ ConfigureMenu(interp, menuPtr, argc, argv, flags) TkMenuEntry *mePtr; mePtr = menuListPtr->entries[i]; - ConfigureMenuEntry(mePtr, 0, - (char **) NULL, TK_CONFIG_ARGV_ONLY - | COMMAND_MASK << mePtr->type); + ConfigureMenuEntry(mePtr, 0, (Tcl_Obj **) NULL); } TkEventuallyRecomputeMenu(menuListPtr); } + for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL; + cleanupPtr = cleanupPtr->nextInstancePtr) { + Tk_FreeSavedOptions(cleanupPtr->errorStructPtr); + ckfree((char *) cleanupPtr->errorStructPtr); + cleanupPtr->errorStructPtr = NULL; + } + return TCL_OK; } + /* *---------------------------------------------------------------------- * - * ConfigureMenuEntry -- + * PostProcessEntry -- * - * This procedure is called to process an argv/argc list in order - * to configure (or reconfigure) one entry in a menu. + * This is called by ConfigureMenuEntry to do all of the configuration + * after Tk_SetOptions is called. This is separate + * so that error handling is easier. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information such as label and accelerator get @@ -1407,55 +1634,29 @@ ConfigureMenu(interp, menuPtr, argc, argv, flags) */ static int -ConfigureMenuEntry(mePtr, argc, argv, flags) - register TkMenuEntry *mePtr; /* Information about menu entry; may - * or may not already have values for - * some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Additional flags to pass to - * Tk_ConfigureWidget. */ +PostProcessEntry(mePtr) + TkMenuEntry *mePtr; /* The entry we are configuring. */ { TkMenu *menuPtr = mePtr->menuPtr; int index = mePtr->index; + char *name; Tk_Image image; /* - * If this entry is a check button or radio button, then remove - * its old trace procedure. - */ - - if ((mePtr->name != NULL) - && ((mePtr->type == CHECK_BUTTON_ENTRY) - || (mePtr->type == RADIO_BUTTON_ENTRY))) { - Tcl_UntraceVar(menuPtr->interp, mePtr->name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, (ClientData) mePtr); - } - - if (menuPtr->tkwin != NULL) { - if (Tk_ConfigureWidget(menuPtr->interp, menuPtr->tkwin, - tkMenuEntryConfigSpecs, argc, argv, (char *) mePtr, - flags | (COMMAND_MASK << mePtr->type)) != TCL_OK) { - return TCL_ERROR; - } - } - - /* * The code below handles special configuration stuff not taken * care of by Tk_ConfigureWidget, such as special processing for * defaults, sizing strings, graphics contexts, etc. */ - if (mePtr->label == NULL) { + if (mePtr->labelPtr == NULL) { mePtr->labelLength = 0; } else { - mePtr->labelLength = strlen(mePtr->label); + Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength); } - if (mePtr->accel == NULL) { + if (mePtr->accelPtr == NULL) { mePtr->accelLength = 0; } else { - mePtr->accelLength = strlen(mePtr->accel); + Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength); } /* @@ -1464,9 +1665,8 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) * cascades have to be updated. */ - if ((mePtr->type == CASCADE_ENTRY) && (mePtr->name != NULL)) { + if ((mePtr->type == CASCADE_ENTRY) && (mePtr->namePtr != NULL)) { TkMenuEntry *cascadeEntryPtr; - TkMenu *cascadeMenuPtr; int alreadyThere; TkMenuReferences *menuRefPtr; char *oldHashKey = NULL; /* Initialization only needed to @@ -1482,19 +1682,18 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) * BUG: We are not recloning for special case #3 yet. */ + name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); if (mePtr->childMenuRefPtr != NULL) { oldHashKey = Tcl_GetHashKey(TkGetMenuHashTable(menuPtr->interp), mePtr->childMenuRefPtr->hashEntryPtr); - if (strcmp(oldHashKey, mePtr->name) != 0) { + if (strcmp(oldHashKey, name) != 0) { UnhookCascadeEntry(mePtr); } } if ((mePtr->childMenuRefPtr == NULL) - || (strcmp(oldHashKey, mePtr->name) != 0)) { - menuRefPtr = TkCreateMenuReferences(menuPtr->interp, - mePtr->name); - cascadeMenuPtr = menuRefPtr->menuPtr; + || (strcmp(oldHashKey, name) != 0)) { + menuRefPtr = TkCreateMenuReferences(menuPtr->interp, name); mePtr->childMenuRefPtr = menuRefPtr; if (menuRefPtr->parentEntryPtr == NULL) { @@ -1531,52 +1730,15 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) return TCL_ERROR; } - if ((mePtr->type == CHECK_BUTTON_ENTRY) - || (mePtr->type == RADIO_BUTTON_ENTRY)) { - char *value; - - if (mePtr->name == NULL) { - mePtr->name = - (char *) ckalloc((unsigned) (mePtr->labelLength + 1)); - strcpy(mePtr->name, (mePtr->label == NULL) ? "" : mePtr->label); - } - if (mePtr->onValue == NULL) { - mePtr->onValue = (char *) ckalloc((unsigned) - (mePtr->labelLength + 1)); - strcpy(mePtr->onValue, (mePtr->label == NULL) ? "" : mePtr->label); - } - - /* - * Select the entry if the associated variable has the - * appropriate value, initialize the variable if it doesn't - * exist, then set a trace on the variable to monitor future - * changes to its value. - */ - - value = Tcl_GetVar(menuPtr->interp, mePtr->name, TCL_GLOBAL_ONLY); - mePtr->entryFlags &= ~ENTRY_SELECTED; - if (value != NULL) { - if (strcmp(value, mePtr->onValue) == 0) { - mePtr->entryFlags |= ENTRY_SELECTED; - } - } else { - Tcl_SetVar(menuPtr->interp, mePtr->name, - (mePtr->type == CHECK_BUTTON_ENTRY) ? mePtr->offValue : "", - TCL_GLOBAL_ONLY); - } - Tcl_TraceVar(menuPtr->interp, mePtr->name, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuVarProc, (ClientData) mePtr); - } - /* * Get the images for the entry, if there are any. Allocate the * new images before freeing the old ones, so that the reference * counts don't go to zero and cause image data to be discarded. */ - if (mePtr->imageString != NULL) { - image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, mePtr->imageString, + if (mePtr->imagePtr != NULL) { + char *imageString = Tcl_GetStringFromObj(mePtr->imagePtr, NULL); + image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, imageString, TkMenuImageProc, (ClientData) mePtr); if (image == NULL) { return TCL_ERROR; @@ -1588,8 +1750,10 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) Tk_FreeImage(mePtr->image); } mePtr->image = image; - if (mePtr->selectImageString != NULL) { - image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, mePtr->selectImageString, + if (mePtr->selectImagePtr != NULL) { + char *selectImageString = Tcl_GetStringFromObj( + mePtr->selectImagePtr, NULL); + image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, selectImageString, TkMenuSelectImageProc, (ClientData) mePtr); if (image == NULL) { return TCL_ERROR; @@ -1602,7 +1766,69 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) } mePtr->selectImage = image; - TkEventuallyRecomputeMenu(menuPtr); + if ((mePtr->type == CHECK_BUTTON_ENTRY) + || (mePtr->type == RADIO_BUTTON_ENTRY)) { + Tcl_Obj *valuePtr; + char *name; + + if (mePtr->namePtr == NULL) { + if (mePtr->labelPtr == NULL) { + mePtr->namePtr = NULL; + } else { + mePtr->namePtr = Tcl_DuplicateObj(mePtr->labelPtr); + Tcl_IncrRefCount(mePtr->namePtr); + } + } + if (mePtr->onValuePtr == NULL) { + if (mePtr->labelPtr == NULL) { + mePtr->onValuePtr = NULL; + } else { + mePtr->onValuePtr = Tcl_DuplicateObj(mePtr->labelPtr); + Tcl_IncrRefCount(mePtr->onValuePtr); + } + } + + /* + * Select the entry if the associated variable has the + * appropriate value, initialize the variable if it doesn't + * exist, then set a trace on the variable to monitor future + * changes to its value. + */ + + if (mePtr->namePtr != NULL) { + valuePtr = Tcl_ObjGetVar2(menuPtr->interp, mePtr->namePtr, NULL, + TCL_GLOBAL_ONLY); + } else { + valuePtr = NULL; + } + mePtr->entryFlags &= ~ENTRY_SELECTED; + if (valuePtr != NULL) { + if (mePtr->onValuePtr != NULL) { + char *value = Tcl_GetStringFromObj(valuePtr, NULL); + char *onValue = Tcl_GetStringFromObj(mePtr->onValuePtr, + NULL); + + + if (strcmp(value, onValue) == 0) { + mePtr->entryFlags |= ENTRY_SELECTED; + } + } + } else { + if (mePtr->namePtr != NULL) { + Tcl_ObjSetVar2(menuPtr->interp, mePtr->namePtr, NULL, + (mePtr->type == CHECK_BUTTON_ENTRY) + ? mePtr->offValuePtr + : Tcl_NewObj(), + TCL_GLOBAL_ONLY); + } + } + if (mePtr->namePtr != NULL) { + name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); + Tcl_TraceVar(menuPtr->interp, name, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, (ClientData) mePtr); + } + } return TCL_OK; } @@ -1610,13 +1836,78 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) /* *---------------------------------------------------------------------- * + * ConfigureMenuEntry -- + * + * This procedure is called to process an argv/argc list in order + * to configure (or reconfigure) one entry in a menu. + * + * Results: + * The return value is a standard Tcl result. If TCL_ERROR is + * returned, then the interp's result contains an error message. + * + * Side effects: + * Configuration information such as label and accelerator get + * set for mePtr; old resources get freed, if there were any. + * + *---------------------------------------------------------------------- + */ + +static int +ConfigureMenuEntry(mePtr, objc, objv) + register TkMenuEntry *mePtr; /* Information about menu entry; may + * or may not already have values for + * some fields. */ + int objc; /* Number of valid entries in argv. */ + Tcl_Obj *CONST objv[]; /* Arguments. */ +{ + TkMenu *menuPtr = mePtr->menuPtr; + Tk_SavedOptions errorStruct; + int result; + + /* + * If this entry is a check button or radio button, then remove + * its old trace procedure. + */ + + if ((mePtr->namePtr != NULL) + && ((mePtr->type == CHECK_BUTTON_ENTRY) + || (mePtr->type == RADIO_BUTTON_ENTRY))) { + char *name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); + Tcl_UntraceVar(menuPtr->interp, name, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, (ClientData) mePtr); + } + + result = TCL_OK; + if (menuPtr->tkwin != NULL) { + if (Tk_SetOptions(menuPtr->interp, (char *) mePtr, + mePtr->optionTable, objc, objv, menuPtr->tkwin, + &errorStruct, (int *) NULL) != TCL_OK) { + return TCL_ERROR; + } + result = PostProcessEntry(mePtr); + if (result != TCL_OK) { + Tk_RestoreSavedOptions(&errorStruct); + PostProcessEntry(mePtr); + } + Tk_FreeSavedOptions(&errorStruct); + } + + TkEventuallyRecomputeMenu(menuPtr); + + return result; +} + +/* + *---------------------------------------------------------------------- + * * ConfigureMenuCloneEntries -- * * Calls ConfigureMenuEntry for each menu in the clone chain. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information such as label and accelerator get @@ -1626,22 +1917,21 @@ ConfigureMenuEntry(mePtr, argc, argv, flags) */ static int -ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) +ConfigureMenuCloneEntries(interp, menuPtr, index, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ TkMenu *menuPtr; /* Information about whole menu. */ int index; /* Index of mePtr within menuPtr's * entries. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Additional flags to pass to - * Tk_ConfigureWidget. */ + int objc; /* Number of valid entries in argv. */ + Tcl_Obj *CONST objv[]; /* Arguments. */ { TkMenuEntry *mePtr; TkMenu *menuListPtr; - char *oldCascadeName = NULL, *newMenuName = NULL; - int cascadeEntryChanged; + int cascadeEntryChanged = 0; TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL; - + Tcl_Obj *oldCascadePtr = NULL; + char *newCascadeName; + /* * Cascades are kind of tricky here. This is special case #3 in the comment * at the top of this file. Basically, if a menu is the master menu of a @@ -1653,21 +1943,47 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) mePtr = menuPtr->masterMenuPtr->entries[index]; if (mePtr->type == CASCADE_ENTRY) { - oldCascadeName = mePtr->name; + oldCascadePtr = mePtr->namePtr; + if (oldCascadePtr != NULL) { + Tcl_IncrRefCount(oldCascadePtr); + } } - if (ConfigureMenuEntry(mePtr, argc, argv, flags) != TCL_OK) { + if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) { return TCL_ERROR; } - cascadeEntryChanged = (mePtr->type == CASCADE_ENTRY) - && (oldCascadeName != mePtr->name); + if (mePtr->type == CASCADE_ENTRY) { + char *oldCascadeName; + + if (mePtr->namePtr != NULL) { + newCascadeName = Tcl_GetStringFromObj(mePtr->namePtr, NULL); + } else { + newCascadeName = NULL; + } + + if ((oldCascadePtr == NULL) && (mePtr->namePtr == NULL)) { + cascadeEntryChanged = 0; + } else if (((oldCascadePtr == NULL) && (mePtr->namePtr != NULL)) + || ((oldCascadePtr != NULL) + && (mePtr->namePtr == NULL))) { + cascadeEntryChanged = 1; + } else { + oldCascadeName = Tcl_GetStringFromObj(oldCascadePtr, + NULL); + cascadeEntryChanged = (strcmp(oldCascadeName, newCascadeName) + == 0); + } + if (oldCascadePtr != NULL) { + Tcl_DecrRefCount(oldCascadePtr); + } + } if (cascadeEntryChanged) { - newMenuName = mePtr->name; - if (newMenuName != NULL) { + if (mePtr->namePtr != NULL) { + newCascadeName = Tcl_GetStringFromObj(mePtr->namePtr, NULL); cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp, - mePtr->name); + newCascadeName); } } @@ -1677,9 +1993,9 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) mePtr = menuListPtr->entries[index]; - if (cascadeEntryChanged && (mePtr->name != NULL)) { - oldCascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp, - mePtr->name); + if (cascadeEntryChanged && (mePtr->namePtr != NULL)) { + oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp, + mePtr->namePtr); if ((oldCascadeMenuRefPtr != NULL) && (oldCascadeMenuRefPtr->menuPtr != NULL)) { @@ -1687,25 +2003,36 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) } } - if (ConfigureMenuEntry(mePtr, argc, argv, flags) != TCL_OK) { + if (ConfigureMenuEntry(mePtr, objc, objv) != TCL_OK) { return TCL_ERROR; } - if (cascadeEntryChanged && (newMenuName != NULL)) { + if (cascadeEntryChanged && (mePtr->namePtr != NULL)) { if (cascadeMenuRefPtr->menuPtr != NULL) { - char *newArgV[2]; - char *newCloneName; - - newCloneName = TkNewMenuName(menuPtr->interp, - Tk_PathName(menuListPtr->tkwin), + Tcl_Obj *newObjv[2]; + Tcl_Obj *newCloneNamePtr; + Tcl_Obj *pathNamePtr = Tcl_NewStringObj( + Tk_PathName(menuListPtr->tkwin), -1); + Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1); + Tcl_Obj *menuObjPtr = Tcl_NewStringObj("-menu", -1); + + Tcl_IncrRefCount(pathNamePtr); + newCloneNamePtr = TkNewMenuName(menuPtr->interp, + pathNamePtr, cascadeMenuRefPtr->menuPtr); - CloneMenu(cascadeMenuRefPtr->menuPtr, newCloneName, - "normal"); - - newArgV[0] = "-menu"; - newArgV[1] = newCloneName; - ConfigureMenuEntry(mePtr, 2, newArgV, flags); - ckfree(newCloneName); + Tcl_IncrRefCount(newCloneNamePtr); + Tcl_IncrRefCount(normalPtr); + CloneMenu(cascadeMenuRefPtr->menuPtr, newCloneNamePtr, + normalPtr); + + newObjv[0] = menuObjPtr; + newObjv[1] = newCloneNamePtr; + Tcl_IncrRefCount(menuObjPtr); + ConfigureMenuEntry(mePtr, 2, newObjv); + Tcl_DecrRefCount(newCloneNamePtr); + Tcl_DecrRefCount(pathNamePtr); + Tcl_DecrRefCount(normalPtr); + Tcl_DecrRefCount(menuObjPtr); } } } @@ -1724,7 +2051,7 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) * A standard Tcl result. If all went well, then *indexPtr is * filled in with the entry index corresponding to string * (ranges from -1 to the number of entries in the menu minus - * one). Otherwise an error message is left in interp->result. + * one). Otherwise an error message is left in the interp's result. * * Side effects: * None. @@ -1733,38 +2060,39 @@ ConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags) */ int -TkGetMenuIndex(interp, menuPtr, string, lastOK, indexPtr) +TkGetMenuIndex(interp, menuPtr, objPtr, lastOK, indexPtr) Tcl_Interp *interp; /* For error messages. */ TkMenu *menuPtr; /* Menu for which the index is being * specified. */ - char *string; /* Specification of an entry in menu. See + Tcl_Obj *objPtr; /* Specification of an entry in menu. See * manual entry for valid .*/ int lastOK; /* Non-zero means its OK to return index * just *after* last entry. */ - int *indexPtr; /* Where to store converted relief. */ + int *indexPtr; /* Where to store converted index. */ { int i; + char *string = Tcl_GetStringFromObj(objPtr, NULL); if ((string[0] == 'a') && (strcmp(string, "active") == 0)) { *indexPtr = menuPtr->active; - return TCL_OK; + goto success; } if (((string[0] == 'l') && (strcmp(string, "last") == 0)) || ((string[0] == 'e') && (strcmp(string, "end") == 0))) { *indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1); - return TCL_OK; + goto success; } if ((string[0] == 'n') && (strcmp(string, "none") == 0)) { *indexPtr = -1; - return TCL_OK; + goto success; } if (string[0] == '@') { if (GetIndexFromCoords(interp, menuPtr, string, indexPtr) == TCL_OK) { - return TCL_OK; + goto success; } } @@ -1780,25 +2108,29 @@ TkGetMenuIndex(interp, menuPtr, string, lastOK, indexPtr) i = -1; } *indexPtr = i; - return TCL_OK; + goto success; } Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); } for (i = 0; i < menuPtr->numEntries; i++) { - char *label; - - label = menuPtr->entries[i]->label; + Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr; + char *label = (labelPtr == NULL) ? NULL + : Tcl_GetStringFromObj(labelPtr, NULL); + if ((label != NULL) - && (Tcl_StringMatch(menuPtr->entries[i]->label, string))) { + && (Tcl_StringMatch(label, string))) { *indexPtr = i; - return TCL_OK; + goto success; } } Tcl_AppendResult(interp, "bad menu entry index \"", string, "\"", (char *) NULL); return TCL_ERROR; + +success: + return TCL_OK; } /* @@ -1834,7 +2166,6 @@ MenuCmdDeletedProc(clientData) */ if (tkwin != NULL) { - menuPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } @@ -1890,41 +2221,49 @@ MenuNewEntry(menuPtr, index, type) mePtr = (TkMenuEntry *) ckalloc(sizeof(TkMenuEntry)); menuPtr->entries[index] = mePtr; mePtr->type = type; + mePtr->optionTable = menuPtr->optionTablesPtr->entryOptionTables[type]; mePtr->menuPtr = menuPtr; - mePtr->label = NULL; + mePtr->labelPtr = NULL; mePtr->labelLength = 0; mePtr->underline = -1; - mePtr->bitmap = None; - mePtr->imageString = NULL; + mePtr->bitmapPtr = NULL; + mePtr->imagePtr = NULL; mePtr->image = NULL; - mePtr->selectImageString = NULL; + mePtr->selectImagePtr = NULL; mePtr->selectImage = NULL; - mePtr->accel = NULL; + mePtr->accelPtr = NULL; mePtr->accelLength = 0; - mePtr->state = tkNormalUid; - mePtr->border = NULL; - mePtr->fg = NULL; - mePtr->activeBorder = NULL; - mePtr->activeFg = NULL; - mePtr->tkfont = NULL; - mePtr->indicatorOn = 1; - mePtr->indicatorFg = NULL; + mePtr->state = ENTRY_DISABLED; + mePtr->borderPtr = NULL; + mePtr->fgPtr = NULL; + mePtr->activeBorderPtr = NULL; + mePtr->activeFgPtr = NULL; + mePtr->fontPtr = NULL; + mePtr->indicatorOn = 0; + mePtr->indicatorFgPtr = NULL; mePtr->columnBreak = 0; mePtr->hideMargin = 0; - mePtr->command = NULL; - mePtr->name = NULL; + mePtr->commandPtr = NULL; + mePtr->namePtr = NULL; mePtr->childMenuRefPtr = NULL; - mePtr->onValue = NULL; - mePtr->offValue = NULL; + mePtr->onValuePtr = NULL; + mePtr->offValuePtr = NULL; mePtr->entryFlags = 0; mePtr->index = index; mePtr->nextCascadePtr = NULL; + if (Tk_InitOptions(menuPtr->interp, (char *) mePtr, + mePtr->optionTable, menuPtr->tkwin) != TCL_OK) { + ckfree((char *) mePtr); + return NULL; + } TkMenuInitializeEntryDrawingFields(mePtr); if (TkpMenuNewEntry(mePtr) != TCL_OK) { + Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable, + menuPtr->tkwin); ckfree((char *) mePtr); return NULL; } - + return mePtr; } @@ -1946,25 +2285,24 @@ MenuNewEntry(menuPtr, index, type) */ static int -MenuAddOrInsert(interp, menuPtr, indexString, argc, argv) +MenuAddOrInsert(interp, menuPtr, indexPtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ TkMenu *menuPtr; /* Widget in which to create new * entry. */ - char *indexString; /* String describing index at which + Tcl_Obj *indexPtr; /* Object describing index at which * to insert. NULL means insert at * end. */ - int argc; /* Number of elements in argv. */ - char **argv; /* Arguments to command: first arg + int objc; /* Number of elements in objv. */ + Tcl_Obj *CONST objv[]; /* Arguments to command: first arg * is type of entry, others are * config options. */ { - int c, type, index; - size_t length; + int type, index; TkMenuEntry *mePtr; TkMenu *menuListPtr; - if (indexString != NULL) { - if (TkGetMenuIndex(interp, menuPtr, indexString, 1, &index) + if (indexPtr != NULL) { + if (TkGetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) { return TCL_ERROR; } @@ -1972,11 +2310,12 @@ MenuAddOrInsert(interp, menuPtr, indexString, argc, argv) index = menuPtr->numEntries; } if (index < 0) { + char *indexString = Tcl_GetStringFromObj(indexPtr, NULL); Tcl_AppendResult(interp, "bad index \"", indexString, "\"", (char *) NULL); return TCL_ERROR; } - if (menuPtr->tearOff && (index == 0)) { + if (menuPtr->tearoff && (index == 0)) { index = 1; } @@ -1984,30 +2323,11 @@ MenuAddOrInsert(interp, menuPtr, indexString, argc, argv) * Figure out the type of the new entry. */ - c = argv[0][0]; - length = strlen(argv[0]); - if ((c == 'c') && (strncmp(argv[0], "cascade", length) == 0) - && (length >= 2)) { - type = CASCADE_ENTRY; - } else if ((c == 'c') && (strncmp(argv[0], "checkbutton", length) == 0) - && (length >= 2)) { - type = CHECK_BUTTON_ENTRY; - } else if ((c == 'c') && (strncmp(argv[0], "command", length) == 0) - && (length >= 2)) { - type = COMMAND_ENTRY; - } else if ((c == 'r') - && (strncmp(argv[0], "radiobutton", length) == 0)) { - type = RADIO_BUTTON_ENTRY; - } else if ((c == 's') - && (strncmp(argv[0], "separator", length) == 0)) { - type = SEPARATOR_ENTRY; - } else { - Tcl_AppendResult(interp, "bad menu entry type \"", - argv[0], "\": must be cascade, checkbutton, ", - "command, radiobutton, or separator", (char *) NULL); + if (Tcl_GetIndexFromObj(interp, objv[0], menuEntryTypeStrings, + "menu entry type", 0, &type) != TCL_OK) { return TCL_ERROR; } - + /* * Now we have to add an entry for every instance related to this menu. */ @@ -2019,9 +2339,9 @@ MenuAddOrInsert(interp, menuPtr, indexString, argc, argv) if (mePtr == NULL) { return TCL_ERROR; } - if (ConfigureMenuEntry(mePtr, argc-1, argv+1, 0) != TCL_OK) { + if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) { TkMenu *errorMenuPtr; - int i; + int i; for (errorMenuPtr = menuPtr->masterMenuPtr; errorMenuPtr != NULL; @@ -2054,28 +2374,40 @@ MenuAddOrInsert(interp, menuPtr, indexString, argc, argv) */ if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) { - if ((mePtr->name != NULL) && (mePtr->childMenuRefPtr != NULL) + if ((mePtr->namePtr != NULL) + && (mePtr->childMenuRefPtr != NULL) && (mePtr->childMenuRefPtr->menuPtr != NULL)) { TkMenu *cascadeMenuPtr = mePtr->childMenuRefPtr->menuPtr->masterMenuPtr; - char *newCascadeName; - char *newArgv[2]; + Tcl_Obj *newCascadePtr; + Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1); + Tcl_Obj *windowNamePtr = + Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1); + Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1); + Tcl_Obj *newObjv[2]; TkMenuReferences *menuRefPtr; - - newCascadeName = TkNewMenuName(menuListPtr->interp, - Tk_PathName(menuListPtr->tkwin), - cascadeMenuPtr); - CloneMenu(cascadeMenuPtr, newCascadeName, "normal"); + + Tcl_IncrRefCount(windowNamePtr); + newCascadePtr = TkNewMenuName(menuListPtr->interp, + windowNamePtr, cascadeMenuPtr); + Tcl_IncrRefCount(newCascadePtr); + Tcl_IncrRefCount(normalPtr); + CloneMenu(cascadeMenuPtr, newCascadePtr, normalPtr); - menuRefPtr = TkFindMenuReferences(menuListPtr->interp, - newCascadeName); + menuRefPtr = TkFindMenuReferencesObj(menuListPtr->interp, + newCascadePtr); if (menuRefPtr == NULL) { panic("CloneMenu failed inside of MenuAddOrInsert."); } - newArgv[0] = "-menu"; - newArgv[1] = newCascadeName; - ConfigureMenuEntry(mePtr, 2, newArgv, 0); - ckfree(newCascadeName); + newObjv[0] = menuNamePtr; + newObjv[1] = newCascadePtr; + Tcl_IncrRefCount(menuNamePtr); + Tcl_IncrRefCount(newCascadePtr); + ConfigureMenuEntry(mePtr, 2, newObjv); + Tcl_DecrRefCount(newCascadePtr); + Tcl_DecrRefCount(menuNamePtr); + Tcl_DecrRefCount(windowNamePtr); + Tcl_DecrRefCount(normalPtr); } } } @@ -2112,6 +2444,8 @@ MenuVarProc(clientData, interp, name1, name2, flags) TkMenuEntry *mePtr = (TkMenuEntry *) clientData; TkMenu *menuPtr; char *value; + char *name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); + char *onValue; menuPtr = mePtr->menuPtr; @@ -2123,7 +2457,7 @@ MenuVarProc(clientData, interp, name1, name2, flags) if (flags & TCL_TRACE_UNSETS) { mePtr->entryFlags &= ~ENTRY_SELECTED; if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_TraceVar(interp, mePtr->name, + Tcl_TraceVar(interp, name, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuVarProc, clientData); } @@ -2137,17 +2471,22 @@ MenuVarProc(clientData, interp, name1, name2, flags) * the menu entry. */ - value = Tcl_GetVar(interp, mePtr->name, TCL_GLOBAL_ONLY); + value = Tcl_GetVar(interp, name, TCL_GLOBAL_ONLY); if (value == NULL) { value = ""; } - if (strcmp(value, mePtr->onValue) == 0) { - if (mePtr->entryFlags & ENTRY_SELECTED) { + if (mePtr->onValuePtr != NULL) { + onValue = Tcl_GetStringFromObj(mePtr->onValuePtr, NULL); + if (strcmp(value, onValue) == 0) { + if (mePtr->entryFlags & ENTRY_SELECTED) { + return (char *) NULL; + } + mePtr->entryFlags |= ENTRY_SELECTED; + } else if (mePtr->entryFlags & ENTRY_SELECTED) { + mePtr->entryFlags &= ~ENTRY_SELECTED; + } else { return (char *) NULL; } - mePtr->entryFlags |= ENTRY_SELECTED; - } else if (mePtr->entryFlags & ENTRY_SELECTED) { - mePtr->entryFlags &= ~ENTRY_SELECTED; } else { return (char *) NULL; } @@ -2193,15 +2532,15 @@ TkActivateMenuEntry(menuPtr, index) * might already have been changed to disabled). */ - if (mePtr->state == tkActiveUid) { - mePtr->state = tkNormalUid; + if (mePtr->state == ENTRY_ACTIVE) { + mePtr->state = ENTRY_NORMAL; } TkEventuallyRedrawMenu(menuPtr, menuPtr->entries[menuPtr->active]); } menuPtr->active = index; if (index >= 0) { mePtr = menuPtr->entries[index]; - mePtr->state = tkActiveUid; + mePtr->state = ENTRY_ACTIVE; TkEventuallyRedrawMenu(menuPtr, mePtr); } return result; @@ -2237,9 +2576,13 @@ TkPostCommand(menuPtr) * the menu's geometry if needed. */ - if (menuPtr->postCommand != NULL) { - result = TkCopyAndGlobalEval(menuPtr->interp, - menuPtr->postCommand); + if (menuPtr->postCommandPtr != NULL) { + Tcl_Obj *postCommandPtr = menuPtr->postCommandPtr; + + Tcl_IncrRefCount(postCommandPtr); + result = Tcl_EvalObjEx(menuPtr->interp, postCommandPtr, + TCL_EVAL_GLOBAL); + Tcl_DecrRefCount(postCommandPtr); if (result != TCL_OK) { return result; } @@ -2269,64 +2612,53 @@ TkPostCommand(menuPtr) */ static int -CloneMenu(menuPtr, newMenuName, newMenuTypeString) +CloneMenu(menuPtr, newMenuNamePtr, newMenuTypePtr) TkMenu *menuPtr; /* The menu we are going to clone */ - char *newMenuName; /* The name to give the new menu */ - char *newMenuTypeString; /* What kind of menu is this, a normal menu + Tcl_Obj *newMenuNamePtr; /* The name to give the new menu */ + Tcl_Obj *newMenuTypePtr; /* What kind of menu is this, a normal menu * a menubar, or a tearoff? */ { int returnResult; - int menuType; - size_t length; + int menuType, i; TkMenuReferences *menuRefPtr; - Tcl_Obj *commandObjPtr; + Tcl_Obj *menuDupCommandArray[4]; - if (newMenuTypeString == NULL) { + if (newMenuTypePtr == NULL) { menuType = MASTER_MENU; } else { - length = strlen(newMenuTypeString); - if (strncmp(newMenuTypeString, "normal", length) == 0) { - menuType = MASTER_MENU; - } else if (strncmp(newMenuTypeString, "tearoff", length) == 0) { - menuType = TEAROFF_MENU; - } else if (strncmp(newMenuTypeString, "menubar", length) == 0) { - menuType = MENUBAR; - } else { - Tcl_AppendResult(menuPtr->interp, - "bad menu type - must be normal, tearoff, or menubar", - (char *) NULL); - return TCL_ERROR; - } + if (Tcl_GetIndexFromObj(menuPtr->interp, newMenuTypePtr, + menuTypeStrings, "menu type", 0, &menuType) != TCL_OK) { + return TCL_ERROR; + } } - commandObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); - Tcl_ListObjAppendElement(menuPtr->interp, commandObjPtr, - Tcl_NewStringObj("tkMenuDup", -1)); - Tcl_ListObjAppendElement(menuPtr->interp, commandObjPtr, - Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1)); - Tcl_ListObjAppendElement(menuPtr->interp, commandObjPtr, - Tcl_NewStringObj(newMenuName, -1)); - if ((newMenuTypeString == NULL) || (newMenuTypeString[0] == '\0')) { - Tcl_ListObjAppendElement(menuPtr->interp, commandObjPtr, - Tcl_NewStringObj("normal", -1)); + menuDupCommandArray[0] = Tcl_NewStringObj("tkMenuDup", -1); + menuDupCommandArray[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1); + menuDupCommandArray[2] = newMenuNamePtr; + if (newMenuTypePtr == NULL) { + menuDupCommandArray[3] = Tcl_NewStringObj("normal", -1); } else { - Tcl_ListObjAppendElement(menuPtr->interp, commandObjPtr, - Tcl_NewStringObj(newMenuTypeString, -1)); + menuDupCommandArray[3] = newMenuTypePtr; + } + for (i = 0; i < 4; i++) { + Tcl_IncrRefCount(menuDupCommandArray[i]); } - Tcl_IncrRefCount(commandObjPtr); Tcl_Preserve((ClientData) menuPtr); - returnResult = Tcl_EvalObj(menuPtr->interp, commandObjPtr); - Tcl_DecrRefCount(commandObjPtr); + returnResult = Tcl_EvalObjv(menuPtr->interp, 4, menuDupCommandArray, 0); + for (i = 0; i < 4; i++) { + Tcl_DecrRefCount(menuDupCommandArray[i]); + } /* * Make sure the tcl command actually created the clone. */ if ((returnResult == TCL_OK) && - ((menuRefPtr = TkFindMenuReferences(menuPtr->interp, newMenuName)) - != (TkMenuReferences *) NULL) + ((menuRefPtr = TkFindMenuReferencesObj(menuPtr->interp, + newMenuNamePtr)) != (TkMenuReferences *) NULL) && (menuPtr->numEntries == menuRefPtr->menuPtr->numEntries)) { TkMenu *newMenuPtr = menuRefPtr->menuPtr; + Tcl_Obj *newObjv[3]; char *newArgv[3]; int i, numElements; @@ -2359,8 +2691,8 @@ CloneMenu(menuPtr, newMenuName, newMenuTypeString) if (Tk_BindtagsCmd((ClientData)newMenuPtr->tkwin, newMenuPtr->interp, 2, newArgv) == TCL_OK) { char *windowName; - Tcl_Obj *bindingsPtr = - Tcl_NewStringObj(newMenuPtr->interp->result, -1); + Tcl_Obj *bindingsPtr = + Tcl_DuplicateObj(Tcl_GetObjResult(newMenuPtr->interp)); Tcl_Obj *elementPtr; Tcl_ListObjLength(newMenuPtr->interp, bindingsPtr, &numElements); @@ -2372,11 +2704,12 @@ CloneMenu(menuPtr, newMenuName, newMenuTypeString) == 0) { Tcl_Obj *newElementPtr = Tcl_NewStringObj( Tk_PathName(newMenuPtr->masterMenuPtr->tkwin), -1); + Tcl_IncrRefCount(newElementPtr); Tcl_ListObjReplace(menuPtr->interp, bindingsPtr, i + 1, 0, 1, &newElementPtr); newArgv[2] = Tcl_GetStringFromObj(bindingsPtr, NULL); - Tk_BindtagsCmd((ClientData)newMenuPtr->tkwin, - menuPtr->interp, 3, newArgv); + Tk_BindtagsCmd((ClientData)newMenuPtr->tkwin, + menuPtr->interp, 3, newArgv); break; } } @@ -2389,30 +2722,35 @@ CloneMenu(menuPtr, newMenuName, newMenuTypeString) */ for (i = 0; i < menuPtr->numEntries; i++) { - char *newCascadeName; TkMenuReferences *cascadeRefPtr; TkMenu *oldCascadePtr; if ((menuPtr->entries[i]->type == CASCADE_ENTRY) - && (menuPtr->entries[i]->name != NULL)) { + && (menuPtr->entries[i]->namePtr != NULL)) { cascadeRefPtr = - TkFindMenuReferences(menuPtr->interp, - menuPtr->entries[i]->name); + TkFindMenuReferencesObj(menuPtr->interp, + menuPtr->entries[i]->namePtr); if ((cascadeRefPtr != NULL) && (cascadeRefPtr->menuPtr)) { - char *nameString; + Tcl_Obj *windowNamePtr = + Tcl_NewStringObj(Tk_PathName(newMenuPtr->tkwin), + -1); + Tcl_Obj *newCascadePtr; oldCascadePtr = cascadeRefPtr->menuPtr; - nameString = Tk_PathName(newMenuPtr->tkwin); - newCascadeName = TkNewMenuName(menuPtr->interp, - nameString, oldCascadePtr); - CloneMenu(oldCascadePtr, newCascadeName, NULL); - - newArgv[0] = "-menu"; - newArgv[1] = newCascadeName; - ConfigureMenuEntry(newMenuPtr->entries[i], 2, newArgv, - TK_CONFIG_ARGV_ONLY); - ckfree(newCascadeName); + Tcl_IncrRefCount(windowNamePtr); + newCascadePtr = TkNewMenuName(menuPtr->interp, + windowNamePtr, oldCascadePtr); + Tcl_IncrRefCount(newCascadePtr); + CloneMenu(oldCascadePtr, newCascadePtr, NULL); + + newObjv[0] = Tcl_NewStringObj("-menu", -1); + newObjv[1] = newCascadePtr; + Tcl_IncrRefCount(newObjv[0]); + ConfigureMenuEntry(newMenuPtr->entries[i], 2, newObjv); + Tcl_DecrRefCount(newObjv[0]); + Tcl_DecrRefCount(newCascadePtr); + Tcl_DecrRefCount(windowNamePtr); } } } @@ -2442,22 +2780,24 @@ CloneMenu(menuPtr, newMenuName, newMenuTypeString) */ static int -MenuDoYPosition(interp, menuPtr, arg) +MenuDoYPosition(interp, menuPtr, objPtr) Tcl_Interp *interp; TkMenu *menuPtr; - char *arg; + Tcl_Obj *objPtr; { int index; TkRecomputeMenu(menuPtr); - if (TkGetMenuIndex(interp, menuPtr, arg, 0, &index) != TCL_OK) { + if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) { goto error; } + Tcl_ResetResult(interp); if (index < 0) { - interp->result = "0"; + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); } else { - sprintf(interp->result, "%d", menuPtr->entries[index]->y); + Tcl_SetObjResult(interp, Tcl_NewIntObj(menuPtr->entries[index]->y)); } + return TCL_OK; error: @@ -2507,7 +2847,8 @@ GetIndexFromCoords(interp, menuPtr, string, indexPtr) goto error; } } else { - x = menuPtr->borderWidth; + Tk_GetPixelsFromObj(interp, menuPtr->tkwin, + menuPtr->borderWidthPtr, &x); } for (i = 0; i < menuPtr->numEntries; i++) { @@ -2583,65 +2924,66 @@ RecursivelyDeleteMenu(menuPtr) *---------------------------------------------------------------------- */ -char * -TkNewMenuName(interp, parentName, menuPtr) +Tcl_Obj * +TkNewMenuName(interp, parentPtr, menuPtr) Tcl_Interp *interp; /* The interp the new name has to live in.*/ - char *parentName; /* The prefix path of the new name. */ + Tcl_Obj *parentPtr; /* The prefix path of the new name. */ TkMenu *menuPtr; /* The menu we are cloning. */ { - Tcl_DString resultDString; - Tcl_DString childDString; + Tcl_Obj *resultPtr = NULL; /* Initialization needed only to prevent + * compiler warning. */ + Tcl_Obj *childPtr; char *destString; - int offset, i; - int doDot = parentName[strlen(parentName) - 1] != '.'; + int i; + int doDot; Tcl_CmdInfo cmdInfo; - char *returnString; Tcl_HashTable *nameTablePtr = NULL; TkWindow *winPtr = (TkWindow *) menuPtr->tkwin; + char *parentName = Tcl_GetStringFromObj(parentPtr, NULL); + if (winPtr->mainPtr != NULL) { nameTablePtr = &(winPtr->mainPtr->nameTable); } - - Tcl_DStringInit(&childDString); - Tcl_DStringAppend(&childDString, Tk_PathName(menuPtr->tkwin), -1); - for (destString = Tcl_DStringValue(&childDString); + + doDot = parentName[strlen(parentName) - 1] != '.'; + + childPtr = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin), -1); + for (destString = Tcl_GetStringFromObj(childPtr, NULL); *destString != '\0'; destString++) { if (*destString == '.') { *destString = '#'; } } - offset = 0; - for (i = 0; ; i++) { if (i == 0) { - Tcl_DStringInit(&resultDString); - Tcl_DStringAppend(&resultDString, parentName, -1); + resultPtr = Tcl_DuplicateObj(parentPtr); if (doDot) { - Tcl_DStringAppend(&resultDString, ".", -1); + Tcl_AppendToObj(resultPtr, ".", -1); } - Tcl_DStringAppend(&resultDString, - Tcl_DStringValue(&childDString), -1); - destString = Tcl_DStringValue(&resultDString); + Tcl_AppendObjToObj(resultPtr, childPtr); } else { - if (i == 1) { - offset = Tcl_DStringLength(&resultDString); - Tcl_DStringSetLength(&resultDString, offset + 10); - destString = Tcl_DStringValue(&resultDString); - } - sprintf(destString + offset, "%d", i); + Tcl_Obj *intPtr; + + Tcl_DecrRefCount(resultPtr); + resultPtr = Tcl_DuplicateObj(parentPtr); + if (doDot) { + Tcl_AppendToObj(resultPtr, ".", -1); + } + Tcl_AppendObjToObj(resultPtr, childPtr); + intPtr = Tcl_NewIntObj(i); + Tcl_AppendObjToObj(resultPtr, intPtr); + Tcl_DecrRefCount(intPtr); } + destString = Tcl_GetStringFromObj(resultPtr, NULL); if ((Tcl_GetCommandInfo(interp, destString, &cmdInfo) == 0) && ((nameTablePtr == NULL) || (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) { break; } } - returnString = ckalloc(strlen(destString) + 1); - strcpy(returnString, destString); - Tcl_DStringFree(&resultDString); - Tcl_DStringFree(&childDString); - return returnString; + Tcl_DecrRefCount(childPtr); + return resultPtr; } /* @@ -2756,32 +3098,45 @@ TkSetWindowMenuBar(interp, tkwin, oldMenuName, menuName) menuPtr = menuRefPtr->menuPtr; if (menuPtr != NULL) { - char *cloneMenuName; + Tcl_Obj *cloneMenuPtr; TkMenuReferences *cloneMenuRefPtr; - char *newArgv[4]; + Tcl_Obj *newObjv[4]; + Tcl_Obj *windowNamePtr = Tcl_NewStringObj(Tk_PathName(tkwin), + -1); + Tcl_Obj *menubarPtr = Tcl_NewStringObj("menubar", -1); /* * Clone the menu and all of the cascades underneath it. */ - cloneMenuName = TkNewMenuName(interp, Tk_PathName(tkwin), + Tcl_IncrRefCount(windowNamePtr); + cloneMenuPtr = TkNewMenuName(interp, windowNamePtr, menuPtr); - CloneMenu(menuPtr, cloneMenuName, "menubar"); + Tcl_IncrRefCount(cloneMenuPtr); + Tcl_IncrRefCount(menubarPtr); + CloneMenu(menuPtr, cloneMenuPtr, menubarPtr); - cloneMenuRefPtr = TkFindMenuReferences(interp, cloneMenuName); + cloneMenuRefPtr = TkFindMenuReferencesObj(interp, cloneMenuPtr); if ((cloneMenuRefPtr != NULL) && (cloneMenuRefPtr->menuPtr != NULL)) { + Tcl_Obj *cursorPtr = Tcl_NewStringObj("-cursor", -1); + Tcl_Obj *nullPtr = Tcl_NewObj(); cloneMenuRefPtr->menuPtr->parentTopLevelPtr = tkwin; menuBarPtr = cloneMenuRefPtr->menuPtr; - newArgv[0] = "-cursor"; - newArgv[1] = ""; + newObjv[0] = cursorPtr; + newObjv[1] = nullPtr; + Tcl_IncrRefCount(cursorPtr); + Tcl_IncrRefCount(nullPtr); ConfigureMenu(menuPtr->interp, cloneMenuRefPtr->menuPtr, - 2, newArgv, TK_CONFIG_ARGV_ONLY); + 2, newObjv); + Tcl_DecrRefCount(cursorPtr); + Tcl_DecrRefCount(nullPtr); } TkpSetWindowMenuBar(tkwin, menuBarPtr); - - ckfree(cloneMenuName); + Tcl_DecrRefCount(cloneMenuPtr); + Tcl_DecrRefCount(menubarPtr); + Tcl_DecrRefCount(windowNamePtr); } else { TkpSetWindowMenuBar(tkwin, NULL); } @@ -2948,6 +3303,35 @@ TkFindMenuReferences(interp, pathName) /* *---------------------------------------------------------------------- * + * TkFindMenuReferencesObj -- + * + * Given a pathname, gives back a pointer to the TkMenuReferences + * structure. + * + * Results: + * Returns a pointer to a menu reference structure. Should not + * be freed by calller; when a field of the reference is cleared, + * TkFreeMenuReferences should be called. Returns NULL if no reference + * with this pathname exists. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TkMenuReferences * +TkFindMenuReferencesObj(interp, objPtr) + Tcl_Interp *interp; /* The interp the menu is living in. */ + Tcl_Obj *objPtr; /* The path of the menu widget */ +{ + char *pathName = Tcl_GetStringFromObj(objPtr, NULL); + return TkFindMenuReferences(interp, pathName); +} + +/* + *---------------------------------------------------------------------- + * * TkFreeMenuReferences -- * * This is called after one of the fields in a menu reference @@ -3050,8 +3434,19 @@ DeleteMenuCloneEntries(menuPtr, first, last) void TkMenuInit() { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + if (!menusInitialized) { - TkpMenuInit(); - menusInitialized = 1; + Tcl_MutexLock(&menuMutex); + if (!menusInitialized) { + TkpMenuInit(); + menusInitialized = 1; + } + Tcl_MutexUnlock(&menuMutex); + } + if (!tsdPtr->menusInitialized) { + TkpMenuThreadInit(); + tsdPtr->menusInitialized = 1; } } diff --git a/generic/tkMenu.h b/generic/tkMenu.h index c6fd3fe..9ec63f4 100644 --- a/generic/tkMenu.h +++ b/generic/tkMenu.h @@ -3,12 +3,12 @@ * * Declarations shared among all of the files that implement menu widgets. * - * Copyright (c) 1996-1997 by Sun Microsystems, Inc. + * Copyright (c) 1996-1998 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenu.h,v 1.4 1998/09/14 18:23:14 stanton Exp $ + * RCS: @(#) $Id: tkMenu.h,v 1.5 1999/04/16 01:51:19 stanton Exp $ */ #ifndef _TKMENU @@ -47,66 +47,72 @@ typedef struct TkMenuEntry { int type; /* Type of menu entry; see below for * valid types. */ struct TkMenu *menuPtr; /* Menu with which this entry is associated. */ - char *label; /* Main text label displayed in entry (NULL - * if no label). Malloc'ed. */ + Tk_OptionTable optionTable; /* Option table for this menu entry. */ + Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL + * if no label). */ int labelLength; /* Number of non-NULL characters in label. */ - Tk_Uid state; /* State of button for display purposes: + int state; /* State of button for display purposes: * normal, active, or disabled. */ - int underline; /* Index of character to underline. */ - Pixmap bitmap; /* Bitmap to display in menu entry, or None. + int underline; /* Value of -underline option: specifies index + * of character to underline (<0 means don't + * underline anything). */ + Tcl_Obj *underlinePtr; /* Index of character to underline. */ + Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or None. * If not None then label is ignored. */ - char *imageString; /* Name of image to display (malloc'ed), or + Tcl_Obj *imagePtr; /* Name of image to display, or * NULL. If non-NULL, bitmap, text, and * textVarName are ignored. */ Tk_Image image; /* Image to display in menu entry, or NULL if * none. */ - char *selectImageString; /* Name of image to display when selected - * (malloc'ed), or NULL. */ + Tcl_Obj *selectImagePtr; /* Name of image to display when selected, or + * NULL. */ Tk_Image selectImage; /* Image to display in entry when selected, * or NULL if none. Ignored if image is * NULL. */ - char *accel; /* Accelerator string displayed at right + Tcl_Obj *accelPtr; /* Accelerator string displayed at right * of menu entry. NULL means no such * accelerator. Malloc'ed. */ int accelLength; /* Number of non-NULL characters in * accelerator. */ int indicatorOn; /* True means draw indicator, false means - * don't draw it. */ + * don't draw it. This field is ignored unless + * the entry is a radio or check button. */ /* * Display attributes */ - Tk_3DBorder border; /* Structure used to draw background for + Tcl_Obj *borderPtr; /* Structure used to draw background for * entry. NULL means use overall border * for menu. */ - XColor *fg; /* Foreground color to use for entry. NULL + Tcl_Obj *fgPtr; /* Foreground color to use for entry. NULL * means use foreground color from menu. */ - Tk_3DBorder activeBorder; /* Used to draw background and border when + Tcl_Obj *activeBorderPtr; /* Used to draw background and border when * element is active. NULL means use * activeBorder from menu. */ - XColor *activeFg; /* Foreground color to use when entry is + Tcl_Obj *activeFgPtr; /* Foreground color to use when entry is * active. NULL means use active foreground * from menu. */ - XColor *indicatorFg; /* Color for indicators in radio and check + Tcl_Obj *indicatorFgPtr; /* Color for indicators in radio and check * button entries. NULL means use indicatorFg * GC from menu. */ - Tk_Font tkfont; /* Text font for menu entries. NULL means + Tcl_Obj *fontPtr; /* Text font for menu entries. NULL means * use overall font for menu. */ int columnBreak; /* If this is 0, this item appears below * the item in front of it. If this is - * 1, this item starts a new column. */ + * 1, this item starts a new column. This + * field is always 0 for tearoff and separator + * entries. */ int hideMargin; /* If this is 0, then the item has enough - * margin to accomodate a standard check - * mark and a default right margin. If this - * is 1, then the item has no such margins. - * and checkbuttons and radiobuttons with - * this set will have a rectangle drawn - * in the indicator around the item if - * the item is checked. - * This is useful palette menus.*/ + * margin to accomodate a standard check mark + * and a default right margin. If this is 1, + * then the item has no such margins. and + * checkbuttons and radiobuttons with this set + * will have a rectangle drawn in the indicator + * around the item if the item is checked. This + * is useful for palette menus. This field is + * ignored for separators and tearoffs. */ int indicatorSpace; /* The width of the indicator space for this - * entry. - */ + * entry. */ int labelWidth; /* Number of pixels to allow for displaying * labels in menu entries. */ @@ -114,15 +120,15 @@ typedef struct TkMenuEntry { * Information used to implement this entry's action: */ - char *command; /* Command to invoke when entry is invoked. + Tcl_Obj *commandPtr; /* Command to invoke when entry is invoked. * Malloc'ed. */ - char *name; /* Name of variable (for check buttons and + Tcl_Obj *namePtr; /* Name of variable (for check buttons and * radio buttons) or menu (for cascade * entries). Malloc'ed.*/ - char *onValue; /* Value to store in variable when selected + Tcl_Obj *onValuePtr; /* Value to store in variable when selected * (only for radio and check buttons). * Malloc'ed. */ - char *offValue; /* Value to store in variable when not + Tcl_Obj *offValuePtr; /* Value to store in variable when not * selected (only for check buttons). * Malloc'ed. */ @@ -179,7 +185,7 @@ typedef struct TkMenuEntry { * does not yet exist. */ TkMenuPlatformEntryData platformEntryData; /* The data for the specific type of menu. - * Depends on platform and menu type what + * Depends on platform and menu type what * kind of options are in this structure. */ } TkMenuEntry; @@ -191,9 +197,9 @@ typedef struct TkMenuEntry { * button and that it should be drawn in * the "selected" state. * ENTRY_NEEDS_REDISPLAY: Non-zero means the entry should be redisplayed. - * ENTRY_LAST_COLUMN: Used by the drawing code. If the entry is in the - * last column, the space to its right needs to - * be filled. + * ENTRY_LAST_COLUMN: Used by the drawing code. If the entry is in + * the last column, the space to its right needs + * to be filled. * ENTRY_PLATFORM_FLAG1 - 4 These flags are reserved for use by the * platform-dependent implementation of menus * and should not be used by anything else. @@ -211,25 +217,22 @@ typedef struct TkMenuEntry { * Types defined for MenuEntries: */ -#define COMMAND_ENTRY 0 -#define SEPARATOR_ENTRY 1 -#define CHECK_BUTTON_ENTRY 2 -#define RADIO_BUTTON_ENTRY 3 -#define CASCADE_ENTRY 4 -#define TEAROFF_ENTRY 5 +#define CASCADE_ENTRY 0 +#define CHECK_BUTTON_ENTRY 1 +#define COMMAND_ENTRY 2 +#define RADIO_BUTTON_ENTRY 3 +#define SEPARATOR_ENTRY 4 +#define TEAROFF_ENTRY 5 /* - * Mask bits for above types: + * Menu states */ -#define COMMAND_MASK TK_CONFIG_USER_BIT -#define SEPARATOR_MASK (TK_CONFIG_USER_BIT << 1) -#define CHECK_BUTTON_MASK (TK_CONFIG_USER_BIT << 2) -#define RADIO_BUTTON_MASK (TK_CONFIG_USER_BIT << 3) -#define CASCADE_MASK (TK_CONFIG_USER_BIT << 4) -#define TEAROFF_MASK (TK_CONFIG_USER_BIT << 5) -#define ALL_MASK (COMMAND_MASK | SEPARATOR_MASK \ - | CHECK_BUTTON_MASK | RADIO_BUTTON_MASK | CASCADE_MASK | TEAROFF_MASK) +EXTERN char *tkMenuStateStrings[]; + +#define ENTRY_ACTIVE 0 +#define ENTRY_NORMAL 1 +#define ENTRY_DISABLED 2 /* * A data structure of the following type is kept for each @@ -253,7 +256,7 @@ typedef struct TkMenu { * nothing active. */ int menuType; /* MASTER_MENU, TEAROFF_MENU, or MENUBAR. * See below for definitions. */ - char *menuTypeName; /* Used to control whether created tkwin + Tcl_Obj *menuTypePtr; /* Used to control whether created tkwin * is a toplevel or not. "normal", "menubar", * or "toplevel" */ @@ -261,20 +264,21 @@ typedef struct TkMenu { * Information used when displaying widget: */ - Tk_3DBorder border; /* Structure used to draw 3-D + Tcl_Obj *borderPtr; /* Structure used to draw 3-D * border and background for menu. */ - int borderWidth; /* Width of border around whole menu. */ - Tk_3DBorder activeBorder; /* Used to draw background and border for + Tcl_Obj *borderWidthPtr; /* Width of border around whole menu. */ + Tcl_Obj *activeBorderPtr; /* Used to draw background and border for * active element (if any). */ - int activeBorderWidth; /* Width of border around active element. */ - int relief; /* 3-d effect: TK_RELIEF_RAISED, etc. */ - Tk_Font tkfont; /* Text font for menu entries. */ - XColor *fg; /* Foreground color for entries. */ - XColor *disabledFg; /* Foreground color when disabled. NULL + Tcl_Obj *activeBorderWidthPtr; + /* Width of border around active element. */ + Tcl_Obj *reliefPtr; /* 3-d effect: TK_RELIEF_RAISED, etc. */ + Tcl_Obj *fontPtr; /* Text font for menu entries. */ + Tcl_Obj *fgPtr; /* Foreground color for entries. */ + Tcl_Obj *disabledFgPtr; /* Foreground color when disabled. NULL * means use normalFg with a 50% stipple * instead. */ - XColor *activeFg; /* Foreground color for active entry. */ - XColor *indicatorFg; /* Color for indicators in radio and check + Tcl_Obj *activeFgPtr; /* Foreground color for active entry. */ + Tcl_Obj *indicatorFgPtr; /* Color for indicators in radio and check * button entries. */ Pixmap gray; /* Bitmap for drawing disabled entries in * a stippled fashion. None means not @@ -305,7 +309,7 @@ typedef struct TkMenu { * Miscellaneous information: */ - int tearOff; /* 1 means this menu can be torn off. On some + int tearoff; /* 1 means this menu can be torn off. On some * platforms, the user can drag an outline * of the menu by just dragging outside of * the menu, and the tearoff is created where @@ -313,17 +317,17 @@ typedef struct TkMenu { * indicator (such as a dashed stripe) is * drawn, and when the menu is selected, the * tearoff is created. */ - char *title; /* The title to use when this menu is torn + Tcl_Obj *titlePtr; /* The title to use when this menu is torn * off. If this is NULL, a default scheme * will be used to generate a title for * tearoff. */ - char *tearOffCommand; /* If non-NULL, points to a command to + Tcl_Obj *tearoffCommandPtr; /* If non-NULL, points to a command to * run whenever the menu is torn-off. */ - char *takeFocus; /* Value of -takefocus option; not used in + Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal * scripts. Malloc'ed, but may be NULL. */ - Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *postCommand; /* Used to detect cycles in cascade hierarchy + Tcl_Obj *cursorPtr; /* Current cursor for window, or None. */ + Tcl_Obj *postCommandPtr; /* Used to detect cycles in cascade hierarchy * trees when preprocessing postcommands * on some platforms. See PostMenu for * more details. */ @@ -341,6 +345,9 @@ typedef struct TkMenu { /* A pointer to the original menu for this * clone chain. Points back to this structure * if this menu is a master menu. */ + struct TkMenuOptionTables *optionTablesPtr; + /* A pointer to the collection of option tables + * that work with menus and menu entries. */ Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the * toplevel that owns the menu. Only applicable * for menubar clones. @@ -360,6 +367,13 @@ typedef struct TkMenu { * Depends on platform and menu type what * kind of options are in this structure. */ + Tk_OptionSpec *extensionPtr; + /* Needed by the configuration package for + * this widget to be extended. */ + Tk_SavedOptions *errorStructPtr; + /* We actually have to allocate these because + * multiple menus get changed during one + * ConfigureMenu call. */ } TkMenu; /* @@ -407,6 +421,16 @@ typedef struct TkMenuReferences { } TkMenuReferences; /* + * This structure contains all of the option tables that are needed + * by menus. + */ + +typedef struct TkMenuOptionTables { + Tk_OptionTable menuOptionTable; /* The option table for menus. */ + Tk_OptionTable entryOptionTables[6];/* The tables for menu entries. */ +} TkMenuOptionTables; + +/* * Flag bits for menus: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler @@ -453,13 +477,6 @@ typedef struct TkMenuReferences { #define DECORATION_BORDER_WIDTH 2 /* - * Configuration specs. Needed for platform-specific default initializations. - */ - -EXTERN Tk_ConfigSpec tkMenuEntryConfigSpecs[]; -EXTERN Tk_ConfigSpec tkMenuConfigSpecs[]; - -/* * Menu-related procedures that are shared among Tk modules but not exported * to the outside world: */ @@ -470,21 +487,26 @@ EXTERN void TkBindMenu _ANSI_ARGS_(( Tk_Window tkwin, TkMenu *menuPtr)); EXTERN TkMenuReferences * TkCreateMenuReferences _ANSI_ARGS_((Tcl_Interp *interp, - char *pathName)); + char *name)); EXTERN void TkDestroyMenu _ANSI_ARGS_((TkMenu *menuPtr)); -EXTERN void TkEventuallyRecomputeMenu _ANSI_ARGS_((TkMenu *menuPtr)); +EXTERN void TkEventuallyRecomputeMenu _ANSI_ARGS_(( + TkMenu *menuPtr)); EXTERN void TkEventuallyRedrawMenu _ANSI_ARGS_(( TkMenu *menuPtr, TkMenuEntry *mePtr)); EXTERN TkMenuReferences * TkFindMenuReferences _ANSI_ARGS_((Tcl_Interp *interp, - char *pathName)); + char *name)); +EXTERN TkMenuReferences * + TkFindMenuReferencesObj _ANSI_ARGS_(( + Tcl_Interp *interp, Tcl_Obj *namePtr)); EXTERN void TkFreeMenuReferences _ANSI_ARGS_(( TkMenuReferences *menuRefPtr)); EXTERN Tcl_HashTable * TkGetMenuHashTable _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN int TkGetMenuIndex _ANSI_ARGS_((Tcl_Interp *interp, - TkMenu *menuPtr, char *string, int lastOK, + TkMenu *menuPtr, Tcl_Obj *objPtr, int lastOK, int *indexPtr)); -EXTERN void TkMenuInitializeDrawingFields _ANSI_ARGS_((TkMenu *menuPtr)); +EXTERN void TkMenuInitializeDrawingFields _ANSI_ARGS_(( + TkMenu *menuPtr)); EXTERN void TkMenuInitializeEntryDrawingFields _ANSI_ARGS_(( TkMenuEntry *mePtr)); EXTERN int TkInvokeMenu _ANSI_ARGS_((Tcl_Interp *interp, @@ -506,8 +528,8 @@ EXTERN void TkMenuSelectImageProc _ANSI_ARGS_ ((ClientData clientData, int x, int y, int width, int height, int imgWidth, int imgHeight)); -EXTERN char * TkNewMenuName _ANSI_ARGS_((Tcl_Interp *interp, - char *parentName, TkMenu *menuPtr)); +EXTERN Tcl_Obj * TkNewMenuName _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *parentNamePtr, TkMenu *menuPtr)); EXTERN int TkPostCommand _ANSI_ARGS_((TkMenu *menuPtr)); EXTERN int TkPostSubmenu _ANSI_ARGS_((Tcl_Interp *interp, TkMenu *menuPtr, TkMenuEntry *mePtr)); @@ -521,7 +543,8 @@ EXTERN void TkRecomputeMenu _ANSI_ARGS_((TkMenu *menuPtr)); * common code. */ -EXTERN void TkpComputeMenubarGeometry _ANSI_ARGS_((TkMenu *menuPtr)); +EXTERN void TkpComputeMenubarGeometry _ANSI_ARGS_(( + TkMenu *menuPtr)); EXTERN void TkpComputeStandardMenuGeometry _ANSI_ARGS_ ((TkMenu *menuPtr)); EXTERN int TkpConfigureMenuEntry diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c index c08e902..42cdf43 100644 --- a/generic/tkMenuDraw.c +++ b/generic/tkMenuDraw.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenuDraw.c,v 1.2 1998/09/14 18:23:14 stanton Exp $ + * RCS: @(#) $Id: tkMenuDraw.c,v 1.3 1999/04/16 01:51:19 stanton Exp $ */ #include "tkMenu.h" @@ -31,7 +31,7 @@ static void DisplayMenu _ANSI_ARGS_((ClientData clientData)); * TkMenuInitializeDrawingFields -- * * Fills in drawing fields of a new menu. Called when new menu is - * created by Tk_MenuCmd. + * created by MenuCmd. * * Results: * None. @@ -188,6 +188,9 @@ TkMenuConfigureDrawOptions(menuPtr) XGCValues gcValues; GC newGC; unsigned long mask; + Tk_3DBorder border, activeBorder; + Tk_Font tkfont; + XColor *fg, *activeFg, *indicatorFg; /* * A few options need special processing, such as setting the @@ -195,11 +198,14 @@ TkMenuConfigureDrawOptions(menuPtr) * defaults that couldn't be specified to Tk_ConfigureWidget. */ - Tk_SetBackgroundFromBorder(menuPtr->tkwin, menuPtr->border); + border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); + Tk_SetBackgroundFromBorder(menuPtr->tkwin, border); - gcValues.font = Tk_FontId(menuPtr->tkfont); - gcValues.foreground = menuPtr->fg->pixel; - gcValues.background = Tk_3DBorderColor(menuPtr->border)->pixel; + tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + gcValues.font = Tk_FontId(tkfont); + fg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->fgPtr); + gcValues.foreground = fg->pixel; + gcValues.background = Tk_3DBorderColor(border)->pixel; newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, &gcValues); if (menuPtr->textGC != None) { @@ -207,17 +213,21 @@ TkMenuConfigureDrawOptions(menuPtr) } menuPtr->textGC = newGC; - gcValues.font = Tk_FontId(menuPtr->tkfont); - gcValues.background = Tk_3DBorderColor(menuPtr->border)->pixel; - if (menuPtr->disabledFg != NULL) { - gcValues.foreground = menuPtr->disabledFg->pixel; + gcValues.font = Tk_FontId(tkfont); + gcValues.background = Tk_3DBorderColor(border)->pixel; + if (menuPtr->disabledFgPtr != NULL) { + XColor *disabledFg; + + disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, + menuPtr->disabledFgPtr); + gcValues.foreground = disabledFg->pixel; mask = GCForeground|GCBackground|GCFont; } else { gcValues.foreground = gcValues.background; mask = GCForeground; if (menuPtr->gray == None) { menuPtr->gray = Tk_GetBitmap(menuPtr->interp, menuPtr->tkwin, - Tk_GetUid("gray50")); + "gray50"); } if (menuPtr->gray != None) { gcValues.fill_style = FillStippled; @@ -231,10 +241,10 @@ TkMenuConfigureDrawOptions(menuPtr) } menuPtr->disabledGC = newGC; - gcValues.foreground = Tk_3DBorderColor(menuPtr->border)->pixel; + gcValues.foreground = Tk_3DBorderColor(border)->pixel; if (menuPtr->gray == None) { menuPtr->gray = Tk_GetBitmap(menuPtr->interp, menuPtr->tkwin, - Tk_GetUid("gray50")); + "gray50"); } if (menuPtr->gray != None) { gcValues.fill_style = FillStippled; @@ -247,10 +257,12 @@ TkMenuConfigureDrawOptions(menuPtr) } menuPtr->disabledImageGC = newGC; - gcValues.font = Tk_FontId(menuPtr->tkfont); - gcValues.foreground = menuPtr->activeFg->pixel; - gcValues.background = - Tk_3DBorderColor(menuPtr->activeBorder)->pixel; + gcValues.font = Tk_FontId(tkfont); + activeFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->activeFgPtr); + gcValues.foreground = activeFg->pixel; + activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, + menuPtr->activeBorderPtr); + gcValues.background = Tk_3DBorderColor(activeBorder)->pixel; newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, &gcValues); if (menuPtr->activeGC != None) { @@ -258,8 +270,10 @@ TkMenuConfigureDrawOptions(menuPtr) } menuPtr->activeGC = newGC; - gcValues.foreground = menuPtr->indicatorFg->pixel; - gcValues.background = Tk_3DBorderColor(menuPtr->border)->pixel; + indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, + menuPtr->indicatorFgPtr); + gcValues.foreground = indicatorFg->pixel; + gcValues.background = Tk_3DBorderColor(border)->pixel; newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, &gcValues); if (menuPtr->indicatorGC != None) { @@ -297,9 +311,10 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) Tk_Font tkfont; TkMenu *menuPtr = mePtr->menuPtr; - tkfont = (mePtr->tkfont == NULL) ? menuPtr->tkfont : mePtr->tkfont; + tkfont = Tk_GetFontFromObj(menuPtr->tkwin, + (mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr); - if (mePtr->state == tkActiveUid) { + if (mePtr->state == ENTRY_ACTIVE) { if (index != menuPtr->active) { TkActivateMenuEntry(menuPtr, index); } @@ -307,30 +322,24 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) if (index == menuPtr->active) { TkActivateMenuEntry(menuPtr, -1); } - if ((mePtr->state != tkNormalUid) - && (mePtr->state != tkDisabledUid)) { - Tcl_AppendResult(menuPtr->interp, "bad state value \"", - mePtr->state, - "\": must be normal, active, or disabled", (char *) NULL); - mePtr->state = tkNormalUid; - return TCL_ERROR; - } } - if ((mePtr->tkfont != NULL) - || (mePtr->border != NULL) - || (mePtr->fg != NULL) - || (mePtr->activeBorder != NULL) - || (mePtr->activeFg != NULL) - || (mePtr->indicatorFg != NULL)) { - gcValues.foreground = (mePtr->fg != NULL) - ? mePtr->fg->pixel - : menuPtr->fg->pixel; - gcValues.background = Tk_3DBorderColor( - (mePtr->border != NULL) - ? mePtr->border - : menuPtr->border) - ->pixel; + if ((mePtr->fontPtr != NULL) + || (mePtr->borderPtr != NULL) + || (mePtr->fgPtr != NULL) + || (mePtr->activeBorderPtr != NULL) + || (mePtr->activeFgPtr != NULL) + || (mePtr->indicatorFgPtr != NULL)) { + XColor *fg, *indicatorFg, *activeFg; + Tk_3DBorder border, activeBorder; + + fg = Tk_GetColorFromObj(menuPtr->tkwin, (mePtr->fgPtr != NULL) + ? mePtr->fgPtr : menuPtr->fgPtr); + gcValues.foreground = fg->pixel; + border = Tk_Get3DBorderFromObj(menuPtr->tkwin, + (mePtr->borderPtr != NULL) ? mePtr->borderPtr + : menuPtr->borderPtr); + gcValues.background = Tk_3DBorderColor(border)->pixel; gcValues.font = Tk_FontId(tkfont); @@ -345,17 +354,20 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); - if (mePtr->indicatorFg != NULL) { - gcValues.foreground = mePtr->indicatorFg->pixel; - } else if (menuPtr->indicatorFg != NULL) { - gcValues.foreground = menuPtr->indicatorFg->pixel; - } + indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, + (mePtr->indicatorFgPtr != NULL) ? mePtr->indicatorFgPtr + : menuPtr->indicatorFgPtr); + gcValues.foreground = indicatorFg->pixel; newIndicatorGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCGraphicsExposures, &gcValues); - if ((menuPtr->disabledFg != NULL) || (mePtr->image != NULL)) { - gcValues.foreground = menuPtr->disabledFg->pixel; + if ((menuPtr->disabledFgPtr != NULL) || (mePtr->image != NULL)) { + XColor *disabledFg; + + disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, + menuPtr->disabledFgPtr); + gcValues.foreground = disabledFg->pixel; mask = GCForeground|GCBackground|GCFont|GCGraphicsExposures; } else { gcValues.foreground = gcValues.background; @@ -365,13 +377,15 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) } newDisabledGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues); - gcValues.foreground = (mePtr->activeFg != NULL) - ? mePtr->activeFg->pixel - : menuPtr->activeFg->pixel; - gcValues.background = Tk_3DBorderColor( - (mePtr->activeBorder != NULL) - ? mePtr->activeBorder - : menuPtr->activeBorder)->pixel; + activeFg = Tk_GetColorFromObj(menuPtr->tkwin, + (mePtr->activeFgPtr != NULL) ? mePtr->activeFgPtr + : menuPtr->activeFgPtr); + activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, + (mePtr->activeBorderPtr != NULL) ? mePtr->activeBorderPtr + : menuPtr->activeBorderPtr); + + gcValues.foreground = activeFg->pixel; + gcValues.background = Tk_3DBorderColor(activeBorder)->pixel; newActiveGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); @@ -475,7 +489,7 @@ TkRecomputeMenu(menuPtr) void TkEventuallyRedrawMenu(menuPtr, mePtr) register TkMenu *menuPtr; /* Information about menu to redraw. */ - register TkMenuEntry *mePtr; /* Entry to redraw. NULL means redraw + register TkMenuEntry *mePtr;/* Entry to redraw. NULL means redraw * all the entries in the menu. */ { int i; @@ -616,21 +630,30 @@ DisplayMenu(clientData) register TkMenuEntry *mePtr; register Tk_Window tkwin = menuPtr->tkwin; int index, strictMotif; - Tk_Font tkfont = menuPtr->tkfont; + Tk_Font tkfont; Tk_FontMetrics menuMetrics; int width; + int borderWidth; + Tk_3DBorder border; + int activeBorderWidth; + int relief; + menuPtr->menuFlags &= ~REDRAW_PENDING; if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, + &borderWidth); + border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, + menuPtr->activeBorderWidthPtr, &activeBorderWidth); + if (menuPtr->menuType == MENUBAR) { - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border, - menuPtr->borderWidth, menuPtr->borderWidth, - Tk_Width(tkwin) - 2 * menuPtr->borderWidth, - Tk_Height(tkwin) - 2 * menuPtr->borderWidth, 0, - TK_RELIEF_FLAT); + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, + borderWidth, Tk_Width(tkwin) - 2 * borderWidth, + Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT); } strictMotif = Tk_StrictMotif(menuPtr->tkwin); @@ -640,7 +663,8 @@ DisplayMenu(clientData) * all of the time. */ - Tk_GetFontMetrics(menuPtr->tkfont, &menuMetrics); + tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + Tk_GetFontMetrics(tkfont, &menuMetrics); /* * Loop through all of the entries, drawing them one at a time. @@ -660,22 +684,22 @@ DisplayMenu(clientData) } else { if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { width = Tk_Width(menuPtr->tkwin) - mePtr->x - - menuPtr->activeBorderWidth; + - activeBorderWidth; } else { - width = mePtr->width + menuPtr->borderWidth; + width = mePtr->width + borderWidth; } } TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, &menuMetrics, mePtr->x, mePtr->y, width, mePtr->height, strictMotif, 1); - if ((index > 0) && (menuPtr->menuType != MENUBAR) + if ((index > 0) && (menuPtr->menuType != MENUBAR) && mePtr->columnBreak) { mePtr = menuPtr->entries[index - 1]; - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border, + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - menuPtr->activeBorderWidth, 0, + Tk_Height(tkwin) - mePtr->y - mePtr->height - + activeBorderWidth, 0, TK_RELIEF_FLAT); } } @@ -684,28 +708,29 @@ DisplayMenu(clientData) int x, y, height; if (menuPtr->numEntries == 0) { - x = y = menuPtr->borderWidth; - width = Tk_Width(tkwin) - 2 * menuPtr->activeBorderWidth; - height = Tk_Height(tkwin) - 2 * menuPtr->activeBorderWidth; + x = y = borderWidth; + width = Tk_Width(tkwin) - 2 * activeBorderWidth; + height = Tk_Height(tkwin) - 2 * activeBorderWidth; } else { mePtr = menuPtr->entries[menuPtr->numEntries - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - menuPtr->border, mePtr->x, mePtr->y + mePtr->height, - mePtr->width, Tk_Height(tkwin) - mePtr->y - mePtr->height - - menuPtr->activeBorderWidth, 0, + border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, + Tk_Height(tkwin) - mePtr->y - mePtr->height + - activeBorderWidth, 0, TK_RELIEF_FLAT); x = mePtr->x + mePtr->width; y = mePtr->y + mePtr->height; - width = Tk_Width(tkwin) - x - menuPtr->activeBorderWidth; - height = Tk_Height(tkwin) - y - menuPtr->activeBorderWidth; + width = Tk_Width(tkwin) - x - activeBorderWidth; + height = Tk_Height(tkwin) - y - activeBorderWidth; } - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), menuPtr->border, x, y, + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, width, height, 0, TK_RELIEF_FLAT); } + Tk_GetReliefFromObj(NULL, menuPtr->reliefPtr, &relief); Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin), - menuPtr->border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), - menuPtr->borderWidth, menuPtr->relief); + border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth, + relief); } /* @@ -739,11 +764,12 @@ TkMenuEventProc(clientData, eventPtr) TkEventuallyRecomputeMenu(menuPtr); TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); } else if (eventPtr->type == ActivateNotify) { - if (menuPtr->menuType == TEAROFF_MENU) { - TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL); - } + if (menuPtr->menuType == TEAROFF_MENU) { + TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL); + } } else if (eventPtr->type == DestroyNotify) { if (menuPtr->tkwin != NULL) { + TkDestroyMenu(menuPtr); menuPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(menuPtr->interp, menuPtr->widgetCmd); } @@ -753,7 +779,7 @@ TkMenuEventProc(clientData, eventPtr) if (menuPtr->menuFlags & RESIZE_PENDING) { Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr); } - TkDestroyMenu(menuPtr); + Tcl_EventuallyFree((ClientData) menuPtr, TCL_DYNAMIC); } } @@ -921,7 +947,6 @@ TkPostSubmenu(interp, menuPtr, mePtr) * posted. NULL means make sure that * no submenu is posted. */ { - char string[30]; int result, x, y; if (mePtr == menuPtr->postedCascade) { @@ -929,6 +954,8 @@ TkPostSubmenu(interp, menuPtr, mePtr) } if (menuPtr->postedCascade != NULL) { + char *name = Tcl_GetStringFromObj(menuPtr->postedCascade->namePtr, + NULL); /* * Note: when unposting a submenu, we have to redraw the entire @@ -948,17 +975,15 @@ TkPostSubmenu(interp, menuPtr, mePtr) */ TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); - result = Tcl_VarEval(interp, menuPtr->postedCascade->name, - " unpost", (char *) NULL); + result = Tcl_VarEval(interp, name, " unpost", (char *) NULL); menuPtr->postedCascade = NULL; if (result != TCL_OK) { return result; } } - if ((mePtr != NULL) && (mePtr->name != NULL) + if ((mePtr != NULL) && (mePtr->namePtr != NULL) && Tk_IsMapped(menuPtr->tkwin)) { - /* * Position the cascade with its upper left corner slightly * below and to the left of the upper right corner of the @@ -967,10 +992,13 @@ TkPostSubmenu(interp, menuPtr, mePtr) * The menu has to redrawn so that the entry can change relief. */ + char string[TCL_INTEGER_SPACE * 2]; + char *name; + + name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); Tk_GetRootCoords(menuPtr->tkwin, &x, &y); AdjustMenuCoords(menuPtr, mePtr, &x, &y, string); - result = Tcl_VarEval(interp, mePtr->name, " post ", string, - (char *) NULL); + result = Tcl_VarEval(interp, name, " post ", string, (char *) NULL); if (result != TCL_OK) { return result; } @@ -1009,10 +1037,15 @@ AdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string) *xPtr += mePtr->x; *yPtr += mePtr->y + mePtr->height; } else { - *xPtr += Tk_Width(menuPtr->tkwin) - menuPtr->borderWidth - - menuPtr->activeBorderWidth - 2; - *yPtr += mePtr->y - + menuPtr->activeBorderWidth + 2; + int borderWidth, activeBorderWidth; + + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, + &borderWidth); + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, + menuPtr->activeBorderWidthPtr, &activeBorderWidth); + *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth + - 2; + *yPtr += mePtr->y + activeBorderWidth + 2; } sprintf(string, "%d %d", *xPtr, *yPtr); } diff --git a/generic/tkMenubutton.c b/generic/tkMenubutton.c index da6d901..b9f0ddf 100644 --- a/generic/tkMenubutton.c +++ b/generic/tkMenubutton.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenubutton.c,v 1.2 1998/09/14 18:23:14 stanton Exp $ + * RCS: @(#) $Id: tkMenubutton.c,v 1.3 1999/04/16 01:51:19 stanton Exp $ */ #include "tkMenubutton.h" @@ -18,117 +18,140 @@ #include "default.h" /* - * Uids internal to menubuttons. + * The following table defines the legal values for the -direction + * option. It is used together with the "enum direction" declaration + * in tkMenubutton.h. */ -static Tk_Uid aboveUid = NULL; -static Tk_Uid belowUid = NULL; -static Tk_Uid leftUid = NULL; -static Tk_Uid rightUid = NULL; -static Tk_Uid flushUid = NULL; +static char *directionStrings[] = { + "above", "below", "flush", "left", "right", (char *) NULL +}; + +/* + * The following table defines the legal values for the -state option. + * It is used together with the "enum state" declaration in tkMenubutton.h. + */ + +static char *stateStrings[] = { + "active", "disabled", "normal", (char *) NULL +}; /* * Information used for parsing configuration specs: */ -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_MENUBUTTON_ACTIVE_BG_COLOR, Tk_Offset(TkMenuButton, activeBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_MENUBUTTON_ACTIVE_BG_MONO, Tk_Offset(TkMenuButton, activeBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_MENUBUTTON_ACTIVE_FG_COLOR, Tk_Offset(TkMenuButton, activeFg), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-activeforeground", "activeForeground", "Background", - DEF_MENUBUTTON_ACTIVE_FG_MONO, Tk_Offset(TkMenuButton, activeFg), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_ANCHOR, "-anchor", "anchor", "Anchor", - DEF_MENUBUTTON_ANCHOR, Tk_Offset(TkMenuButton, anchor), 0}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_MENUBUTTON_BG_COLOR, Tk_Offset(TkMenuButton, normalBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_MENUBUTTON_BG_MONO, Tk_Offset(TkMenuButton, normalBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_BITMAP, "-bitmap", "bitmap", "Bitmap", - DEF_MENUBUTTON_BITMAP, Tk_Offset(TkMenuButton, bitmap), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_MENUBUTTON_BORDER_WIDTH, Tk_Offset(TkMenuButton, borderWidth), 0}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_MENUBUTTON_CURSOR, Tk_Offset(TkMenuButton, cursor), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_UID, "-direction", "direction", "Direction", - DEF_MENUBUTTON_DIRECTION, Tk_Offset(TkMenuButton, direction), - 0}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", + DEF_MENUBUTTON_ACTIVE_BG_COLOR, -1, + Tk_Offset(TkMenuButton, activeBorder), 0, + (ClientData) DEF_MENUBUTTON_ACTIVE_BG_MONO, 0}, + {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", + DEF_MENUBUTTON_ACTIVE_FG_COLOR, -1, + Tk_Offset(TkMenuButton, activeFg), + 0, (ClientData) DEF_MENUBUTTON_ACTIVE_FG_MONO, 0}, + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + DEF_MENUBUTTON_ANCHOR, -1, + Tk_Offset(TkMenuButton, anchor), 0, 0, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_MENUBUTTON_BG_COLOR, -1, Tk_Offset(TkMenuButton, normalBorder), + 0, (ClientData) DEF_MENUBUTTON_BG_MONO, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", + DEF_MENUBUTTON_BITMAP, -1, Tk_Offset(TkMenuButton, bitmap), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_MENUBUTTON_BORDER_WIDTH, -1, + Tk_Offset(TkMenuButton, borderWidth), 0, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_MENUBUTTON_CURSOR, -1, Tk_Offset(TkMenuButton, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction", + DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction), + 0, (ClientData) directionStrings, 0}, + {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", "DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR, - Tk_Offset(TkMenuButton, disabledFg), - TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_COLOR, "-disabledforeground", "disabledForeground", - "DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_MONO, - Tk_Offset(TkMenuButton, disabledFg), - TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_FONT, "-font", "font", "Font", - DEF_MENUBUTTON_FONT, Tk_Offset(TkMenuButton, tkfont), 0}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_MENUBUTTON_FG, Tk_Offset(TkMenuButton, normalFg), 0}, - {TK_CONFIG_STRING, "-height", "height", "Height", - DEF_MENUBUTTON_HEIGHT, Tk_Offset(TkMenuButton, heightString), 0}, - {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", - "HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG, - Tk_Offset(TkMenuButton, highlightBgColorPtr), 0}, - {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_MENUBUTTON_HIGHLIGHT, Tk_Offset(TkMenuButton, highlightColorPtr), - 0}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", + -1, Tk_Offset(TkMenuButton, disabledFg), TK_OPTION_NULL_OK, + (ClientData) DEF_MENUBUTTON_DISABLED_FG_MONO, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_MENUBUTTON_FONT, -1, Tk_Offset(TkMenuButton, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_MENUBUTTON_FG, -1, Tk_Offset(TkMenuButton, normalFg), 0, 0, 0}, + {TK_OPTION_STRING, "-height", "height", "Height", + DEF_MENUBUTTON_HEIGHT, -1, Tk_Offset(TkMenuButton, heightString), + 0, 0, 0}, + {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkMenuButton, highlightBgColorPtr), 0, 0, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_MENUBUTTON_HIGHLIGHT, -1, + Tk_Offset(TkMenuButton, highlightColorPtr), 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH, - Tk_Offset(TkMenuButton, highlightWidth), 0}, - {TK_CONFIG_STRING, "-image", "image", "Image", - DEF_MENUBUTTON_IMAGE, Tk_Offset(TkMenuButton, imageString), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", - DEF_MENUBUTTON_INDICATOR, Tk_Offset(TkMenuButton, indicatorOn), 0}, - {TK_CONFIG_JUSTIFY, "-justify", "justify", "Justify", - DEF_MENUBUTTON_JUSTIFY, Tk_Offset(TkMenuButton, justify), 0}, - {TK_CONFIG_STRING, "-menu", "menu", "Menu", - DEF_MENUBUTTON_MENU, Tk_Offset(TkMenuButton, menuName), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-padx", "padX", "Pad", - DEF_MENUBUTTON_PADX, Tk_Offset(TkMenuButton, padX), 0}, - {TK_CONFIG_PIXELS, "-pady", "padY", "Pad", - DEF_MENUBUTTON_PADY, Tk_Offset(TkMenuButton, padY), 0}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_MENUBUTTON_RELIEF, Tk_Offset(TkMenuButton, relief), 0}, - {TK_CONFIG_UID, "-state", "state", "State", - DEF_MENUBUTTON_STATE, Tk_Offset(TkMenuButton, state), 0}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_MENUBUTTON_TAKE_FOCUS, Tk_Offset(TkMenuButton, takeFocus), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-text", "text", "Text", - DEF_MENUBUTTON_TEXT, Tk_Offset(TkMenuButton, text), 0}, - {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", - DEF_MENUBUTTON_TEXT_VARIABLE, Tk_Offset(TkMenuButton, textVarName), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_INT, "-underline", "underline", "Underline", - DEF_MENUBUTTON_UNDERLINE, Tk_Offset(TkMenuButton, underline), 0}, - {TK_CONFIG_STRING, "-width", "width", "Width", - DEF_MENUBUTTON_WIDTH, Tk_Offset(TkMenuButton, widthString), 0}, - {TK_CONFIG_PIXELS, "-wraplength", "wrapLength", "WrapLength", - DEF_MENUBUTTON_WRAP_LENGTH, Tk_Offset(TkMenuButton, wrapLength), 0}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, + -1, Tk_Offset(TkMenuButton, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-image", "image", "Image", + DEF_MENUBUTTON_IMAGE, -1, Tk_Offset(TkMenuButton, imageString), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn", + DEF_MENUBUTTON_INDICATOR, -1, Tk_Offset(TkMenuButton, indicatorOn), + 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0}, + {TK_OPTION_STRING, "-menu", "menu", "Menu", + DEF_MENUBUTTON_MENU, -1, Tk_Offset(TkMenuButton, menuName), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-padx", "padX", "Pad", + DEF_MENUBUTTON_PADX, -1, Tk_Offset(TkMenuButton, padX), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-pady", "padY", "Pad", + DEF_MENUBUTTON_PADY, -1, Tk_Offset(TkMenuButton, padY), + 0, 0, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_MENUBUTTON_RELIEF, -1, Tk_Offset(TkMenuButton, relief), + 0, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_MENUBUTTON_STATE, -1, Tk_Offset(TkMenuButton, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_MENUBUTTON_TAKE_FOCUS, -1, + Tk_Offset(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_STRING, "-text", "text", "Text", + DEF_MENUBUTTON_TEXT, -1, Tk_Offset(TkMenuButton, text), 0, 0, 0}, + {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", + DEF_MENUBUTTON_TEXT_VARIABLE, -1, + Tk_Offset(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-underline", "underline", "Underline", + DEF_MENUBUTTON_UNDERLINE, -1, Tk_Offset(TkMenuButton, underline), + 0, 0, 0}, + {TK_OPTION_STRING, "-width", "width", "Width", + DEF_MENUBUTTON_WIDTH, -1, Tk_Offset(TkMenuButton, widthString), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + DEF_MENUBUTTON_WRAP_LENGTH, -1, Tk_Offset(TkMenuButton, wrapLength), + 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /* + * The following tables define the menubutton widget commands and map the + * indexes into the string tables into a single enumerated type used + * to dispatch the scale widget command. + */ + +static char *commandNames[] = { + "cget", "configure", (char *) NULL +}; + +enum command { + COMMAND_CGET, COMMAND_CONFIGURE, +}; + +/* * Forward declarations for procedures defined later in this file: */ @@ -142,17 +165,18 @@ static void MenuButtonImageProc _ANSI_ARGS_((ClientData clientData, static char * MenuButtonTextVarProc _ANSI_ARGS_(( ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); -static int MenuButtonWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +static int MenuButtonWidgetObjCmd _ANSI_ARGS_(( + ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[])); static int ConfigureMenuButton _ANSI_ARGS_((Tcl_Interp *interp, - TkMenuButton *mbPtr, int argc, char **argv, - int flags)); + TkMenuButton *mbPtr, int objc, + Tcl_Obj *CONST objv[])); static void DestroyMenuButton _ANSI_ARGS_((char *memPtr)); /* *-------------------------------------------------------------- * - * Tk_MenubuttonCmd -- + * Tk_MenubuttonObjCmd -- * * This procedure is invoked to process the "button", "label", * "radiobutton", and "checkbutton" Tcl commands. See the @@ -168,20 +192,38 @@ static void DestroyMenuButton _ANSI_ARGS_((char *memPtr)); */ int -Tk_MenubuttonCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_MenubuttonObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to + * option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { register TkMenuButton *mbPtr; - Tk_Window tkwin = (Tk_Window) clientData; - Tk_Window new; + Tk_OptionTable optionTable; + Tk_Window tkwin; + + optionTable = (Tk_OptionTable) clientData; + if (optionTable == NULL) { + Tcl_CmdInfo info; + char *name; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + /* + * We haven't created the option table for this widget class + * yet. Do it now and save the table as the clientData for + * the command, so we'll have access to it in future + * invocations of the command. + */ + + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + name = Tcl_GetString(objv[0]); + Tcl_GetCommandInfo(interp, name, &info); + info.objClientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, name, &info); + } + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } @@ -189,25 +231,28 @@ Tk_MenubuttonCmd(clientData, interp, argc, argv) * Create the new window. */ - new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); - if (new == NULL) { + tkwin = Tk_CreateWindowFromPath(interp, + Tk_MainWindow(interp), Tcl_GetString(objv[1]), (char *) NULL); + if (tkwin == NULL) { return TCL_ERROR; } - Tk_SetClass(new, "Menubutton"); - mbPtr = TkpCreateMenuButton(new); + Tk_SetClass(tkwin, "Menubutton"); + mbPtr = TkpCreateMenuButton(tkwin); - TkSetClassProcs(new, &tkpMenubuttonClass, (ClientData) mbPtr); + TkSetClassProcs(tkwin, &tkpMenubuttonClass, (ClientData) mbPtr); /* * Initialize the data structure for the button. */ - mbPtr->tkwin = new; - mbPtr->display = Tk_Display (new); + mbPtr->tkwin = tkwin; + mbPtr->display = Tk_Display (tkwin); mbPtr->interp = interp; - mbPtr->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(mbPtr->tkwin), - MenuButtonWidgetCmd, (ClientData) mbPtr, MenuButtonCmdDeletedProc); + mbPtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(mbPtr->tkwin), MenuButtonWidgetObjCmd, + (ClientData) mbPtr, MenuButtonCmdDeletedProc); + mbPtr->optionTable = optionTable; mbPtr->menuName = NULL; mbPtr->text = NULL; mbPtr->underline = -1; @@ -215,7 +260,7 @@ Tk_MenubuttonCmd(clientData, interp, argc, argv) mbPtr->bitmap = None; mbPtr->imageString = NULL; mbPtr->image = NULL; - mbPtr->state = tkNormalUid; + mbPtr->state = STATE_NORMAL; mbPtr->normalBorder = NULL; mbPtr->activeBorder = NULL; mbPtr->borderWidth = 0; @@ -247,34 +292,35 @@ Tk_MenubuttonCmd(clientData, interp, argc, argv) mbPtr->indicatorOn = 0; mbPtr->indicatorWidth = 0; mbPtr->indicatorHeight = 0; + mbPtr->direction = DIRECTION_FLUSH; mbPtr->cursor = None; mbPtr->takeFocus = NULL; mbPtr->flags = 0; - if (aboveUid == NULL) { - aboveUid = Tk_GetUid("above"); - belowUid = Tk_GetUid("below"); - leftUid = Tk_GetUid("left"); - rightUid = Tk_GetUid("right"); - flushUid = Tk_GetUid("flush"); - } - mbPtr->direction = flushUid; Tk_CreateEventHandler(mbPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, MenuButtonEventProc, (ClientData) mbPtr); - if (ConfigureMenuButton(interp, mbPtr, argc-2, argv+2, 0) != TCL_OK) { + + if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) + != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); return TCL_ERROR; } - interp->result = Tk_PathName(mbPtr->tkwin); + if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) { + Tk_DestroyWindow(mbPtr->tkwin); + return TCL_ERROR; + } + + Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(mbPtr->tkwin), + -1); return TCL_OK; } /* *-------------------------------------------------------------- * - * MenuButtonWidgetCmd -- + * MenuButtonWidgetObjCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. @@ -290,56 +336,68 @@ Tk_MenubuttonCmd(clientData, interp, argc, argv) */ static int -MenuButtonWidgetCmd(clientData, interp, argc, argv) +MenuButtonWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about button widget. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { register TkMenuButton *mbPtr = (TkMenuButton *) clientData; - int result; - size_t length; - int c; + int result, index; + Tcl_Obj *objPtr; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " option ?arg arg ...?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } + result = Tcl_GetIndexFromObj(interp, objv[1], + commandNames, "option", 0, &index); + if (result != TCL_OK) { + return result; + } Tcl_Preserve((ClientData) mbPtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - result = TCL_ERROR; - } else { - result = Tk_ConfigureValue(interp, mbPtr->tkwin, configSpecs, - (char *) mbPtr, argv[2], 0); + + switch (index) { + case COMMAND_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); + goto error; + } + + objPtr = Tk_GetOptionValue(interp, (char *) mbPtr, + mbPtr->optionTable, objv[2], mbPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + break; } - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, mbPtr->tkwin, configSpecs, - (char *) mbPtr, (char *) NULL, 0); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, mbPtr->tkwin, configSpecs, - (char *) mbPtr, argv[2], 0); - } else { - result = ConfigureMenuButton(interp, mbPtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); + + case COMMAND_CONFIGURE: { + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr, + mbPtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + mbPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + } else { + result = ConfigureMenuButton(interp, mbPtr, objc-2, + objv+2); + } + break; } - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be cget or configure", - (char *) NULL); - result = TCL_ERROR; } Tcl_Release((ClientData) mbPtr); return result; + + error: + Tcl_Release((ClientData) mbPtr); + return TCL_ERROR; } /* @@ -348,9 +406,9 @@ MenuButtonWidgetCmd(clientData, interp, argc, argv) * DestroyMenuButton -- * * This procedure is invoked to recycle all of the resources - * associated with a button widget. It is invoked as a + * associated with a menubutton widget. It is invoked as a * when-idle handler in order to make sure that there is no - * other use of the button pending at the time of the deletion. + * other use of the menubutton pending at the time of the deletion. * * Results: * None. @@ -366,6 +424,11 @@ DestroyMenuButton(memPtr) char *memPtr; /* Info about button widget. */ { register TkMenuButton *mbPtr = (TkMenuButton *) memPtr; + TkpDestroyMenuButton(mbPtr); + + if (mbPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr); + } /* * Free up all the stuff that requires special handling, then @@ -373,6 +436,7 @@ DestroyMenuButton(memPtr) * stuff. */ + Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd); if (mbPtr->textVarName != NULL) { Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, @@ -387,15 +451,19 @@ DestroyMenuButton(memPtr) if (mbPtr->activeTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC); } + if (mbPtr->disabledGC != None) { + Tk_FreeGC(mbPtr->display, mbPtr->disabledGC); + } if (mbPtr->gray != None) { Tk_FreeBitmap(mbPtr->display, mbPtr->gray); } - if (mbPtr->disabledGC != None) { - Tk_FreeGC(mbPtr->display, mbPtr->disabledGC); + if (mbPtr->textLayout != NULL) { + Tk_FreeTextLayout(mbPtr->textLayout); } - Tk_FreeTextLayout(mbPtr->textLayout); - Tk_FreeOptions(configSpecs, (char *) mbPtr, mbPtr->display, 0); - ckfree((char *) mbPtr); + Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, + mbPtr->tkwin); + mbPtr->tkwin = NULL; + Tcl_EventuallyFree((ClientData) mbPtr, TCL_DYNAMIC); } /* @@ -409,7 +477,7 @@ DestroyMenuButton(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, @@ -420,147 +488,174 @@ DestroyMenuButton(memPtr) */ static int -ConfigureMenuButton(interp, mbPtr, argc, argv, flags) +ConfigureMenuButton(interp, mbPtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ - register TkMenuButton *mbPtr; /* Information about widget; may or may - * not already have values for some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Flags to pass to Tk_ConfigureWidget. */ + register TkMenuButton *mbPtr; + /* Information about widget; may or may + * not already have values for some + * fields. */ + int objc; /* Number of valid entries in objv. */ + Tcl_Obj *CONST objv[]; /* Arguments. */ { - int result; + Tk_SavedOptions savedOptions; + Tcl_Obj *errorResult = NULL; + int error; Tk_Image image; /* - * Eliminate any existing trace on variables monitored by the menubutton. + * Eliminate any existing trace on variables monitored by the + * menubutton. */ if (mbPtr->textVarName != NULL) { - Tcl_UntraceVar(interp, mbPtr->textVarName, + Tcl_UntraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuButtonTextVarProc, (ClientData) mbPtr); } - result = Tk_ConfigureWidget(interp, mbPtr->tkwin, configSpecs, - argc, argv, (char *) mbPtr, flags); - if (result != TCL_OK) { - return TCL_ERROR; - } - /* - * A few options need special processing, such as setting the - * background from a 3-D border, or filling in complicated - * defaults that couldn't be specified to Tk_ConfigureWidget. + * The following loop is potentially executed twice. During the + * first pass configuration options get set to their new values. + * If there is an error in this pass, we execute a second pass + * to restore all the options to their previous values. */ - if ((mbPtr->state == tkActiveUid) && !Tk_StrictMotif(mbPtr->tkwin)) { - Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->activeBorder); - } else { - Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->normalBorder); - if ((mbPtr->state != tkNormalUid) && (mbPtr->state != tkActiveUid) - && (mbPtr->state != tkDisabledUid)) { - Tcl_AppendResult(interp, "bad state value \"", mbPtr->state, - "\": must be normal, active, or disabled", (char *) NULL); - mbPtr->state = tkNormalUid; - return TCL_ERROR; + for (error = 0; error <= 1; error++) { + if (!error) { + /* + * First pass: set options to new values. + */ + + if (Tk_SetOptions(interp, (char *) mbPtr, + mbPtr->optionTable, objc, objv, + mbPtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) { + continue; + } + } else { + /* + * Second pass: restore options to old values. + */ + + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); } - } - if ((mbPtr->direction != aboveUid) && (mbPtr->direction != belowUid) - && (mbPtr->direction != leftUid) && (mbPtr->direction != rightUid) - && (mbPtr->direction != flushUid)) { - Tcl_AppendResult(interp, "bad direction value \"", mbPtr->direction, - "\": must be above, below, left, right, or flush", - (char *) NULL); - mbPtr->direction = belowUid; - return TCL_ERROR; - } - - if (mbPtr->highlightWidth < 0) { - mbPtr->highlightWidth = 0; - } + /* + * A few options need special processing, such as setting the + * background from a 3-D border, or filling in complicated + * defaults that couldn't be specified to Tk_SetOptions. + */ - if (mbPtr->padX < 0) { - mbPtr->padX = 0; - } - if (mbPtr->padY < 0) { - mbPtr->padY = 0; - } + if ((mbPtr->state == STATE_ACTIVE) + && !Tk_StrictMotif(mbPtr->tkwin)) { + Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->activeBorder); + } else { + Tk_SetBackgroundFromBorder(mbPtr->tkwin, mbPtr->normalBorder); + } - /* - * Get the image for the widget, if there is one. Allocate the - * new image before freeing the old one, so that the reference - * count doesn't go to zero and cause image data to be discarded. - */ + if (mbPtr->highlightWidth < 0) { + mbPtr->highlightWidth = 0; + } - if (mbPtr->imageString != NULL) { - image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin, - mbPtr->imageString, MenuButtonImageProc, (ClientData) mbPtr); - if (image == NULL) { - return TCL_ERROR; + if (mbPtr->padX < 0) { + mbPtr->padX = 0; + } + if (mbPtr->padY < 0) { + mbPtr->padY = 0; } - } else { - image = NULL; - } - if (mbPtr->image != NULL) { - Tk_FreeImage(mbPtr->image); - } - mbPtr->image = image; - if ((mbPtr->image == NULL) && (mbPtr->bitmap == None) - && (mbPtr->textVarName != NULL)) { /* - * The menubutton displays a variable. Set up a trace to watch - * for any changes in it. + * Get the image for the widget, if there is one. Allocate the + * new image before freeing the old one, so that the reference + * count doesn't go to zero and cause image data to be discarded. */ - char *value; + if (mbPtr->imageString != NULL) { + image = Tk_GetImage(mbPtr->interp, mbPtr->tkwin, + mbPtr->imageString, MenuButtonImageProc, + (ClientData) mbPtr); + if (image == NULL) { + return TCL_ERROR; + } + } else { + image = NULL; + } + if (mbPtr->image != NULL) { + Tk_FreeImage(mbPtr->image); + } + mbPtr->image = image; - value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); - if (value == NULL) { - Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, - TCL_GLOBAL_ONLY); + /* + * Recompute the geometry for the button. + */ + + if ((mbPtr->bitmap != None) || (mbPtr->image != NULL)) { + if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->widthString, + &mbPtr->width) != TCL_OK) { + widthError: + Tcl_AddErrorInfo(interp, "\n (processing -width option)"); + continue; + } + if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->heightString, + &mbPtr->height) != TCL_OK) { + heightError: + Tcl_AddErrorInfo(interp, "\n (processing -height option)"); + continue; + } } else { - if (mbPtr->text != NULL) { - ckfree(mbPtr->text); + if (Tcl_GetInt(interp, mbPtr->widthString, &mbPtr->width) + != TCL_OK) { + goto widthError; + } + if (Tcl_GetInt(interp, mbPtr->heightString, &mbPtr->height) + != TCL_OK) { + goto heightError; } - mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); - strcpy(mbPtr->text, value); } - Tcl_TraceVar(interp, mbPtr->textVarName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - MenuButtonTextVarProc, (ClientData) mbPtr); + break; } - /* - * Recompute the geometry for the button. - */ + if (!error) { + Tk_FreeSavedOptions(&savedOptions); + } - if ((mbPtr->bitmap != None) || (mbPtr->image != NULL)) { - if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->widthString, - &mbPtr->width) != TCL_OK) { - widthError: - Tcl_AddErrorInfo(interp, "\n (processing -width option)"); - return TCL_ERROR; - } - if (Tk_GetPixels(interp, mbPtr->tkwin, mbPtr->heightString, - &mbPtr->height) != TCL_OK) { - heightError: - Tcl_AddErrorInfo(interp, "\n (processing -height option)"); - return TCL_ERROR; - } - } else { - if (Tcl_GetInt(interp, mbPtr->widthString, &mbPtr->width) - != TCL_OK) { - goto widthError; - } - if (Tcl_GetInt(interp, mbPtr->heightString, &mbPtr->height) - != TCL_OK) { - goto heightError; - } + if ((mbPtr->image == NULL) && (mbPtr->bitmap == None) + && (mbPtr->textVarName != NULL)) { + + /* + * The menubutton displays the value of a variable. + * Set up a trace to watch for any changes in it, create + * the variable if it doesn't exist, and fetch its + * current value. + */ + + char *value; + + value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); + if (value == NULL) { + Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, + TCL_GLOBAL_ONLY); + } else { + if (mbPtr->text != NULL) { + ckfree(mbPtr->text); + } + mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); + strcpy(mbPtr->text, value); + } + Tcl_TraceVar(interp, mbPtr->textVarName, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuButtonTextVarProc, (ClientData) mbPtr); } + TkMenuButtonWorldChanged((ClientData) mbPtr); - return TCL_OK; + if (error) { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); + return TCL_ERROR; + } else { + return TCL_OK; + } } /* @@ -690,15 +785,7 @@ MenuButtonEventProc(clientData, eventPtr) goto redraw; } else if (eventPtr->type == DestroyNotify) { - TkpDestroyMenuButton(mbPtr); - if (mbPtr->tkwin != NULL) { - mbPtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd); - } - if (mbPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(TkpDisplayMenuButton, (ClientData) mbPtr); - } - Tcl_EventuallyFree((ClientData) mbPtr, DestroyMenuButton); + DestroyMenuButton((char *) mbPtr); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { mbPtr->flags |= GOT_FOCUS; @@ -756,7 +843,6 @@ MenuButtonCmdDeletedProc(clientData) */ if (tkwin != NULL) { - mbPtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } diff --git a/generic/tkMenubutton.h b/generic/tkMenubutton.h index b032274..eb7e030 100644 --- a/generic/tkMenubutton.h +++ b/generic/tkMenubutton.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMenubutton.h,v 1.4 1998/09/14 18:23:15 stanton Exp $ + * RCS: @(#) $Id: tkMenubutton.h,v 1.5 1999/04/16 01:51:19 stanton Exp $ */ #ifndef _TKMENUBUTTON @@ -25,6 +25,23 @@ #endif /* + * Legal values for the "orient" field of TkMenubutton records. + */ + +enum direction { + DIRECTION_ABOVE, DIRECTION_BELOW, DIRECTION_FLUSH, + DIRECTION_LEFT, DIRECTION_RIGHT +}; + +/* + * Legal values for the "state" field of TkMenubutton records. + */ + +enum state { + STATE_ACTIVE, STATE_DISABLED, STATE_NORMAL +}; + +/* * A data structure of the following type is kept for each * widget managed by this file: */ @@ -39,6 +56,8 @@ typedef struct { * freed up even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with menubutton. */ Tcl_Command widgetCmd; /* Token for menubutton's widget command. */ + Tk_OptionTable optionTable; /* Table that defines configuration options + * available for this widget. */ char *menuName; /* Name of menu associated with widget. * Malloc-ed. */ @@ -65,7 +84,7 @@ typedef struct { * Information used when displaying widget: */ - Tk_Uid state; /* State of button for display purposes: + enum state state; /* State of button for display purposes: * normal, active, or disabled. */ Tk_3DBorder normalBorder; /* Structure used to draw 3-D * border and background when window @@ -143,7 +162,7 @@ typedef struct { * Miscellaneous information: */ - Tk_Uid direction; /* Direction for where to pop the menu. + enum direction direction; /* Direction for where to pop the menu. * Valid directions are "above", "below", * "left", "right", and "flush". "flush" * means that the upper left corner of the diff --git a/generic/tkMessage.c b/generic/tkMessage.c index d12c0a3..3f7a4e7 100644 --- a/generic/tkMessage.c +++ b/generic/tkMessage.c @@ -6,12 +6,12 @@ * in a window according to a particular aspect ratio. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMessage.c,v 1.2 1998/09/14 18:23:15 stanton Exp $ + * RCS: @(#) $Id: tkMessage.c,v 1.3 1999/04/16 01:51:20 stanton Exp $ */ #include "tkPort.h" @@ -40,7 +40,7 @@ typedef struct { char *string; /* String displayed in message. */ int numChars; /* Number of characters in string, not - * including terminating NULL character. */ + * including terminating NULL. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. * If non-NULL, message displays the contents * of this variable. */ @@ -274,7 +274,7 @@ Tk_MessageCmd(clientData, interp, argc, argv) goto error; } - interp->result = Tk_PathName(msgPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(msgPtr->tkwin), TCL_STATIC); return TCL_OK; error: @@ -401,7 +401,7 @@ DestroyMessage(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, @@ -465,7 +465,7 @@ ConfigureMessage(interp, msgPtr, argc, argv, flags) * that couldn't be specified to Tk_ConfigureWidget. */ - msgPtr->numChars = strlen(msgPtr->string); + msgPtr->numChars = Tcl_NumUtfChars(msgPtr->string, -1); Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border); @@ -834,8 +834,8 @@ MessageTextVarProc(clientData, interp, name1, name2, flags) if (msgPtr->string != NULL) { ckfree(msgPtr->string); } - msgPtr->numChars = strlen(value); - msgPtr->string = (char *) ckalloc((unsigned) (msgPtr->numChars + 1)); + msgPtr->numChars = Tcl_NumUtfChars(value, -1); + msgPtr->string = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(msgPtr->string, value); ComputeMessageGeometry(msgPtr); diff --git a/generic/tkObj.c b/generic/tkObj.c new file mode 100644 index 0000000..ff2684c --- /dev/null +++ b/generic/tkObj.c @@ -0,0 +1,659 @@ +/* + * tkObj.c -- + * + * This file contains procedures that implement the common Tk object + * types + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkObj.c,v 1.2 1999/04/16 01:51:20 stanton Exp $ + */ + +#include "tkInt.h" + +/* + * The following structure is the internal representation for pixel objects. + */ + +typedef struct PixelRep { + double value; + int units; + Tk_Window tkwin; + int returnValue; +} PixelRep; + +#define SIMPLE_PIXELREP(objPtr) \ + ((objPtr)->internalRep.twoPtrValue.ptr2 == 0) + +#define SET_SIMPLEPIXEL(objPtr, intval) \ + (objPtr)->internalRep.twoPtrValue.ptr1 = (VOID *) (intval); \ + (objPtr)->internalRep.twoPtrValue.ptr2 = 0 + +#define GET_SIMPLEPIXEL(objPtr) \ + ((int) (objPtr)->internalRep.twoPtrValue.ptr1) + +#define SET_COMPLEXPIXEL(objPtr, repPtr) \ + (objPtr)->internalRep.twoPtrValue.ptr1 = 0; \ + (objPtr)->internalRep.twoPtrValue.ptr2 = (VOID *) repPtr + +#define GET_COMPLEXPIXEL(objPtr) \ + ((PixelRep *) (objPtr)->internalRep.twoPtrValue.ptr2) + + +/* + * The following structure is the internal representation for mm objects. + */ + +typedef struct MMRep { + double value; + int units; + Tk_Window tkwin; + double returnValue; +} MMRep; + +/* + * Prototypes for procedures defined later in this file: + */ + +static void DupMMInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, + Tcl_Obj *copyPtr)); +static void DupPixelInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, + Tcl_Obj *copyPtr)); +static void FreeMMInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr)); +static void FreePixelInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr)); +static int SetMMFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); +static int SetPixelFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); +static int SetWindowFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); + +/* + * The following structure defines the implementation of the "pixel" + * Tcl object, used for measuring distances. The pixel object remembers + * its initial display-independant settings. + */ + +static Tcl_ObjType pixelObjType = { + "pixel", /* name */ + FreePixelInternalRep, /* freeIntRepProc */ + DupPixelInternalRep, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetPixelFromAny /* setFromAnyProc */ +}; + +/* + * The following structure defines the implementation of the "pixel" + * Tcl object, used for measuring distances. The pixel object remembers + * its initial display-independant settings. + */ + +static Tcl_ObjType mmObjType = { + "mm", /* name */ + FreeMMInternalRep, /* freeIntRepProc */ + DupMMInternalRep, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetMMFromAny /* setFromAnyProc */ +}; + +/* + * The following structure defines the implementation of the "window" + * Tcl object. + */ + +static Tcl_ObjType windowObjType = { + "window", /* name */ + (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ + (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetWindowFromAny /* setFromAnyProc */ +}; + + + +/* + *---------------------------------------------------------------------- + * + * Tk_GetPixelsFromObj -- + * + * Attempt to return a pixel value from the Tcl object "objPtr". If the + * object is not already a pixel value, an attempt will be made to convert + * it to one. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in the interpreter's + * result unless "interp" is NULL. + * + * Side effects: + * If the object is not already a pixel, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetPixelsFromObj(interp, tkwin, objPtr, intPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tk_Window tkwin; + Tcl_Obj *objPtr; /* The object from which to get pixels. */ + int *intPtr; /* Place to store resulting pixels. */ +{ + int result; + double d; + PixelRep *pixelPtr; + static double bias[] = { + 1.0, 10.0, 25.4, 25.4 / 72.0 + }; + + if (objPtr->typePtr != &pixelObjType) { + result = SetPixelFromAny(interp, objPtr); + if (result != TCL_OK) { + return result; + } + } + + if (SIMPLE_PIXELREP(objPtr)) { + *intPtr = GET_SIMPLEPIXEL(objPtr); + } else { + pixelPtr = GET_COMPLEXPIXEL(objPtr); + if (pixelPtr->tkwin != tkwin) { + d = pixelPtr->value; + if (pixelPtr->units >= 0) { + d *= bias[pixelPtr->units] * WidthOfScreen(Tk_Screen(tkwin)); + d /= WidthMMOfScreen(Tk_Screen(tkwin)); + } + if (d < 0) { + pixelPtr->returnValue = (int) (d - 0.5); + } else { + pixelPtr->returnValue = (int) (d + 0.5); + } + pixelPtr->tkwin = tkwin; + } + *intPtr = pixelPtr->returnValue; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * FreePixelInternalRep -- + * + * Deallocate the storage associated with a pixel object's internal + * representation. + * + * Results: + * None. + * + * Side effects: + * Frees objPtr's internal representation and sets objPtr's + * internalRep to NULL. + * + *---------------------------------------------------------------------- + */ + +static void +FreePixelInternalRep(objPtr) + Tcl_Obj *objPtr; /* Pixel object with internal rep to free. */ +{ + PixelRep *pixelPtr; + + if (!SIMPLE_PIXELREP(objPtr)) { + pixelPtr = GET_COMPLEXPIXEL(objPtr); + ckfree((char *) pixelPtr); + } + SET_SIMPLEPIXEL(objPtr, 0); +} + +/* + *---------------------------------------------------------------------- + * + * DupPixelInternalRep -- + * + * Initialize the internal representation of a pixel Tcl_Obj to a + * copy of the internal representation of an existing pixel object. + * + * Results: + * None. + * + * Side effects: + * copyPtr's internal rep is set to the pixel corresponding to + * srcPtr's internal rep. + * + *---------------------------------------------------------------------- + */ + +static void +DupPixelInternalRep(srcPtr, copyPtr) + register Tcl_Obj *srcPtr; /* Object with internal rep to copy. */ + register Tcl_Obj *copyPtr; /* Object with internal rep to set. */ +{ + PixelRep *oldPtr, *newPtr; + + copyPtr->typePtr = srcPtr->typePtr; + + if (SIMPLE_PIXELREP(srcPtr)) { + SET_SIMPLEPIXEL(copyPtr, GET_SIMPLEPIXEL(srcPtr)); + } else { + oldPtr = GET_COMPLEXPIXEL(srcPtr); + newPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + newPtr->value = oldPtr->value; + newPtr->units = oldPtr->units; + newPtr->tkwin = oldPtr->tkwin; + newPtr->returnValue = oldPtr->returnValue; + SET_COMPLEXPIXEL(copyPtr, newPtr); + } +} + +/* + *---------------------------------------------------------------------- + * + * SetPixelFromAny -- + * + * Attempt to generate a pixel internal form for the Tcl object + * "objPtr". + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * If no error occurs, a pixel representation of the object is + * stored internally and the type of "objPtr" is set to pixel. + * + *---------------------------------------------------------------------- + */ + +static int +SetPixelFromAny(interp, objPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + char *string, *rest; + double d; + int i, units; + PixelRep *pixelPtr; + + string = Tcl_GetStringFromObj(objPtr, NULL); + + d = strtod(string, &rest); + if (rest == string) { + /* + * Must copy string before resetting the result in case a caller + * is trying to convert the interpreter's result to pixels. + */ + + char buf[100]; + + error: + sprintf(buf, "bad screen distance \"%.50s\"", string); + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, buf, NULL); + return TCL_ERROR; + } + while ((*rest != '\0') && isspace(UCHAR(*rest))) { + rest++; + } + switch (*rest) { + case '\0': + units = -1; + break; + + case 'm': + units = 0; + break; + + case 'c': + units = 1; + break; + + case 'i': + units = 2; + break; + + case 'p': + units = 3; + break; + + default: + goto error; + } + + /* + * Free the old internalRep before setting the new one. + */ + + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + + objPtr->typePtr = &pixelObjType; + + i = (int) d; + if ((units < 0) && (i == d)) { + SET_SIMPLEPIXEL(objPtr, i); + } else { + pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + pixelPtr->value = d; + pixelPtr->units = units; + pixelPtr->tkwin = NULL; + pixelPtr->returnValue = i; + SET_COMPLEXPIXEL(objPtr, pixelPtr); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_GetMMFromObj -- + * + * Attempt to return an mm value from the Tcl object "objPtr". If the + * object is not already an mm value, an attempt will be made to convert + * it to one. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in the interpreter's + * result unless "interp" is NULL. + * + * Side effects: + * If the object is not already a pixel, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetMMFromObj(interp, tkwin, objPtr, doublePtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tk_Window tkwin; + Tcl_Obj *objPtr; /* The object from which to get mms. */ + double *doublePtr; /* Place to store resulting millimeters. */ +{ + int result; + double d; + MMRep *mmPtr; + static double bias[] = { + 10.0, 25.4, 1.0, 25.4 / 72.0 + }; + + if (objPtr->typePtr != &mmObjType) { + result = SetMMFromAny(interp, objPtr); + if (result != TCL_OK) { + return result; + } + } + + mmPtr = (MMRep *) objPtr->internalRep.otherValuePtr; + if (mmPtr->tkwin != tkwin) { + d = mmPtr->value; + if (mmPtr->units == -1) { + d /= WidthOfScreen(Tk_Screen(tkwin)); + d *= WidthMMOfScreen(Tk_Screen(tkwin)); + } else { + d *= bias[mmPtr->units]; + } + mmPtr->tkwin = tkwin; + mmPtr->returnValue = d; + } + *doublePtr = mmPtr->returnValue; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * FreeMMInternalRep -- + * + * Deallocate the storage associated with a mm object's internal + * representation. + * + * Results: + * None. + * + * Side effects: + * Frees objPtr's internal representation and sets objPtr's + * internalRep to NULL. + * + *---------------------------------------------------------------------- + */ + +static void +FreeMMInternalRep(objPtr) + Tcl_Obj *objPtr; /* MM object with internal rep to free. */ +{ + ckfree((char *) objPtr->internalRep.otherValuePtr); + objPtr->internalRep.otherValuePtr = NULL; +} + +/* + *---------------------------------------------------------------------- + * + * DupMMInternalRep -- + * + * Initialize the internal representation of a pixel Tcl_Obj to a + * copy of the internal representation of an existing pixel object. + * + * Results: + * None. + * + * Side effects: + * copyPtr's internal rep is set to the pixel corresponding to + * srcPtr's internal rep. + * + *---------------------------------------------------------------------- + */ + +static void +DupMMInternalRep(srcPtr, copyPtr) + register Tcl_Obj *srcPtr; /* Object with internal rep to copy. */ + register Tcl_Obj *copyPtr; /* Object with internal rep to set. */ +{ + MMRep *oldPtr, *newPtr; + + copyPtr->typePtr = srcPtr->typePtr; + oldPtr = (MMRep *) srcPtr->internalRep.otherValuePtr; + newPtr = (MMRep *) ckalloc(sizeof(MMRep)); + newPtr->value = oldPtr->value; + newPtr->units = oldPtr->units; + newPtr->tkwin = oldPtr->tkwin; + newPtr->returnValue = oldPtr->returnValue; + copyPtr->internalRep.otherValuePtr = (VOID *) newPtr; +} + +/* + *---------------------------------------------------------------------- + * + * SetMMFromAny -- + * + * Attempt to generate a mm internal form for the Tcl object + * "objPtr". + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * If no error occurs, a mm representation of the object is + * stored internally and the type of "objPtr" is set to mm. + * + *---------------------------------------------------------------------- + */ + +static int +SetMMFromAny(interp, objPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + char *string, *rest; + double d; + int units; + MMRep *mmPtr; + + string = Tcl_GetStringFromObj(objPtr, NULL); + + d = strtod(string, &rest); + if (rest == string) { + /* + * Must copy string before resetting the result in case a caller + * is trying to convert the interpreter's result to mms. + */ + + error: + Tcl_AppendResult(interp, "bad screen distance \"", string, + "\"", (char *) NULL); + return TCL_ERROR; + } + while ((*rest != '\0') && isspace(UCHAR(*rest))) { + rest++; + } + switch (*rest) { + case '\0': + units = -1; + break; + + case 'c': + units = 0; + break; + + case 'i': + units = 1; + break; + + case 'm': + units = 2; + break; + + case 'p': + units = 3; + break; + + default: + goto error; + } + + /* + * Free the old internalRep before setting the new one. + */ + + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + + objPtr->typePtr = &mmObjType; + + mmPtr = (MMRep *) ckalloc(sizeof(MMRep)); + mmPtr->value = d; + mmPtr->units = units; + mmPtr->tkwin = NULL; + mmPtr->returnValue = d; + objPtr->internalRep.otherValuePtr = (VOID *) mmPtr; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TkGetWindowFromObj -- + * + * Attempt to return a Tk_Window from the Tcl object "objPtr". If the + * object is not already a Tk_Window, an attempt will be made to convert + * it to one. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in the interpreter's + * result unless "interp" is NULL. + * + * Side effects: + * If the object is not already a Tk_Window, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + Tk_Window tkwin; /* A token to get the main window from. */ + register Tcl_Obj *objPtr; /* The object from which to get boolean. */ + Tk_Window *windowPtr; /* Place to store resulting window. */ +{ + register int result; + Tk_Window lastWindow; + + result = SetWindowFromAny(interp, objPtr); + if (result != TCL_OK) { + return result; + } + + lastWindow = (Tk_Window) objPtr->internalRep.twoPtrValue.ptr1; + if (tkwin != lastWindow) { + Tk_Window foundWindow = Tk_NameToWindow(interp, + Tcl_GetStringFromObj(objPtr, NULL), tkwin); + + if (foundWindow == NULL) { + return TCL_ERROR; + } + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) tkwin; + objPtr->internalRep.twoPtrValue.ptr2 = (VOID *) foundWindow; + } + *windowPtr = (Tk_Window) objPtr->internalRep.twoPtrValue.ptr2; + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * SetWindowFromAny -- + * + * Attempt to generate a Tk_Window internal form for the Tcl object + * "objPtr". + * + * Results: + * The return value is a standard Tcl result. If an error occurs during + * conversion, an error message is left in the interpreter's result + * unless "interp" is NULL. + * + * Side effects: + * If no error occurs, a standard window value is stored as "objPtr"s + * internal representation and the type of "objPtr" is set to Tk_Window. + * + *---------------------------------------------------------------------- + */ + +static int +SetWindowFromAny(interp, objPtr) + Tcl_Interp *interp; /* Used for error reporting if not NULL. */ + register Tcl_Obj *objPtr; /* The object to convert. */ +{ + Tcl_ObjType *typePtr; + + /* + * Free the old internalRep before setting the new one. + */ + + Tcl_GetStringFromObj(objPtr, NULL); + typePtr = objPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(objPtr); + } + objPtr->typePtr = &windowObjType; + objPtr->internalRep.twoPtrValue.ptr1 = NULL; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; + + return TCL_OK; +} diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c new file mode 100644 index 0000000..4b783e6 --- /dev/null +++ b/generic/tkOldConfig.c @@ -0,0 +1,1000 @@ +/* + * tkOldConfig.c -- + * + * This file contains the Tk_ConfigureWidget procedure. THIS FILE + * IS HERE FOR BACKWARD COMPATIBILITY; THE NEW CONFIGURATION + * PACKAGE SHOULD BE USED FOR NEW PROJECTS. + * + * Copyright (c) 1990-1994 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tkOldConfig.c,v 1.2 1999/04/16 01:51:20 stanton Exp $ + */ + +#include "tkPort.h" +#include "tk.h" + +/* + * Values for "flags" field of Tk_ConfigSpec structures. Be sure + * to coordinate these values with those defined in tk.h + * (TK_CONFIG_COLOR_ONLY, etc.). There must not be overlap! + * + * INIT - Non-zero means (char *) things have been + * converted to Tk_Uid's. + */ + +#define INIT 0x20 + +/* + * Forward declarations for procedures defined later in this file: + */ + +static int DoConfig _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, Tk_ConfigSpec *specPtr, + Tk_Uid value, int valueIsUid, char *widgRec)); +static Tk_ConfigSpec * FindConfigSpec _ANSI_ARGS_((Tcl_Interp *interp, + Tk_ConfigSpec *specs, char *argvName, + int needFlags, int hateFlags)); +static char * FormatConfigInfo _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, Tk_ConfigSpec *specPtr, + char *widgRec)); +static char * FormatConfigValue _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, Tk_ConfigSpec *specPtr, + char *widgRec, char *buffer, + Tcl_FreeProc **freeProcPtr)); + +/* + *-------------------------------------------------------------- + * + * Tk_ConfigureWidget -- + * + * Process command-line options and database options to + * fill in fields of a widget record with resources and + * other parameters. + * + * Results: + * A standard Tcl return value. In case of an error, + * the interp's result will hold an error message. + * + * Side effects: + * The fields of widgRec get filled in with information + * from argc/argv and the option database. Old information + * in widgRec's fields gets recycled. + * + *-------------------------------------------------------------- + */ + +int +Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Window tkwin; /* Window containing widget (needed to + * set up X resources). */ + Tk_ConfigSpec *specs; /* Describes legal options. */ + int argc; /* Number of elements in argv. */ + char **argv; /* Command-line options. */ + char *widgRec; /* Record whose fields are to be + * modified. Values must be properly + * initialized. */ + int flags; /* Used to specify additional flags + * that must be present in config specs + * for them to be considered. Also, + * may have TK_CONFIG_ARGV_ONLY set. */ +{ + register Tk_ConfigSpec *specPtr; + Tk_Uid value; /* Value of option from database. */ + int needFlags; /* Specs must contain this set of flags + * or else they are not considered. */ + int hateFlags; /* If a spec contains any bits here, it's + * not considered. */ + + needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); + if (Tk_Depth(tkwin) <= 1) { + hateFlags = TK_CONFIG_COLOR_ONLY; + } else { + hateFlags = TK_CONFIG_MONO_ONLY; + } + + /* + * Pass one: scan through all the option specs, replacing strings + * with Tk_Uids (if this hasn't been done already) and clearing + * the TK_CONFIG_OPTION_SPECIFIED flags. + */ + + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + if (!(specPtr->specFlags & INIT) && (specPtr->argvName != NULL)) { + if (specPtr->dbName != NULL) { + specPtr->dbName = Tk_GetUid(specPtr->dbName); + } + if (specPtr->dbClass != NULL) { + specPtr->dbClass = Tk_GetUid(specPtr->dbClass); + } + if (specPtr->defValue != NULL) { + specPtr->defValue = Tk_GetUid(specPtr->defValue); + } + } + specPtr->specFlags = (specPtr->specFlags & ~TK_CONFIG_OPTION_SPECIFIED) + | INIT; + } + + /* + * Pass two: scan through all of the arguments, processing those + * that match entries in the specs. + */ + + for ( ; argc > 0; argc -= 2, argv += 2) { + specPtr = FindConfigSpec(interp, specs, *argv, needFlags, hateFlags); + if (specPtr == NULL) { + return TCL_ERROR; + } + + /* + * Process the entry. + */ + + if (argc < 2) { + Tcl_AppendResult(interp, "value for \"", *argv, + "\" missing", (char *) NULL); + return TCL_ERROR; + } + if (DoConfig(interp, tkwin, specPtr, argv[1], 0, widgRec) != TCL_OK) { + char msg[100]; + + sprintf(msg, "\n (processing \"%.40s\" option)", + specPtr->argvName); + Tcl_AddErrorInfo(interp, msg); + return TCL_ERROR; + } + specPtr->specFlags |= TK_CONFIG_OPTION_SPECIFIED; + } + + /* + * Pass three: scan through all of the specs again; if no + * command-line argument matched a spec, then check for info + * in the option database. If there was nothing in the + * database, then use the default. + */ + + if (!(flags & TK_CONFIG_ARGV_ONLY)) { + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED) + || (specPtr->argvName == NULL) + || (specPtr->type == TK_CONFIG_SYNONYM)) { + continue; + } + if (((specPtr->specFlags & needFlags) != needFlags) + || (specPtr->specFlags & hateFlags)) { + continue; + } + value = NULL; + if (specPtr->dbName != NULL) { + value = Tk_GetOption(tkwin, specPtr->dbName, specPtr->dbClass); + } + if (value != NULL) { + if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != + TCL_OK) { + char msg[200]; + + sprintf(msg, "\n (%s \"%.50s\" in widget \"%.50s\")", + "database entry for", + specPtr->dbName, Tk_PathName(tkwin)); + Tcl_AddErrorInfo(interp, msg); + return TCL_ERROR; + } + } else { + if (specPtr->defValue != NULL) { + value = Tk_GetUid(specPtr->defValue); + } else { + value = NULL; + } + if ((value != NULL) && !(specPtr->specFlags + & TK_CONFIG_DONT_SET_DEFAULT)) { + if (DoConfig(interp, tkwin, specPtr, value, 1, widgRec) != + TCL_OK) { + char msg[200]; + + sprintf(msg, + "\n (%s \"%.50s\" in widget \"%.50s\")", + "default value for", + specPtr->dbName, Tk_PathName(tkwin)); + Tcl_AddErrorInfo(interp, msg); + return TCL_ERROR; + } + } + } + } + } + + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * FindConfigSpec -- + * + * Search through a table of configuration specs, looking for + * one that matches a given argvName. + * + * Results: + * The return value is a pointer to the matching entry, or NULL + * if nothing matched. In that case an error message is left + * in the interp's result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +static Tk_ConfigSpec * +FindConfigSpec(interp, specs, argvName, needFlags, hateFlags) + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_ConfigSpec *specs; /* Pointer to table of configuration + * specifications for a widget. */ + char *argvName; /* Name (suitable for use in a "config" + * command) identifying particular option. */ + int needFlags; /* Flags that must be present in matching + * entry. */ + int hateFlags; /* Flags that must NOT be present in + * matching entry. */ +{ + register Tk_ConfigSpec *specPtr; + register char c; /* First character of current argument. */ + Tk_ConfigSpec *matchPtr; /* Matching spec, or NULL. */ + size_t length; + + c = argvName[1]; + length = strlen(argvName); + matchPtr = NULL; + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + if (specPtr->argvName == NULL) { + continue; + } + if ((specPtr->argvName[1] != c) + || (strncmp(specPtr->argvName, argvName, length) != 0)) { + continue; + } + if (((specPtr->specFlags & needFlags) != needFlags) + || (specPtr->specFlags & hateFlags)) { + continue; + } + if (specPtr->argvName[length] == 0) { + matchPtr = specPtr; + goto gotMatch; + } + if (matchPtr != NULL) { + Tcl_AppendResult(interp, "ambiguous option \"", argvName, + "\"", (char *) NULL); + return (Tk_ConfigSpec *) NULL; + } + matchPtr = specPtr; + } + + if (matchPtr == NULL) { + Tcl_AppendResult(interp, "unknown option \"", argvName, + "\"", (char *) NULL); + return (Tk_ConfigSpec *) NULL; + } + + /* + * Found a matching entry. If it's a synonym, then find the + * entry that it's a synonym for. + */ + + gotMatch: + specPtr = matchPtr; + if (specPtr->type == TK_CONFIG_SYNONYM) { + for (specPtr = specs; ; specPtr++) { + if (specPtr->type == TK_CONFIG_END) { + Tcl_AppendResult(interp, + "couldn't find synonym for option \"", + argvName, "\"", (char *) NULL); + return (Tk_ConfigSpec *) NULL; + } + if ((specPtr->dbName == matchPtr->dbName) + && (specPtr->type != TK_CONFIG_SYNONYM) + && ((specPtr->specFlags & needFlags) == needFlags) + && !(specPtr->specFlags & hateFlags)) { + break; + } + } + } + return specPtr; +} + +/* + *-------------------------------------------------------------- + * + * DoConfig -- + * + * This procedure applies a single configuration option + * to a widget record. + * + * Results: + * A standard Tcl return value. + * + * Side effects: + * WidgRec is modified as indicated by specPtr and value. + * The old value is recycled, if that is appropriate for + * the value type. + * + *-------------------------------------------------------------- + */ + +static int +DoConfig(interp, tkwin, specPtr, value, valueIsUid, widgRec) + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Window tkwin; /* Window containing widget (needed to + * set up X resources). */ + Tk_ConfigSpec *specPtr; /* Specifier to apply. */ + char *value; /* Value to use to fill in widgRec. */ + int valueIsUid; /* Non-zero means value is a Tk_Uid; + * zero means it's an ordinary string. */ + char *widgRec; /* Record whose fields are to be + * modified. Values must be properly + * initialized. */ +{ + char *ptr; + Tk_Uid uid; + int nullValue; + + nullValue = 0; + if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { + nullValue = 1; + } + + do { + ptr = widgRec + specPtr->offset; + switch (specPtr->type) { + case TK_CONFIG_BOOLEAN: + if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_INT: + if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_DOUBLE: + if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_STRING: { + char *old, *new; + + if (nullValue) { + new = NULL; + } else { + new = (char *) ckalloc((unsigned) (strlen(value) + 1)); + strcpy(new, value); + } + old = *((char **) ptr); + if (old != NULL) { + ckfree(old); + } + *((char **) ptr) = new; + break; + } + case TK_CONFIG_UID: + if (nullValue) { + *((Tk_Uid *) ptr) = NULL; + } else { + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + *((Tk_Uid *) ptr) = uid; + } + break; + case TK_CONFIG_COLOR: { + XColor *newPtr, *oldPtr; + + if (nullValue) { + newPtr = NULL; + } else { + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + newPtr = Tk_GetColor(interp, tkwin, uid); + if (newPtr == NULL) { + return TCL_ERROR; + } + } + oldPtr = *((XColor **) ptr); + if (oldPtr != NULL) { + Tk_FreeColor(oldPtr); + } + *((XColor **) ptr) = newPtr; + break; + } + case TK_CONFIG_FONT: { + Tk_Font new; + + if (nullValue) { + new = NULL; + } else { + new = Tk_GetFont(interp, tkwin, value); + if (new == NULL) { + return TCL_ERROR; + } + } + Tk_FreeFont(*((Tk_Font *) ptr)); + *((Tk_Font *) ptr) = new; + break; + } + case TK_CONFIG_BITMAP: { + Pixmap new, old; + + if (nullValue) { + new = None; + } else { + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + new = Tk_GetBitmap(interp, tkwin, uid); + if (new == None) { + return TCL_ERROR; + } + } + old = *((Pixmap *) ptr); + if (old != None) { + Tk_FreeBitmap(Tk_Display(tkwin), old); + } + *((Pixmap *) ptr) = new; + break; + } + case TK_CONFIG_BORDER: { + Tk_3DBorder new, old; + + if (nullValue) { + new = NULL; + } else { + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + new = Tk_Get3DBorder(interp, tkwin, uid); + if (new == NULL) { + return TCL_ERROR; + } + } + old = *((Tk_3DBorder *) ptr); + if (old != NULL) { + Tk_Free3DBorder(old); + } + *((Tk_3DBorder *) ptr) = new; + break; + } + case TK_CONFIG_RELIEF: + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_CURSOR: + case TK_CONFIG_ACTIVE_CURSOR: { + Tk_Cursor new, old; + + if (nullValue) { + new = None; + } else { + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + new = Tk_GetCursor(interp, tkwin, uid); + if (new == None) { + return TCL_ERROR; + } + } + old = *((Tk_Cursor *) ptr); + if (old != None) { + Tk_FreeCursor(Tk_Display(tkwin), old); + } + *((Tk_Cursor *) ptr) = new; + if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) { + Tk_DefineCursor(tkwin, new); + } + break; + } + case TK_CONFIG_JUSTIFY: + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_ANCHOR: + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_CAP_STYLE: + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_JOIN_STYLE: + uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value); + if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_PIXELS: + if (Tk_GetPixels(interp, tkwin, value, (int *) ptr) + != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_MM: + if (Tk_GetScreenMM(interp, tkwin, value, (double *) ptr) + != TCL_OK) { + return TCL_ERROR; + } + break; + case TK_CONFIG_WINDOW: { + Tk_Window tkwin2; + + if (nullValue) { + tkwin2 = NULL; + } else { + tkwin2 = Tk_NameToWindow(interp, value, tkwin); + if (tkwin2 == NULL) { + return TCL_ERROR; + } + } + *((Tk_Window *) ptr) = tkwin2; + break; + } + case TK_CONFIG_CUSTOM: + if ((*specPtr->customPtr->parseProc)( + specPtr->customPtr->clientData, interp, tkwin, + value, widgRec, specPtr->offset) != TCL_OK) { + return TCL_ERROR; + } + break; + default: { + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "bad config table: unknown type %d", + specPtr->type); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_ERROR; + } + } + specPtr++; + } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END)); + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * Tk_ConfigureInfo -- + * + * Return information about the configuration options + * for a window, and their current values. + * + * Results: + * Always returns TCL_OK. The interp's result will be modified + * hold a description of either a single configuration option + * available for "widgRec" via "specs", or all the configuration + * options available. In the "all" case, the result will + * available for "widgRec" via "specs". The result will + * be a list, each of whose entries describes one option. + * Each entry will itself be a list containing the option's + * name for use on command lines, database name, database + * class, default value, and current value (empty string + * if none). For options that are synonyms, the list will + * contain only two values: name and synonym name. If the + * "name" argument is non-NULL, then the only information + * returned is that for the named argument (i.e. the corresponding + * entry in the overall list is returned). + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int +Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Window tkwin; /* Window corresponding to widgRec. */ + Tk_ConfigSpec *specs; /* Describes legal options. */ + char *widgRec; /* Record whose fields contain current + * values for options. */ + char *argvName; /* If non-NULL, indicates a single option + * whose info is to be returned. Otherwise + * info is returned for all options. */ + int flags; /* Used to specify additional flags + * that must be present in config specs + * for them to be considered. */ +{ + register Tk_ConfigSpec *specPtr; + int needFlags, hateFlags; + char *list; + char *leader = "{"; + + needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); + if (Tk_Depth(tkwin) <= 1) { + hateFlags = TK_CONFIG_COLOR_ONLY; + } else { + hateFlags = TK_CONFIG_MONO_ONLY; + } + + /* + * If information is only wanted for a single configuration + * spec, then handle that one spec specially. + */ + + Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); + if (argvName != NULL) { + specPtr = FindConfigSpec(interp, specs, argvName, needFlags, + hateFlags); + if (specPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetResult(interp, + FormatConfigInfo(interp, tkwin, specPtr, widgRec), + TCL_DYNAMIC); + return TCL_OK; + } + + /* + * Loop through all the specs, creating a big list with all + * their information. + */ + + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + if ((argvName != NULL) && (specPtr->argvName != argvName)) { + continue; + } + if (((specPtr->specFlags & needFlags) != needFlags) + || (specPtr->specFlags & hateFlags)) { + continue; + } + if (specPtr->argvName == NULL) { + continue; + } + list = FormatConfigInfo(interp, tkwin, specPtr, widgRec); + Tcl_AppendResult(interp, leader, list, "}", (char *) NULL); + ckfree(list); + leader = " {"; + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------- + * + * FormatConfigInfo -- + * + * Create a valid Tcl list holding the configuration information + * for a single configuration option. + * + * Results: + * A Tcl list, dynamically allocated. The caller is expected to + * arrange for this list to be freed eventually. + * + * Side effects: + * Memory is allocated. + * + *-------------------------------------------------------------- + */ + +static char * +FormatConfigInfo(interp, tkwin, specPtr, widgRec) + Tcl_Interp *interp; /* Interpreter to use for things + * like floating-point precision. */ + Tk_Window tkwin; /* Window corresponding to widget. */ + register Tk_ConfigSpec *specPtr; /* Pointer to information describing + * option. */ + char *widgRec; /* Pointer to record holding current + * values of info for widget. */ +{ + char *argv[6], *result; + char buffer[200]; + Tcl_FreeProc *freeProc = (Tcl_FreeProc *) NULL; + + argv[0] = specPtr->argvName; + argv[1] = specPtr->dbName; + argv[2] = specPtr->dbClass; + argv[3] = specPtr->defValue; + if (specPtr->type == TK_CONFIG_SYNONYM) { + return Tcl_Merge(2, argv); + } + argv[4] = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, + &freeProc); + if (argv[1] == NULL) { + argv[1] = ""; + } + if (argv[2] == NULL) { + argv[2] = ""; + } + if (argv[3] == NULL) { + argv[3] = ""; + } + if (argv[4] == NULL) { + argv[4] = ""; + } + result = Tcl_Merge(5, argv); + if (freeProc != NULL) { + if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) { + ckfree(argv[4]); + } else { + (*freeProc)(argv[4]); + } + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * FormatConfigValue -- + * + * This procedure formats the current value of a configuration + * option. + * + * Results: + * The return value is the formatted value of the option given + * by specPtr and widgRec. If the value is static, so that it + * need not be freed, *freeProcPtr will be set to NULL; otherwise + * *freeProcPtr will be set to the address of a procedure to + * free the result, and the caller must invoke this procedure + * when it is finished with the result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static char * +FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer, freeProcPtr) + Tcl_Interp *interp; /* Interpreter for use in real conversions. */ + Tk_Window tkwin; /* Window corresponding to widget. */ + Tk_ConfigSpec *specPtr; /* Pointer to information describing option. + * Must not point to a synonym option. */ + char *widgRec; /* Pointer to record holding current + * values of info for widget. */ + char *buffer; /* Static buffer to use for small values. + * Must have at least 200 bytes of storage. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to word to fill in with address + * of procedure to free the result, or NULL + * if result is static. */ +{ + char *ptr, *result; + + *freeProcPtr = NULL; + ptr = widgRec + specPtr->offset; + result = ""; + switch (specPtr->type) { + case TK_CONFIG_BOOLEAN: + if (*((int *) ptr) == 0) { + result = "0"; + } else { + result = "1"; + } + break; + case TK_CONFIG_INT: + sprintf(buffer, "%d", *((int *) ptr)); + result = buffer; + break; + case TK_CONFIG_DOUBLE: + Tcl_PrintDouble(interp, *((double *) ptr), buffer); + result = buffer; + break; + case TK_CONFIG_STRING: + result = (*(char **) ptr); + if (result == NULL) { + result = ""; + } + break; + case TK_CONFIG_UID: { + Tk_Uid uid = *((Tk_Uid *) ptr); + if (uid != NULL) { + result = uid; + } + break; + } + case TK_CONFIG_COLOR: { + XColor *colorPtr = *((XColor **) ptr); + if (colorPtr != NULL) { + result = Tk_NameOfColor(colorPtr); + } + break; + } + case TK_CONFIG_FONT: { + Tk_Font tkfont = *((Tk_Font *) ptr); + if (tkfont != NULL) { + result = Tk_NameOfFont(tkfont); + } + break; + } + case TK_CONFIG_BITMAP: { + Pixmap pixmap = *((Pixmap *) ptr); + if (pixmap != None) { + result = Tk_NameOfBitmap(Tk_Display(tkwin), pixmap); + } + break; + } + case TK_CONFIG_BORDER: { + Tk_3DBorder border = *((Tk_3DBorder *) ptr); + if (border != NULL) { + result = Tk_NameOf3DBorder(border); + } + break; + } + case TK_CONFIG_RELIEF: + result = Tk_NameOfRelief(*((int *) ptr)); + break; + case TK_CONFIG_CURSOR: + case TK_CONFIG_ACTIVE_CURSOR: { + Tk_Cursor cursor = *((Tk_Cursor *) ptr); + if (cursor != None) { + result = Tk_NameOfCursor(Tk_Display(tkwin), cursor); + } + break; + } + case TK_CONFIG_JUSTIFY: + result = Tk_NameOfJustify(*((Tk_Justify *) ptr)); + break; + case TK_CONFIG_ANCHOR: + result = Tk_NameOfAnchor(*((Tk_Anchor *) ptr)); + break; + case TK_CONFIG_CAP_STYLE: + result = Tk_NameOfCapStyle(*((int *) ptr)); + break; + case TK_CONFIG_JOIN_STYLE: + result = Tk_NameOfJoinStyle(*((int *) ptr)); + break; + case TK_CONFIG_PIXELS: + sprintf(buffer, "%d", *((int *) ptr)); + result = buffer; + break; + case TK_CONFIG_MM: + Tcl_PrintDouble(interp, *((double *) ptr), buffer); + result = buffer; + break; + case TK_CONFIG_WINDOW: { + Tk_Window tkwin; + + tkwin = *((Tk_Window *) ptr); + if (tkwin != NULL) { + result = Tk_PathName(tkwin); + } + break; + } + case TK_CONFIG_CUSTOM: + result = (*specPtr->customPtr->printProc)( + specPtr->customPtr->clientData, tkwin, widgRec, + specPtr->offset, freeProcPtr); + break; + default: + result = "?? unknown type ??"; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_ConfigureValue -- + * + * This procedure returns the current value of a configuration + * option for a widget. + * + * Results: + * The return value is a standard Tcl completion code (TCL_OK or + * TCL_ERROR). The interp's result will be set to hold either the value + * of the option given by argvName (if TCL_OK is returned) or + * an error message (if TCL_ERROR is returned). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags) + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Window tkwin; /* Window corresponding to widgRec. */ + Tk_ConfigSpec *specs; /* Describes legal options. */ + char *widgRec; /* Record whose fields contain current + * values for options. */ + char *argvName; /* Gives the command-line name for the + * option whose value is to be returned. */ + int flags; /* Used to specify additional flags + * that must be present in config specs + * for them to be considered. */ +{ + Tk_ConfigSpec *specPtr; + int needFlags, hateFlags; + + needFlags = flags & ~(TK_CONFIG_USER_BIT - 1); + if (Tk_Depth(tkwin) <= 1) { + hateFlags = TK_CONFIG_COLOR_ONLY; + } else { + hateFlags = TK_CONFIG_MONO_ONLY; + } + specPtr = FindConfigSpec(interp, specs, argvName, needFlags, hateFlags); + if (specPtr == NULL) { + return TCL_ERROR; + } + interp->result = FormatConfigValue(interp, tkwin, specPtr, widgRec, + interp->result, &interp->freeProc); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Tk_FreeOptions -- + * + * Free up all resources associated with configuration options. + * + * Results: + * None. + * + * Side effects: + * Any resource in widgRec that is controlled by a configuration + * option (e.g. a Tk_3DBorder or XColor) is freed in the appropriate + * fashion. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +void +Tk_FreeOptions(specs, widgRec, display, needFlags) + Tk_ConfigSpec *specs; /* Describes legal options. */ + char *widgRec; /* Record whose fields contain current + * values for options. */ + Display *display; /* X display; needed for freeing some + * resources. */ + int needFlags; /* Used to specify additional flags + * that must be present in config specs + * for them to be considered. */ +{ + register Tk_ConfigSpec *specPtr; + char *ptr; + + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + if ((specPtr->specFlags & needFlags) != needFlags) { + continue; + } + ptr = widgRec + specPtr->offset; + switch (specPtr->type) { + case TK_CONFIG_STRING: + if (*((char **) ptr) != NULL) { + ckfree(*((char **) ptr)); + *((char **) ptr) = NULL; + } + break; + case TK_CONFIG_COLOR: + if (*((XColor **) ptr) != NULL) { + Tk_FreeColor(*((XColor **) ptr)); + *((XColor **) ptr) = NULL; + } + break; + case TK_CONFIG_FONT: + Tk_FreeFont(*((Tk_Font *) ptr)); + *((Tk_Font *) ptr) = NULL; + break; + case TK_CONFIG_BITMAP: + if (*((Pixmap *) ptr) != None) { + Tk_FreeBitmap(display, *((Pixmap *) ptr)); + *((Pixmap *) ptr) = None; + } + break; + case TK_CONFIG_BORDER: + if (*((Tk_3DBorder *) ptr) != NULL) { + Tk_Free3DBorder(*((Tk_3DBorder *) ptr)); + *((Tk_3DBorder *) ptr) = NULL; + } + break; + case TK_CONFIG_CURSOR: + case TK_CONFIG_ACTIVE_CURSOR: + if (*((Tk_Cursor *) ptr) != None) { + Tk_FreeCursor(display, *((Tk_Cursor *) ptr)); + *((Tk_Cursor *) ptr) = None; + } + } + } +} diff --git a/generic/tkOption.c b/generic/tkOption.c index 9b7e17d..689723e 100644 --- a/generic/tkOption.c +++ b/generic/tkOption.c @@ -6,12 +6,12 @@ * with windows either by name or by class or both. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkOption.c,v 1.2 1998/09/14 18:23:15 stanton Exp $ + * RCS: @(#) $Id: tkOption.c,v 1.3 1999/04/16 01:51:20 stanton Exp $ */ #include "tkPort.h" @@ -141,13 +141,6 @@ typedef struct ElArray { */ #define NUM_STACKS 8 -static ElArray *stacks[NUM_STACKS]; -static TkWindow *cachedWindow = NULL; /* Lowest-level window currently - * loaded in stacks at present. - * NULL means stacks have never - * been used, or have been - * invalidated because of a change - * to the database. */ /* * One of the following structures is used to keep track of each @@ -163,33 +156,41 @@ typedef struct StackLevel { * fields when popping out of a level. */ } StackLevel; -/* - * Information about all of the stack levels that are currently - * active. This array grows dynamically to become as large as needed. - */ +typedef struct ThreadSpecificData { + int initialized; /* 0 means the ThreadSpecific Data structure + * for the current thread needs to be + * initialized. */ + ElArray *stacks[NUM_STACKS]; + TkWindow *cachedWindow; + /* Lowest-level window currently + * loaded in stacks at present. + * NULL means stacks have never + * been used, or have been + * invalidated because of a change + * to the database. */ + /* + * Information about all of the stack levels that are currently + * active. This array grows dynamically to become as large as needed. + */ -static StackLevel *levels = NULL; - /* Array describing current stack. */ -static int numLevels = 0; /* Total space allocated. */ -static int curLevel = -1; /* Highest level currently in use. Note: + StackLevel *levels; /* Array describing current stack. */ + int numLevels; /* Total space allocated. */ + int curLevel; /* Highest level currently in use. Note: * curLevel is never 0! (I don't remember * why anymore...) */ + /* + * The variable below is a serial number for all options entered into + * the database so far. It increments on each addition to the option + * database. It is used in computing option priorities, so that the + * most recent entry wins when choosing between options at the same + * priority level. + */ -/* - * The variable below is a serial number for all options entered into - * the database so far. It increments on each addition to the option - * database. It is used in computing option priorities, so that the - * most recent entry wins when choosing between options at the same - * priority level. - */ - -static int serial = 0; - -/* - * Special "no match" Element to use as default for searches. - */ - -static Element defaultMatch; + int serial; + Element defaultMatch; /* Special "no match" Element to use as + * default for searches.*/ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Forward declarations for procedures defined in this file: @@ -248,11 +249,13 @@ Tk_AddOption(tkwin, name, value, priority) int count, firstField, length; #define TMP_SIZE 100 char tmp[TMP_SIZE+1]; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->mainPtr->optionRootPtr == NULL) { OptionInit(winPtr->mainPtr); } - cachedWindow = NULL; /* Invalidate the cache. */ + tsdPtr->cachedWindow = NULL; /* Invalidate the cache. */ /* * Compute the priority for the new element, including both the @@ -265,8 +268,8 @@ Tk_AddOption(tkwin, name, value, priority) } else if (priority > TK_MAX_PRIO) { priority = TK_MAX_PRIO; } - newEl.priority = (priority << 24) + serial; - serial++; + newEl.priority = (priority << 24) + tsdPtr->serial; + tsdPtr->serial++; /* * Parse the option one field at a time. @@ -396,28 +399,30 @@ Tk_GetOption(tkwin, name, className) Tk_Uid nameId, classId; register Element *elPtr, *bestPtr; register int count; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Note: no need to call OptionInit here: it will be done by * the SetupStacks call below (squeeze out those nanoseconds). */ - if (tkwin != (Tk_Window) cachedWindow) { + if (tkwin != (Tk_Window) tsdPtr->cachedWindow) { SetupStacks((TkWindow *) tkwin, 1); } nameId = Tk_GetUid(name); - bestPtr = &defaultMatch; - for (elPtr = stacks[EXACT_LEAF_NAME]->els, - count = stacks[EXACT_LEAF_NAME]->numUsed; count > 0; + bestPtr = &tsdPtr->defaultMatch; + for (elPtr = tsdPtr->stacks[EXACT_LEAF_NAME]->els, + count = tsdPtr->stacks[EXACT_LEAF_NAME]->numUsed; count > 0; elPtr++, count--) { if ((elPtr->nameUid == nameId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; } } - for (elPtr = stacks[WILDCARD_LEAF_NAME]->els, - count = stacks[WILDCARD_LEAF_NAME]->numUsed; count > 0; + for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_NAME]->els, + count = tsdPtr->stacks[WILDCARD_LEAF_NAME]->numUsed; count > 0; elPtr++, count--) { if ((elPtr->nameUid == nameId) && (elPtr->priority > bestPtr->priority)) { @@ -426,17 +431,17 @@ Tk_GetOption(tkwin, name, className) } if (className != NULL) { classId = Tk_GetUid(className); - for (elPtr = stacks[EXACT_LEAF_CLASS]->els, - count = stacks[EXACT_LEAF_CLASS]->numUsed; count > 0; + for (elPtr = tsdPtr->stacks[EXACT_LEAF_CLASS]->els, + count = tsdPtr->stacks[EXACT_LEAF_CLASS]->numUsed; count > 0; elPtr++, count--) { if ((elPtr->nameUid == classId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; } } - for (elPtr = stacks[WILDCARD_LEAF_CLASS]->els, - count = stacks[WILDCARD_LEAF_CLASS]->numUsed; count > 0; - elPtr++, count--) { + for (elPtr = tsdPtr->stacks[WILDCARD_LEAF_CLASS]->els, + count = tsdPtr->stacks[WILDCARD_LEAF_CLASS]->numUsed; + count > 0; elPtr++, count--) { if ((elPtr->nameUid == classId) && (elPtr->priority > bestPtr->priority)) { bestPtr = elPtr; @@ -474,6 +479,8 @@ Tk_OptionCmd(clientData, interp, argc, argv) Tk_Window tkwin = (Tk_Window) clientData; size_t length; char c; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -513,7 +520,7 @@ Tk_OptionCmd(clientData, interp, argc, argv) ClearOptionTree(mainPtr->optionRootPtr); mainPtr->optionRootPtr = NULL; } - cachedWindow = NULL; + tsdPtr->cachedWindow = NULL; return TCL_OK; } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { Tk_Window window; @@ -530,7 +537,7 @@ Tk_OptionCmd(clientData, interp, argc, argv) } value = Tk_GetOption(window, argv[3], argv[4]); if (value != NULL) { - interp->result = value; + Tcl_SetResult(interp, value, TCL_STATIC); } return TCL_OK; } else if ((c == 'r') && (strncmp(argv[1], "readfile", length) == 0)) { @@ -581,6 +588,9 @@ void TkOptionDeadWindow(winPtr) register TkWindow *winPtr; /* Window to be cleaned up. */ { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + /* * If this window is in the option stacks, then clear the stacks. */ @@ -588,11 +598,11 @@ TkOptionDeadWindow(winPtr) if (winPtr->optionLevel != -1) { int i; - for (i = 1; i <= curLevel; i++) { - levels[i].winPtr->optionLevel = -1; + for (i = 1; i <= tsdPtr->curLevel; i++) { + tsdPtr->levels[i].winPtr->optionLevel = -1; } - curLevel = -1; - cachedWindow = NULL; + tsdPtr->curLevel = -1; + tsdPtr->cachedWindow = NULL; } /* @@ -632,6 +642,8 @@ TkOptionClassChanged(winPtr) { int i, j, *basePtr; ElArray *arrayPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->optionLevel == -1) { return; @@ -642,22 +654,22 @@ TkOptionClassChanged(winPtr) * flush all of the levels above the matching one. */ - for (i = 1; i <= curLevel; i++) { - if (levels[i].winPtr == winPtr) { - for (j = i; j <= curLevel; j++) { - levels[j].winPtr->optionLevel = -1; + for (i = 1; i <= tsdPtr->curLevel; i++) { + if (tsdPtr->levels[i].winPtr == winPtr) { + for (j = i; j <= tsdPtr->curLevel; j++) { + tsdPtr->levels[j].winPtr->optionLevel = -1; } - curLevel = i-1; - basePtr = levels[i].bases; + tsdPtr->curLevel = i-1; + basePtr = tsdPtr->levels[i].bases; for (j = 0; j < NUM_STACKS; j++) { - arrayPtr = stacks[j]; + arrayPtr = tsdPtr->stacks[j]; arrayPtr->numUsed = basePtr[j]; arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed]; } - if (curLevel <= 0) { - cachedWindow = NULL; + if (tsdPtr->curLevel <= 0) { + tsdPtr->cachedWindow = NULL; } else { - cachedWindow = levels[curLevel].winPtr; + tsdPtr->cachedWindow = tsdPtr->levels[tsdPtr->curLevel].winPtr; } break; } @@ -674,7 +686,7 @@ TkOptionClassChanged(winPtr) * Results: * The return value is the integer priority level corresponding * to string, or -1 if string doesn't point to a valid priority level. - * In this case, an error message is left in interp->result. + * In this case, an error message is left in the interp's result. * * Side effects: * None. @@ -734,7 +746,7 @@ ParsePriority(interp, string) * Results: * The return value is a standard Tcl return code. In the case of * an error in parsing string, TCL_ERROR will be returned and an - * error message will be left in interp->result. The memory at + * error message will be left in the interp's result. The memory at * string is totally trashed by this procedure. If you care about * its contents, make a copy before calling here. * @@ -797,8 +809,10 @@ AddFromString(interp, tkwin, string, priority) dst = name = src; while (*src != ':') { if ((*src == '\0') || (*src == '\n')) { - sprintf(interp->result, "missing colon on line %d", - lineNum); + char buf[32 + TCL_INTEGER_SPACE]; + + sprintf(buf, "missing colon on line %d", lineNum); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } if ((src[0] == '\\') && (src[1] == '\n')) { @@ -830,7 +844,10 @@ AddFromString(interp, tkwin, string, priority) src++; } if (*src == '\0') { - sprintf(interp->result, "missing value on line %d", lineNum); + char buf[32 + TCL_INTEGER_SPACE]; + + sprintf(buf, "missing value on line %d", lineNum); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } @@ -842,8 +859,10 @@ AddFromString(interp, tkwin, string, priority) dst = value = src; while (*src != '\n') { if (*src == '\0') { - sprintf(interp->result, "missing newline on line %d", - lineNum); + char buf[32 + TCL_INTEGER_SPACE]; + + sprintf(buf, "missing newline on line %d", lineNum); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } if ((src[0] == '\\') && (src[1] == '\n')) { @@ -879,7 +898,7 @@ AddFromString(interp, tkwin, string, priority) * Results: * The return value is a standard Tcl return code. In the case of * an error in parsing string, TCL_ERROR will be returned and an - * error message will be left in interp->result. + * error message will be left in the interp's result. * * Side effects: * None. @@ -1062,6 +1081,8 @@ SetupStacks(winPtr, leaf) int level, i, *iPtr; register StackLevel *levelPtr; register ElArray *arrayPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * The following array defines the order in which the current @@ -1086,7 +1107,7 @@ SetupStacks(winPtr, leaf) if (winPtr->parentPtr != NULL) { level = winPtr->parentPtr->optionLevel; - if ((level == -1) || (cachedWindow == NULL)) { + if ((level == -1) || (tsdPtr->cachedWindow == NULL)) { SetupStacks(winPtr->parentPtr, 0); level = winPtr->parentPtr->optionLevel; } @@ -1100,19 +1121,19 @@ SetupStacks(winPtr, leaf) * mark those windows as no longer having cached information. */ - if (curLevel >= level) { - while (curLevel >= level) { - levels[curLevel].winPtr->optionLevel = -1; - curLevel--; + if (tsdPtr->curLevel >= level) { + while (tsdPtr->curLevel >= level) { + tsdPtr->levels[tsdPtr->curLevel].winPtr->optionLevel = -1; + tsdPtr->curLevel--; } - levelPtr = &levels[level]; + levelPtr = &tsdPtr->levels[level]; for (i = 0; i < NUM_STACKS; i++) { - arrayPtr = stacks[i]; + arrayPtr = tsdPtr->stacks[i]; arrayPtr->numUsed = levelPtr->bases[i]; arrayPtr->nextToUse = &arrayPtr->els[arrayPtr->numUsed]; } } - curLevel = winPtr->optionLevel = level; + tsdPtr->curLevel = winPtr->optionLevel = level; /* * Step 3: if the root database information isn't loaded or @@ -1120,11 +1141,11 @@ SetupStacks(winPtr, leaf) * database root (this only happens if winPtr is a main window). */ - if ((curLevel == 1) - && ((cachedWindow == NULL) - || (cachedWindow->mainPtr != winPtr->mainPtr))) { + if ((tsdPtr->curLevel == 1) + && ((tsdPtr->cachedWindow == NULL) + || (tsdPtr->cachedWindow->mainPtr != winPtr->mainPtr))) { for (i = 0; i < NUM_STACKS; i++) { - arrayPtr = stacks[i]; + arrayPtr = tsdPtr->stacks[i]; arrayPtr->numUsed = 0; arrayPtr->nextToUse = arrayPtr->els; } @@ -1138,33 +1159,41 @@ SetupStacks(winPtr, leaf) * any more). */ - if (curLevel >= numLevels) { + if (tsdPtr->curLevel >= tsdPtr->numLevels) { StackLevel *newLevels; newLevels = (StackLevel *) ckalloc((unsigned) - (numLevels*2*sizeof(StackLevel))); - memcpy((VOID *) newLevels, (VOID *) levels, - (numLevels*sizeof(StackLevel))); - ckfree((char *) levels); - numLevels *= 2; - levels = newLevels; + (tsdPtr->numLevels*2*sizeof(StackLevel))); + memcpy((VOID *) newLevels, (VOID *) tsdPtr->levels, + (tsdPtr->numLevels*sizeof(StackLevel))); + ckfree((char *) tsdPtr->levels); + tsdPtr->numLevels *= 2; + tsdPtr->levels = newLevels; } - levelPtr = &levels[curLevel]; + levelPtr = &tsdPtr->levels[tsdPtr->curLevel]; levelPtr->winPtr = winPtr; - arrayPtr = stacks[EXACT_LEAF_NAME]; + arrayPtr = tsdPtr->stacks[EXACT_LEAF_NAME]; arrayPtr->numUsed = 0; arrayPtr->nextToUse = arrayPtr->els; - arrayPtr = stacks[EXACT_LEAF_CLASS]; + arrayPtr = tsdPtr->stacks[EXACT_LEAF_CLASS]; arrayPtr->numUsed = 0; arrayPtr->nextToUse = arrayPtr->els; - levelPtr->bases[EXACT_LEAF_NAME] = stacks[EXACT_LEAF_NAME]->numUsed; - levelPtr->bases[EXACT_LEAF_CLASS] = stacks[EXACT_LEAF_CLASS]->numUsed; - levelPtr->bases[EXACT_NODE_NAME] = stacks[EXACT_NODE_NAME]->numUsed; - levelPtr->bases[EXACT_NODE_CLASS] = stacks[EXACT_NODE_CLASS]->numUsed; - levelPtr->bases[WILDCARD_LEAF_NAME] = stacks[WILDCARD_LEAF_NAME]->numUsed; - levelPtr->bases[WILDCARD_LEAF_CLASS] = stacks[WILDCARD_LEAF_CLASS]->numUsed; - levelPtr->bases[WILDCARD_NODE_NAME] = stacks[WILDCARD_NODE_NAME]->numUsed; - levelPtr->bases[WILDCARD_NODE_CLASS] = stacks[WILDCARD_NODE_CLASS]->numUsed; + levelPtr->bases[EXACT_LEAF_NAME] = tsdPtr->stacks[EXACT_LEAF_NAME] + ->numUsed; + levelPtr->bases[EXACT_LEAF_CLASS] = tsdPtr->stacks[EXACT_LEAF_CLASS] + ->numUsed; + levelPtr->bases[EXACT_NODE_NAME] = tsdPtr->stacks[EXACT_NODE_NAME] + ->numUsed; + levelPtr->bases[EXACT_NODE_CLASS] = tsdPtr->stacks[EXACT_NODE_CLASS] + ->numUsed; + levelPtr->bases[WILDCARD_LEAF_NAME] = tsdPtr->stacks[WILDCARD_LEAF_NAME] + ->numUsed; + levelPtr->bases[WILDCARD_LEAF_CLASS] = tsdPtr->stacks[WILDCARD_LEAF_CLASS] + ->numUsed; + levelPtr->bases[WILDCARD_NODE_NAME] = tsdPtr->stacks[WILDCARD_NODE_NAME] + ->numUsed; + levelPtr->bases[WILDCARD_NODE_CLASS] = tsdPtr->stacks[WILDCARD_NODE_CLASS] + ->numUsed; /* @@ -1184,7 +1213,7 @@ SetupStacks(winPtr, leaf) } else { id = winPtr->nameUid; } - elPtr = stacks[i]->els; + elPtr = tsdPtr->stacks[i]->els; count = levelPtr->bases[i]; /* @@ -1203,7 +1232,7 @@ SetupStacks(winPtr, leaf) ExtendStacks(elPtr->child.arrayPtr, leaf); } } - cachedWindow = winPtr; + tsdPtr->cachedWindow = winPtr; } /* @@ -1232,13 +1261,16 @@ ExtendStacks(arrayPtr, leaf) { register int count; register Element *elPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (elPtr = arrayPtr->els, count = arrayPtr->numUsed; count > 0; elPtr++, count--) { if (!(elPtr->flags & (NODE|WILDCARD)) && !leaf) { continue; } - stacks[elPtr->flags] = ExtendArray(stacks[elPtr->flags], elPtr); + tsdPtr->stacks[elPtr->flags] = ExtendArray( + tsdPtr->stacks[elPtr->flags], elPtr); } } @@ -1266,24 +1298,32 @@ OptionInit(mainPtr) { int i; Tcl_Interp *interp; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Element *defaultMatchPtr = &tsdPtr->defaultMatch; /* * First, once-only initialization. */ - - if (numLevels == 0) { - - numLevels = 5; - levels = (StackLevel *) ckalloc((unsigned) (5*sizeof(StackLevel))); + + if (tsdPtr->initialized == 0) { + tsdPtr->initialized = 1; + tsdPtr->cachedWindow = NULL; + tsdPtr->numLevels = 5; + tsdPtr->curLevel = -1; + tsdPtr->serial = 0; + + tsdPtr->levels = (StackLevel *) ckalloc((unsigned) + (5*sizeof(StackLevel))); for (i = 0; i < NUM_STACKS; i++) { - stacks[i] = NewArray(10); - levels[0].bases[i] = 0; + tsdPtr->stacks[i] = NewArray(10); + tsdPtr->levels[0].bases[i] = 0; } - defaultMatch.nameUid = NULL; - defaultMatch.child.valueUid = NULL; - defaultMatch.priority = -1; - defaultMatch.flags = 0; + defaultMatchPtr->nameUid = NULL; + defaultMatchPtr->child.valueUid = NULL; + defaultMatchPtr->priority = -1; + defaultMatchPtr->flags = 0; } /* diff --git a/generic/tkPack.c b/generic/tkPack.c index 380315a..20a8a23 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -5,12 +5,12 @@ * geometry manager for Tk. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkPack.c,v 1.2 1998/09/14 18:23:15 stanton Exp $ + * RCS: @(#) $Id: tkPack.c,v 1.3 1999/04/16 01:51:20 stanton Exp $ */ #include "tkPort.h" @@ -96,19 +96,6 @@ typedef struct Packer { #define DONT_PROPAGATE 32 /* - * Hash table used to map from Tk_Window tokens to corresponding - * Packer structures: - */ - -static Tcl_HashTable packerHashTable; - -/* - * Have statics in this module been initialized? - */ - -static int initialized = 0; - -/* * The following structure is the official type record for the * packer: */ @@ -281,7 +268,7 @@ Tk_PackCmd(clientData, interp, argc, argv) } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { register Packer *slavePtr; Tk_Window slave; - char buffer[300]; + char buffer[64 + TCL_INTEGER_SPACE * 4]; static char *sideNames[] = {"top", "bottom", "left", "right"}; if (argc != 3) { @@ -342,9 +329,9 @@ Tk_PackCmd(clientData, interp, argc, argv) masterPtr = GetPacker(master); if (argc == 3) { if (masterPtr->flags & DONT_PROPAGATE) { - interp->result = "0"; + Tcl_SetResult(interp, "0", TCL_STATIC); } else { - interp->result = "1"; + Tcl_SetResult(interp, "1", TCL_STATIC); } return TCL_OK; } @@ -957,10 +944,11 @@ GetPacker(tkwin) register Packer *packPtr; Tcl_HashEntry *hPtr; int new; + TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (!initialized) { - initialized = 1; - Tcl_InitHashTable(&packerHashTable, TCL_ONE_WORD_KEYS); + if (!dispPtr->packInit) { + dispPtr->packInit = 1; + Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS); } /* @@ -968,7 +956,8 @@ GetPacker(tkwin) * then create a new one. */ - hPtr = Tcl_CreateHashEntry(&packerHashTable, (char *) tkwin, &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin, + &new); if (!new) { return (Packer *) Tcl_GetHashValue(hPtr); } @@ -1324,6 +1313,8 @@ PackStructureProc(clientData, eventPtr) XEvent *eventPtr; /* Describes what just happened. */ { register Packer *packPtr = (Packer *) clientData; + TkDisplay *dispPtr; + if (eventPtr->type == ConfigureNotify) { if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { @@ -1353,8 +1344,11 @@ PackStructureProc(clientData, eventPtr) nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } - Tcl_DeleteHashEntry(Tcl_FindHashEntry(&packerHashTable, - (char *) packPtr->tkwin)); + if (packPtr->tkwin != NULL) { + dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr; + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable, + (char *) packPtr->tkwin)); + } if (packPtr->flags & REQUESTED_REPACK) { Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr); } @@ -1398,7 +1392,7 @@ PackStructureProc(clientData, eventPtr) * * Results: * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is - * returned and interp->result is set to contain an error message. + * returned and the interp's result is set to contain an error message. * * Side effects: * Slave windows get taken over by the packer. diff --git a/generic/tkPlace.c b/generic/tkPlace.c index 4e3784d..6fa2e46 100644 --- a/generic/tkPlace.c +++ b/generic/tkPlace.c @@ -5,12 +5,12 @@ * for Tk based on absolute placement or "rubber-sheet" placement. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkPlace.c,v 1.2 1998/09/14 18:23:15 stanton Exp $ + * RCS: @(#) $Id: tkPlace.c,v 1.3 1999/04/16 01:51:20 stanton Exp $ */ #include "tkPort.h" @@ -99,15 +99,6 @@ typedef struct Master { #define PARENT_RECONFIG_PENDING 1 /* - * The hash tables below both use Tk_Window tokens as keys. They map - * from Tk_Windows to Slave and Master structures for windows, if they - * exist. - */ - -static int initialized = 0; -static Tcl_HashTable masterTable; -static Tcl_HashTable slaveTable; -/* * The following structure is the official type record for the * placer: */ @@ -168,15 +159,18 @@ Tk_PlaceCmd(clientData, interp, argc, argv) Tcl_HashEntry *hPtr; size_t length; int c; + TkDisplay *dispPtr; + + dispPtr = ((TkWindow *) clientData)->dispPtr; /* * Initialize, if that hasn't been done yet. */ - if (!initialized) { - Tcl_InitHashTable(&masterTable, TCL_ONE_WORD_KEYS); - Tcl_InitHashTable(&slaveTable, TCL_ONE_WORD_KEYS); - initialized = 1; + if (!dispPtr->placeInit) { + Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS); + dispPtr->placeInit = 1; } if (argc < 3) { @@ -225,7 +219,7 @@ Tk_PlaceCmd(clientData, interp, argc, argv) argv[0], " forget pathName\"", (char *) NULL); return TCL_ERROR; } - hPtr = Tcl_FindHashEntry(&slaveTable, (char *) tkwin); + hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); if (hPtr == NULL) { return TCL_OK; } @@ -243,14 +237,14 @@ Tk_PlaceCmd(clientData, interp, argc, argv) Tk_UnmapWindow(tkwin); ckfree((char *) slavePtr); } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) { - char buffer[50]; + char buffer[32 + TCL_INTEGER_SPACE]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " info pathName\"", (char *) NULL); return TCL_ERROR; } - hPtr = Tcl_FindHashEntry(&slaveTable, (char *) tkwin); + hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin); if (hPtr == NULL) { return TCL_OK; } @@ -306,7 +300,7 @@ Tk_PlaceCmd(clientData, interp, argc, argv) argv[0], " slaves pathName\"", (char *) NULL); return TCL_ERROR; } - hPtr = Tcl_FindHashEntry(&masterTable, (char *) tkwin); + hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin); if (hPtr != NULL) { Master *masterPtr; masterPtr = (Master *) Tcl_GetHashValue(hPtr); @@ -348,8 +342,9 @@ FindSlave(tkwin) Tcl_HashEntry *hPtr; register Slave *slavePtr; int new; + TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr; - hPtr = Tcl_CreateHashEntry(&slaveTable, (char *) tkwin, &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &new); if (new) { slavePtr = (Slave *) ckalloc(sizeof(Slave)); slavePtr->tkwin = tkwin; @@ -441,8 +436,9 @@ FindMaster(tkwin) Tcl_HashEntry *hPtr; register Master *masterPtr; int new; + TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr; - hPtr = Tcl_CreateHashEntry(&masterTable, (char *) tkwin, &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &new); if (new) { masterPtr = (Master *) ckalloc(sizeof(Master)); masterPtr->tkwin = tkwin; @@ -467,7 +463,7 @@ FindMaster(tkwin) * * Results: * A standard Tcl result. If an error occurs then a message is - * left in interp->result. + * left in the interp's result. * * Side effects: * Information in slavePtr may change, and slavePtr's master is @@ -902,6 +898,7 @@ MasterStructureProc(clientData, eventPtr) { register Master *masterPtr = (Master *) clientData; register Slave *slavePtr, *nextPtr; + TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr; if (eventPtr->type == ConfigureNotify) { if ((masterPtr->slavePtr != NULL) @@ -916,7 +913,7 @@ MasterStructureProc(clientData, eventPtr) nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } - Tcl_DeleteHashEntry(Tcl_FindHashEntry(&masterTable, + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable, (char *) masterPtr->tkwin)); if (masterPtr->flags & PARENT_RECONFIG_PENDING) { Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr); @@ -971,10 +968,11 @@ SlaveStructureProc(clientData, eventPtr) XEvent *eventPtr; /* Describes what just happened. */ { register Slave *slavePtr = (Slave *) clientData; + TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr; if (eventPtr->type == DestroyNotify) { UnlinkSlave(slavePtr); - Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable, + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) slavePtr->tkwin)); ckfree((char *) slavePtr); } @@ -1047,13 +1045,15 @@ PlaceLostSlaveProc(clientData, tkwin) Tk_Window tkwin; /* Tk's handle for the slave window. */ { register Slave *slavePtr = (Slave *) clientData; + TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); } Tk_UnmapWindow(tkwin); UnlinkSlave(slavePtr); - Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable, (char *) tkwin)); + Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable, + (char *) tkwin)); Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc, (ClientData) slavePtr); ckfree((char *) slavePtr); diff --git a/generic/tkPlatDecls.h b/generic/tkPlatDecls.h index 37714d2..e0dd331 100644 --- a/generic/tkPlatDecls.h +++ b/generic/tkPlatDecls.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkPlatDecls.h,v 1.2 1999/03/10 07:04:42 stanton Exp $ + * RCS: @(#) $Id: tkPlatDecls.h,v 1.3 1999/04/16 01:51:21 stanton Exp $ */ #ifndef _TKPLATDECLS @@ -121,74 +121,74 @@ extern TkPlatStubs *tkPlatStubsPtr; #ifdef __WIN32__ #ifndef Tk_AttachHWND -#define Tk_AttachHWND(tkwin, hwnd) \ - (tkPlatStubsPtr->tk_AttachHWND)(tkwin, hwnd) /* 0 */ +#define Tk_AttachHWND \ + (tkPlatStubsPtr->tk_AttachHWND) /* 0 */ #endif #ifndef Tk_GetHINSTANCE -#define Tk_GetHINSTANCE() \ - (tkPlatStubsPtr->tk_GetHINSTANCE)() /* 1 */ +#define Tk_GetHINSTANCE \ + (tkPlatStubsPtr->tk_GetHINSTANCE) /* 1 */ #endif #ifndef Tk_GetHWND -#define Tk_GetHWND(window) \ - (tkPlatStubsPtr->tk_GetHWND)(window) /* 2 */ +#define Tk_GetHWND \ + (tkPlatStubsPtr->tk_GetHWND) /* 2 */ #endif #ifndef Tk_HWNDToWindow -#define Tk_HWNDToWindow(hwnd) \ - (tkPlatStubsPtr->tk_HWNDToWindow)(hwnd) /* 3 */ +#define Tk_HWNDToWindow \ + (tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */ #endif #ifndef Tk_PointerEvent -#define Tk_PointerEvent(hwnd, x, y) \ - (tkPlatStubsPtr->tk_PointerEvent)(hwnd, x, y) /* 4 */ +#define Tk_PointerEvent \ + (tkPlatStubsPtr->tk_PointerEvent) /* 4 */ #endif #ifndef Tk_TranslateWinEvent -#define Tk_TranslateWinEvent(hwnd, message, wParam, lParam, result) \ - (tkPlatStubsPtr->tk_TranslateWinEvent)(hwnd, message, wParam, lParam, result) /* 5 */ +#define Tk_TranslateWinEvent \ + (tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */ #endif #endif /* __WIN32__ */ #ifdef MAC_TCL #ifndef Tk_MacSetEmbedHandler -#define Tk_MacSetEmbedHandler(registerWinProcPtr, getPortProcPtr, containerExistProcPtr, getClipProc, getOffsetProc) \ - (tkPlatStubsPtr->tk_MacSetEmbedHandler)(registerWinProcPtr, getPortProcPtr, containerExistProcPtr, getClipProc, getOffsetProc) /* 0 */ +#define Tk_MacSetEmbedHandler \ + (tkPlatStubsPtr->tk_MacSetEmbedHandler) /* 0 */ #endif #ifndef Tk_MacTurnOffMenus -#define Tk_MacTurnOffMenus() \ - (tkPlatStubsPtr->tk_MacTurnOffMenus)() /* 1 */ +#define Tk_MacTurnOffMenus \ + (tkPlatStubsPtr->tk_MacTurnOffMenus) /* 1 */ #endif #ifndef Tk_MacTkOwnsCursor -#define Tk_MacTkOwnsCursor(tkOwnsIt) \ - (tkPlatStubsPtr->tk_MacTkOwnsCursor)(tkOwnsIt) /* 2 */ +#define Tk_MacTkOwnsCursor \ + (tkPlatStubsPtr->tk_MacTkOwnsCursor) /* 2 */ #endif #ifndef TkMacInitMenus -#define TkMacInitMenus(interp) \ - (tkPlatStubsPtr->tkMacInitMenus)(interp) /* 3 */ +#define TkMacInitMenus \ + (tkPlatStubsPtr->tkMacInitMenus) /* 3 */ #endif #ifndef TkMacInitAppleEvents -#define TkMacInitAppleEvents(interp) \ - (tkPlatStubsPtr->tkMacInitAppleEvents)(interp) /* 4 */ +#define TkMacInitAppleEvents \ + (tkPlatStubsPtr->tkMacInitAppleEvents) /* 4 */ #endif #ifndef TkMacConvertEvent -#define TkMacConvertEvent(eventPtr) \ - (tkPlatStubsPtr->tkMacConvertEvent)(eventPtr) /* 5 */ +#define TkMacConvertEvent \ + (tkPlatStubsPtr->tkMacConvertEvent) /* 5 */ #endif #ifndef TkMacConvertTkEvent -#define TkMacConvertTkEvent(eventPtr, window) \ - (tkPlatStubsPtr->tkMacConvertTkEvent)(eventPtr, window) /* 6 */ +#define TkMacConvertTkEvent \ + (tkPlatStubsPtr->tkMacConvertTkEvent) /* 6 */ #endif #ifndef TkGenWMConfigureEvent -#define TkGenWMConfigureEvent(tkwin, x, y, width, height, flags) \ - (tkPlatStubsPtr->tkGenWMConfigureEvent)(tkwin, x, y, width, height, flags) /* 7 */ +#define TkGenWMConfigureEvent \ + (tkPlatStubsPtr->tkGenWMConfigureEvent) /* 7 */ #endif #ifndef TkMacInvalClipRgns -#define TkMacInvalClipRgns(winPtr) \ - (tkPlatStubsPtr->tkMacInvalClipRgns)(winPtr) /* 8 */ +#define TkMacInvalClipRgns \ + (tkPlatStubsPtr->tkMacInvalClipRgns) /* 8 */ #endif #ifndef TkMacHaveAppearance -#define TkMacHaveAppearance() \ - (tkPlatStubsPtr->tkMacHaveAppearance)() /* 9 */ +#define TkMacHaveAppearance \ + (tkPlatStubsPtr->tkMacHaveAppearance) /* 9 */ #endif #ifndef TkMacGetDrawablePort -#define TkMacGetDrawablePort(drawable) \ - (tkPlatStubsPtr->tkMacGetDrawablePort)(drawable) /* 10 */ +#define TkMacGetDrawablePort \ + (tkPlatStubsPtr->tkMacGetDrawablePort) /* 10 */ #endif #endif /* MAC_TCL */ diff --git a/generic/tkPlatStubs.c b/generic/tkPlatStubs.c deleted file mode 100644 index f58d8ed..0000000 --- a/generic/tkPlatStubs.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * tkPlatStubs.c -- - * - * This file contains the wrapper functions for the platform independent - * unsupported Tk API. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * All rights reserved. - * - * RCS: @(#) $Id: tkPlatStubs.c,v 1.2 1999/03/10 07:04:42 stanton Exp $ - */ - -#include "tk.h" - -#ifdef __WIN32__ -#include "tkWinInt.h" -#endif - -/* - * WARNING: This file is automatically generated by the tools/genStubs.tcl - * script. Any modifications to the function declarations below should be made - * in the generic/tk.decls script. - */ - -/* !BEGIN!: Do not edit below this line. */ - -/* - * Exported stub functions: - */ - -#ifdef __WIN32__ -/* Slot 0 */ -Window -Tk_AttachHWND(tkwin, hwnd) - Tk_Window tkwin; - HWND hwnd; -{ - return (tkPlatStubsPtr->tk_AttachHWND)(tkwin, hwnd); -} - -/* Slot 1 */ -HINSTANCE -Tk_GetHINSTANCE() -{ - return (tkPlatStubsPtr->tk_GetHINSTANCE)(); -} - -/* Slot 2 */ -HWND -Tk_GetHWND(window) - Window window; -{ - return (tkPlatStubsPtr->tk_GetHWND)(window); -} - -/* Slot 3 */ -Tk_Window -Tk_HWNDToWindow(hwnd) - HWND hwnd; -{ - return (tkPlatStubsPtr->tk_HWNDToWindow)(hwnd); -} - -/* Slot 4 */ -void -Tk_PointerEvent(hwnd, x, y) - HWND hwnd; - int x; - int y; -{ - (tkPlatStubsPtr->tk_PointerEvent)(hwnd, x, y); -} - -/* Slot 5 */ -int -Tk_TranslateWinEvent(hwnd, message, wParam, lParam, result) - HWND hwnd; - UINT message; - WPARAM wParam; - LPARAM lParam; - LRESULT * result; -{ - return (tkPlatStubsPtr->tk_TranslateWinEvent)(hwnd, message, wParam, lParam, result); -} - -#endif /* __WIN32__ */ -#ifdef MAC_TCL -/* Slot 0 */ -void -Tk_MacSetEmbedHandler(registerWinProcPtr, getPortProcPtr, containerExistProcPtr, getClipProc, getOffsetProc) - Tk_MacEmbedRegisterWinProc * registerWinProcPtr; - Tk_MacEmbedGetGrafPortProc * getPortProcPtr; - Tk_MacEmbedMakeContainerExistProc * containerExistProcPtr; - Tk_MacEmbedGetClipProc * getClipProc; - Tk_MacEmbedGetOffsetInParentProc * getOffsetProc; -{ - (tkPlatStubsPtr->tk_MacSetEmbedHandler)(registerWinProcPtr, getPortProcPtr, containerExistProcPtr, getClipProc, getOffsetProc); -} - -/* Slot 1 */ -void -Tk_MacTurnOffMenus() -{ - (tkPlatStubsPtr->tk_MacTurnOffMenus)(); -} - -/* Slot 2 */ -void -Tk_MacTkOwnsCursor(tkOwnsIt) - int tkOwnsIt; -{ - (tkPlatStubsPtr->tk_MacTkOwnsCursor)(tkOwnsIt); -} - -/* Slot 3 */ -void -TkMacInitMenus(interp) - Tcl_Interp * interp; -{ - (tkPlatStubsPtr->tkMacInitMenus)(interp); -} - -/* Slot 4 */ -void -TkMacInitAppleEvents(interp) - Tcl_Interp * interp; -{ - (tkPlatStubsPtr->tkMacInitAppleEvents)(interp); -} - -/* Slot 5 */ -int -TkMacConvertEvent(eventPtr) - EventRecord * eventPtr; -{ - return (tkPlatStubsPtr->tkMacConvertEvent)(eventPtr); -} - -/* Slot 6 */ -int -TkMacConvertTkEvent(eventPtr, window) - EventRecord * eventPtr; - Window window; -{ - return (tkPlatStubsPtr->tkMacConvertTkEvent)(eventPtr, window); -} - -/* Slot 7 */ -void -TkGenWMConfigureEvent(tkwin, x, y, width, height, flags) - Tk_Window tkwin; - int x; - int y; - int width; - int height; - int flags; -{ - (tkPlatStubsPtr->tkGenWMConfigureEvent)(tkwin, x, y, width, height, flags); -} - -/* Slot 8 */ -void -TkMacInvalClipRgns(winPtr) - TkWindow * winPtr; -{ - (tkPlatStubsPtr->tkMacInvalClipRgns)(winPtr); -} - -/* Slot 9 */ -int -TkMacHaveAppearance() -{ - return (tkPlatStubsPtr->tkMacHaveAppearance)(); -} - -/* Slot 10 */ -GWorldPtr -TkMacGetDrawablePort(drawable) - Drawable drawable; -{ - return (tkPlatStubsPtr->tkMacGetDrawablePort)(drawable); -} - -#endif /* MAC_TCL */ - -/* !END!: Do not edit above this line. */ diff --git a/generic/tkPointer.c b/generic/tkPointer.c index 4b18d0b..d14074d 100644 --- a/generic/tkPointer.c +++ b/generic/tkPointer.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: tkPointer.c,v 1.3 1999/03/10 07:04:43 stanton Exp $ + * RCS: @(#) $Id: tkPointer.c,v 1.4 1999/04/16 01:51:21 stanton Exp $ */ #include "tkInt.h" @@ -36,19 +36,18 @@ static unsigned int buttonMasks[] = { }; #define ButtonMask(b) (buttonMasks[(b)-Button1]) -/* - * Declarations of static variables used in the pointer module. - */ - -static TkWindow *cursorWinPtr = NULL; /* Window that is currently - * controlling the global cursor. */ -static TkWindow *grabWinPtr = NULL; /* Window that defines the top of the +typedef struct ThreadSpecificData { + TkWindow *grabWinPtr; /* Window that defines the top of the * grab tree in a global grab. */ -static XPoint lastPos = { 0, 0}; /* Last reported mouse position. */ -static int lastState = 0; /* Last known state flags. */ -static TkWindow *lastWinPtr = NULL; /* Last reported mouse window. */ -static TkWindow *restrictWinPtr = NULL; /* Window to which all mouse events + int lastState; /* Last known state flags. */ + XPoint lastPos; /* Last reported mouse position. */ + TkWindow *lastWinPtr; /* Last reported mouse window. */ + TkWindow *restrictWinPtr; /* Window to which all mouse events * will be reported. */ + TkWindow *cursorWinPtr; /* Window that is currently + * controlling the global cursor. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Forward declarations of procedures used in this file. @@ -141,8 +140,12 @@ GenerateEnterLeave(winPtr, x, y, state) int state; /* State flags. */ { int crossed = 0; /* 1 if mouse crossed a window boundary */ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr; + TkWindow *lastWinPtr = tsdPtr->lastWinPtr; - if (winPtr != lastWinPtr) { + if (winPtr != tsdPtr->lastWinPtr) { if (restrictWinPtr) { int newPos, oldPos; @@ -200,7 +203,7 @@ GenerateEnterLeave(winPtr, x, y, state) crossed = 1; } } - lastWinPtr = winPtr; + tsdPtr->lastWinPtr = winPtr; } return crossed; @@ -230,11 +233,13 @@ Tk_UpdatePointer(tkwin, x, y, state) int x, y; /* Pointer location in root coords. */ int state; /* Modifier state mask. */ { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); TkWindow *winPtr = (TkWindow *)tkwin; TkWindow *targetWinPtr; XPoint pos; XEvent event; - int changes = (state ^ lastState) & ALL_BUTTONS; + int changes = (state ^ tsdPtr->lastState) & ALL_BUTTONS; int type, b, mask; pos.x = x; @@ -245,7 +250,8 @@ Tk_UpdatePointer(tkwin, x, y, state) * state since we haven't generated the button events yet. */ - lastState = (state & ~ALL_BUTTONS) | (lastState & ALL_BUTTONS); + tsdPtr->lastState = (state & ~ALL_BUTTONS) | (tsdPtr->lastState + & ALL_BUTTONS); /* * Generate Enter/Leave events. If the pointer has crossed window @@ -253,8 +259,8 @@ Tk_UpdatePointer(tkwin, x, y, state) * redundant motion events. */ - if (GenerateEnterLeave(winPtr, x, y, lastState)) { - lastPos = pos; + if (GenerateEnterLeave(winPtr, x, y, tsdPtr->lastState)) { + tsdPtr->lastPos = pos; } /* @@ -273,30 +279,30 @@ Tk_UpdatePointer(tkwin, x, y, state) * if this is the first button down. */ - if (!restrictWinPtr) { - if (!grabWinPtr) { + if (!tsdPtr->restrictWinPtr) { + if (!tsdPtr->grabWinPtr) { /* * Mouse is not grabbed, so set a button grab. */ - restrictWinPtr = winPtr; - TkpSetCapture(restrictWinPtr); + tsdPtr->restrictWinPtr = winPtr; + TkpSetCapture(tsdPtr->restrictWinPtr); - } else if ((lastState & ALL_BUTTONS) == 0) { + } else if ((tsdPtr->lastState & ALL_BUTTONS) == 0) { /* * Mouse is in a non-button grab, so ensure * the button grab is inside the grab tree. */ - if (TkPositionInTree(winPtr, grabWinPtr) + if (TkPositionInTree(winPtr, tsdPtr->grabWinPtr) == TK_GRAB_IN_TREE) { - restrictWinPtr = winPtr; + tsdPtr->restrictWinPtr = winPtr; } else { - restrictWinPtr = grabWinPtr; + tsdPtr->restrictWinPtr = tsdPtr->grabWinPtr; } - TkpSetCapture(restrictWinPtr); + TkpSetCapture(tsdPtr->restrictWinPtr); } } @@ -309,8 +315,8 @@ Tk_UpdatePointer(tkwin, x, y, state) * aren't in a global grab. */ - if ((lastState & ALL_BUTTONS) == mask) { - if (!grabWinPtr) { + if ((tsdPtr->lastState & ALL_BUTTONS) == mask) { + if (!tsdPtr->grabWinPtr) { TkpSetCapture(NULL); } } @@ -321,16 +327,16 @@ Tk_UpdatePointer(tkwin, x, y, state) * the restrict window to the current mouse position. */ - if (restrictWinPtr) { - InitializeEvent(&event, restrictWinPtr, type, x, y, - lastState, b); + if (tsdPtr->restrictWinPtr) { + InitializeEvent(&event, tsdPtr->restrictWinPtr, type, x, y, + tsdPtr->lastState, b); Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - lastState &= ~mask; - lastWinPtr = restrictWinPtr; - restrictWinPtr = NULL; + tsdPtr->lastState &= ~mask; + tsdPtr->lastWinPtr = tsdPtr->restrictWinPtr; + tsdPtr->restrictWinPtr = NULL; - GenerateEnterLeave(winPtr, x, y, lastState); - lastPos = pos; + GenerateEnterLeave(winPtr, x, y, tsdPtr->lastState); + tsdPtr->lastPos = pos; continue; } } @@ -342,10 +348,10 @@ Tk_UpdatePointer(tkwin, x, y, state) * managed by Tk should be reported to the grab window. */ - if (restrictWinPtr) { - targetWinPtr = restrictWinPtr; - } else if (grabWinPtr && !winPtr) { - targetWinPtr = grabWinPtr; + if (tsdPtr->restrictWinPtr) { + targetWinPtr = tsdPtr->restrictWinPtr; + } else if (tsdPtr->grabWinPtr && !winPtr) { + targetWinPtr = tsdPtr->grabWinPtr; } else { targetWinPtr = winPtr; } @@ -356,7 +362,7 @@ Tk_UpdatePointer(tkwin, x, y, state) if (winPtr != NULL) { InitializeEvent(&event, targetWinPtr, type, x, y, - lastState, b); + tsdPtr->lastState, b); Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } @@ -364,9 +370,9 @@ Tk_UpdatePointer(tkwin, x, y, state) * Update the state for the next iteration. */ - lastState = (type == ButtonPress) - ? (lastState | mask) : (lastState & ~mask); - lastPos = pos; + tsdPtr->lastState = (type == ButtonPress) + ? (tsdPtr->lastState | mask) : (tsdPtr->lastState & ~mask); + tsdPtr->lastPos = pos; } } @@ -374,11 +380,11 @@ Tk_UpdatePointer(tkwin, x, y, state) * Make sure the cursor window is up to date. */ - if (restrictWinPtr) { - targetWinPtr = restrictWinPtr; - } else if (grabWinPtr) { - targetWinPtr = (TkPositionInTree(winPtr, grabWinPtr) - == TK_GRAB_IN_TREE) ? winPtr : grabWinPtr; + if (tsdPtr->restrictWinPtr) { + targetWinPtr = tsdPtr->restrictWinPtr; + } else if (tsdPtr->grabWinPtr) { + targetWinPtr = (TkPositionInTree(winPtr, tsdPtr->grabWinPtr) + == TK_GRAB_IN_TREE) ? winPtr : tsdPtr->grabWinPtr; } else { targetWinPtr = winPtr; } @@ -389,19 +395,19 @@ Tk_UpdatePointer(tkwin, x, y, state) * generate a motion event. */ - if (lastPos.x != pos.x || lastPos.y != pos.y) { - if (restrictWinPtr) { - targetWinPtr = restrictWinPtr; - } else if (grabWinPtr && !winPtr) { - targetWinPtr = grabWinPtr; + if (tsdPtr->lastPos.x != pos.x || tsdPtr->lastPos.y != pos.y) { + if (tsdPtr->restrictWinPtr) { + targetWinPtr = tsdPtr->restrictWinPtr; + } else if (tsdPtr->grabWinPtr && !winPtr) { + targetWinPtr = tsdPtr->grabWinPtr; } if (targetWinPtr != NULL) { InitializeEvent(&event, targetWinPtr, MotionNotify, x, y, - lastState, NotifyNormal); + tsdPtr->lastState, NotifyNormal); Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } - lastPos = pos; + tsdPtr->lastPos = pos; } } @@ -437,12 +443,16 @@ XGrabPointer(display, grab_window, owner_events, event_mask, pointer_mode, Cursor cursor; Time time; { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + display->request++; - grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window); - restrictWinPtr = NULL; - TkpSetCapture(grabWinPtr); - if (TkPositionInTree(lastWinPtr, grabWinPtr) != TK_GRAB_IN_TREE) { - UpdateCursor(grabWinPtr); + tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window); + tsdPtr->restrictWinPtr = NULL; + TkpSetCapture(tsdPtr->grabWinPtr); + if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr) + != TK_GRAB_IN_TREE) { + UpdateCursor(tsdPtr->grabWinPtr); } return GrabSuccess; } @@ -468,11 +478,14 @@ XUngrabPointer(display, time) Display* display; Time time; { + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + display->request++; - grabWinPtr = NULL; - restrictWinPtr = NULL; + tsdPtr->grabWinPtr = NULL; + tsdPtr->restrictWinPtr = NULL; TkpSetCapture(NULL); - UpdateCursor(lastWinPtr); + UpdateCursor(tsdPtr->lastWinPtr); } /* @@ -495,16 +508,19 @@ void TkPointerDeadWindow(winPtr) TkWindow *winPtr; { - if (winPtr == lastWinPtr) { - lastWinPtr = NULL; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (winPtr == tsdPtr->lastWinPtr) { + tsdPtr->lastWinPtr = NULL; } - if (winPtr == grabWinPtr) { - grabWinPtr = NULL; + if (winPtr == tsdPtr->grabWinPtr) { + tsdPtr->grabWinPtr = NULL; } - if (winPtr == restrictWinPtr) { - restrictWinPtr = NULL; + if (winPtr == tsdPtr->restrictWinPtr) { + tsdPtr->restrictWinPtr = NULL; } - if (!(restrictWinPtr || grabWinPtr)) { + if (!(tsdPtr->restrictWinPtr || tsdPtr->grabWinPtr)) { TkpSetCapture(NULL); } } @@ -531,6 +547,8 @@ UpdateCursor(winPtr) TkWindow *winPtr; { Cursor cursor = None; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * A window inherits its cursor from its parent if it doesn't @@ -538,7 +556,7 @@ UpdateCursor(winPtr) * cursor. */ - cursorWinPtr = winPtr; + tsdPtr->cursorWinPtr = winPtr; while (winPtr != NULL) { if (winPtr->atts.cursor != None) { cursor = winPtr->atts.cursor; @@ -577,8 +595,10 @@ XDefineCursor(display, w, cursor) Cursor cursor; { TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (cursorWinPtr == winPtr) { + if (tsdPtr->cursorWinPtr == winPtr) { UpdateCursor(winPtr); } display->request++; diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c index beba5a0..70556b4 100644 --- a/generic/tkRectOval.c +++ b/generic/tkRectOval.c @@ -5,12 +5,12 @@ * widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkRectOval.c,v 1.2 1998/09/14 18:23:16 stanton Exp $ + * RCS: @(#) $Id: tkRectOval.c,v 1.3 1999/04/16 01:51:21 stanton Exp $ */ #include <stdio.h> @@ -157,7 +157,7 @@ Tk_ItemType tkOvalType = { * Results: * A standard Tcl return value. If an error occurred in * creating the item, then an error message is left in - * interp->result; in this case itemPtr is left uninitialized, + * the interp's result; in this case itemPtr is left uninitialized, * so it can be safely freed by the caller. * * Side effects: @@ -230,7 +230,7 @@ CreateRectOval(interp, canvas, itemPtr, argc, argv) * for details on what it does. * * Results: - * Returns TCL_OK or TCL_ERROR, and sets interp->result. + * Returns TCL_OK or TCL_ERROR, and sets the interp's result. * * Side effects: * The coordinates for the given item may be changed. @@ -273,9 +273,10 @@ RectOvalCoords(interp, canvas, itemPtr, argc, argv) } ComputeRectOvalBbox(canvas, rectOvalPtr); } else { - sprintf(interp->result, - "wrong # coordinates: expected 0 or 4, got %d", - argc); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", argc); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; @@ -292,7 +293,7 @@ RectOvalCoords(interp, canvas, itemPtr, argc, argv) * * Results: * A standard Tcl result code. If an error occurs, then - * an error message is left in interp->result. + * an error message is left in the interp's result. * * Side effects: * Configuration information, such as colors and stipple @@ -942,7 +943,7 @@ TranslateRectOval(canvas, itemPtr, deltaX, deltaY) * Results: * The return value is a standard Tcl result. If an error * occurs in generating Postscript then an error message is - * left in interp->result, replacing whatever used to be there. + * left in the interp's result, replacing whatever used to be there. * If no error occurs, then Postscript for the rectangle is * appended to the result. * @@ -962,7 +963,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) * collect font information; 0 means * final Postscript is being created. */ { - char pathCmd[500], string[100]; + char pathCmd[500]; RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; double y1, y2; @@ -1016,6 +1017,8 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) */ if (rectOvalPtr->outlineColor != NULL) { + char string[32 + TCL_INTEGER_SPACE]; + Tcl_AppendResult(interp, pathCmd, (char *) NULL); sprintf(string, "%d setlinewidth", rectOvalPtr->width); Tcl_AppendResult(interp, string, diff --git a/generic/tkScale.c b/generic/tkScale.c index 8cdfc3c..74efdd8 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -12,12 +12,12 @@ * permission. * * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1996 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkScale.c,v 1.2 1998/09/14 18:23:16 stanton Exp $ + * RCS: @(#) $Id: tkScale.c,v 1.3 1999/04/16 01:51:21 stanton Exp $ */ #include "tkPort.h" @@ -26,96 +26,132 @@ #include "tclMath.h" #include "tkScale.h" -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_SCALE_ACTIVE_BG_COLOR, Tk_Offset(TkScale, activeBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground", - DEF_SCALE_ACTIVE_BG_MONO, Tk_Offset(TkScale, activeBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_SCALE_BG_COLOR, Tk_Offset(TkScale, bgBorder), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - DEF_SCALE_BG_MONO, Tk_Offset(TkScale, bgBorder), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement", - DEF_SCALE_BIG_INCREMENT, Tk_Offset(TkScale, bigIncrement), 0}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_SCALE_BORDER_WIDTH, Tk_Offset(TkScale, borderWidth), 0}, - {TK_CONFIG_STRING, "-command", "command", "Command", - DEF_SCALE_COMMAND, Tk_Offset(TkScale, command), TK_CONFIG_NULL_OK}, - {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor", - DEF_SCALE_CURSOR, Tk_Offset(TkScale, cursor), TK_CONFIG_NULL_OK}, - {TK_CONFIG_INT, "-digits", "digits", "Digits", - DEF_SCALE_DIGITS, Tk_Offset(TkScale, digits), 0}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_FONT, "-font", "font", "Font", - DEF_SCALE_FONT, Tk_Offset(TkScale, tkfont), - 0}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_SCALE_FG_COLOR, Tk_Offset(TkScale, textColorPtr), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground", - DEF_SCALE_FG_MONO, Tk_Offset(TkScale, textColorPtr), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_DOUBLE, "-from", "from", "From", - DEF_SCALE_FROM, Tk_Offset(TkScale, fromValue), 0}, - {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground", - "HighlightBackground", DEF_SCALE_HIGHLIGHT_BG, - Tk_Offset(TkScale, highlightBgColorPtr), 0}, - {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_SCALE_HIGHLIGHT, Tk_Offset(TkScale, highlightColorPtr), 0}, - {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", - DEF_SCALE_HIGHLIGHT_WIDTH, Tk_Offset(TkScale, highlightWidth), 0}, - {TK_CONFIG_STRING, "-label", "label", "Label", - DEF_SCALE_LABEL, Tk_Offset(TkScale, label), TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-length", "length", "Length", - DEF_SCALE_LENGTH, Tk_Offset(TkScale, length), 0}, - {TK_CONFIG_UID, "-orient", "orient", "Orient", - DEF_SCALE_ORIENT, Tk_Offset(TkScale, orientUid), 0}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - DEF_SCALE_RELIEF, Tk_Offset(TkScale, relief), 0}, - {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", - DEF_SCALE_REPEAT_DELAY, Tk_Offset(TkScale, repeatDelay), 0}, - {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval", - DEF_SCALE_REPEAT_INTERVAL, Tk_Offset(TkScale, repeatInterval), 0}, - {TK_CONFIG_DOUBLE, "-resolution", "resolution", "Resolution", - DEF_SCALE_RESOLUTION, Tk_Offset(TkScale, resolution), 0}, - {TK_CONFIG_BOOLEAN, "-showvalue", "showValue", "ShowValue", - DEF_SCALE_SHOW_VALUE, Tk_Offset(TkScale, showValue), 0}, - {TK_CONFIG_PIXELS, "-sliderlength", "sliderLength", "SliderLength", - DEF_SCALE_SLIDER_LENGTH, Tk_Offset(TkScale, sliderLength), 0}, - {TK_CONFIG_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief", - DEF_SCALE_SLIDER_RELIEF, Tk_Offset(TkScale, sliderRelief), - TK_CONFIG_DONT_SET_DEFAULT}, - {TK_CONFIG_UID, "-state", "state", "State", - DEF_SCALE_STATE, Tk_Offset(TkScale, state), 0}, - {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_SCALE_TAKE_FOCUS, Tk_Offset(TkScale, takeFocus), - TK_CONFIG_NULL_OK}, - {TK_CONFIG_DOUBLE, "-tickinterval", "tickInterval", "TickInterval", - DEF_SCALE_TICK_INTERVAL, Tk_Offset(TkScale, tickInterval), 0}, - {TK_CONFIG_DOUBLE, "-to", "to", "To", - DEF_SCALE_TO, Tk_Offset(TkScale, toValue), 0}, - {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background", - DEF_SCALE_TROUGH_COLOR, Tk_Offset(TkScale, troughColorPtr), - TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background", - DEF_SCALE_TROUGH_MONO, Tk_Offset(TkScale, troughColorPtr), - TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_STRING, "-variable", "variable", "Variable", - DEF_SCALE_VARIABLE, Tk_Offset(TkScale, varName), TK_CONFIG_NULL_OK}, - {TK_CONFIG_PIXELS, "-width", "width", "Width", - DEF_SCALE_WIDTH, Tk_Offset(TkScale, width), 0}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} +/* + * The following table defines the legal values for the -orient option. + * It is used together with the "enum orient" declaration in tkScale.h. + */ + +static char *orientStrings[] = { + "horizontal", "vertical", (char *) NULL +}; + +/* + * The following table defines the legal values for the -state option. + * It is used together with the "enum state" declaration in tkScale.h. + */ + +static char *stateStrings[] = { + "active", "disabled", "normal", (char *) NULL +}; + +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground", + DEF_SCALE_ACTIVE_BG_COLOR, -1, Tk_Offset(TkScale, activeBorder), + 0, (ClientData) DEF_SCALE_ACTIVE_BG_MONO, 0}, + {TK_OPTION_BORDER, "-background", "background", "Background", + DEF_SCALE_BG_COLOR, -1, Tk_Offset(TkScale, bgBorder), + 0, (ClientData) DEF_SCALE_BG_MONO, 0}, + {TK_OPTION_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement", + DEF_SCALE_BIG_INCREMENT, -1, Tk_Offset(TkScale, bigIncrement), + 0, 0, 0}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + DEF_SCALE_BORDER_WIDTH, -1, Tk_Offset(TkScale, borderWidth), + 0, 0, 0}, + {TK_OPTION_STRING, "-command", "command", "Command", + DEF_SCALE_COMMAND, Tk_Offset(TkScale, commandPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + DEF_SCALE_CURSOR, -1, Tk_Offset(TkScale, cursor), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_INT, "-digits", "digits", "Digits", + DEF_SCALE_DIGITS, -1, Tk_Offset(TkScale, digits), + 0, 0, 0}, + {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEF_SCALE_FONT, -1, Tk_Offset(TkScale, tkfont), 0, 0, 0}, + {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", + DEF_SCALE_FG_COLOR, -1, Tk_Offset(TkScale, textColorPtr), 0, + (ClientData) DEF_SCALE_FG_MONO, 0}, + {TK_OPTION_DOUBLE, "-from", "from", "From", DEF_SCALE_FROM, -1, + Tk_Offset(TkScale, fromValue), 0, 0, 0}, + {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground", + "HighlightBackground", DEF_SCALE_HIGHLIGHT_BG_COLOR, + -1, Tk_Offset(TkScale, highlightBorder), + 0, (ClientData) DEF_SCALE_HIGHLIGHT_BG_MONO, 0}, + {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", + DEF_SCALE_HIGHLIGHT, -1, Tk_Offset(TkScale, highlightColorPtr), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", + "HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, -1, + Tk_Offset(TkScale, highlightWidth), 0, 0, 0}, + {TK_OPTION_STRING, "-label", "label", "Label", + DEF_SCALE_LABEL, Tk_Offset(TkScale, labelPtr), -1, 0, 0, 0}, + {TK_OPTION_PIXELS, "-length", "length", "Length", + DEF_SCALE_LENGTH, -1, Tk_Offset(TkScale, length), 0, 0, 0}, + {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", + DEF_SCALE_ORIENT, -1, Tk_Offset(TkScale, orient), + 0, (ClientData) orientStrings, 0}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + DEF_SCALE_RELIEF, -1, Tk_Offset(TkScale, relief), 0, 0, 0}, + {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", + DEF_SCALE_REPEAT_DELAY, -1, Tk_Offset(TkScale, repeatDelay), + 0, 0, 0}, + {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval", + DEF_SCALE_REPEAT_INTERVAL, -1, Tk_Offset(TkScale, repeatInterval), + 0, 0, 0}, + {TK_OPTION_DOUBLE, "-resolution", "resolution", "Resolution", + DEF_SCALE_RESOLUTION, -1, Tk_Offset(TkScale, resolution), + 0, 0, 0}, + {TK_OPTION_BOOLEAN, "-showvalue", "showValue", "ShowValue", + DEF_SCALE_SHOW_VALUE, -1, Tk_Offset(TkScale, showValue), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-sliderlength", "sliderLength", "SliderLength", + DEF_SCALE_SLIDER_LENGTH, -1, Tk_Offset(TkScale, sliderLength), + 0, 0, 0}, + {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief", + DEF_SCALE_SLIDER_RELIEF, -1, Tk_Offset(TkScale, sliderRelief), + 0, 0, 0}, + {TK_OPTION_STRING_TABLE, "-state", "state", "State", + DEF_SCALE_STATE, -1, Tk_Offset(TkScale, state), + 0, (ClientData) stateStrings, 0}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + DEF_SCALE_TAKE_FOCUS, Tk_Offset(TkScale, takeFocusPtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_DOUBLE, "-tickinterval", "tickInterval", "TickInterval", + DEF_SCALE_TICK_INTERVAL, -1, Tk_Offset(TkScale, tickInterval), + 0, 0, 0}, + {TK_OPTION_DOUBLE, "-to", "to", "To", + DEF_SCALE_TO, -1, Tk_Offset(TkScale, toValue), 0, 0, 0}, + {TK_OPTION_COLOR, "-troughcolor", "troughColor", "Background", + DEF_SCALE_TROUGH_COLOR, -1, Tk_Offset(TkScale, troughColorPtr), + 0, (ClientData) DEF_SCALE_TROUGH_MONO, 0}, + {TK_OPTION_STRING, "-variable", "variable", "Variable", + DEF_SCALE_VARIABLE, Tk_Offset(TkScale, varNamePtr), -1, + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_PIXELS, "-width", "width", "Width", + DEF_SCALE_WIDTH, -1, Tk_Offset(TkScale, width), 0, 0, 0}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, 0, 0} +}; + +/* + * The following tables define the scale widget commands and map the + * indexes into the string tables into a single enumerated type used + * to dispatch the scale widget command. + */ + +static char *commandNames[] = { + "cget", "configure", "coords", "get", "identify", "set", (char *) NULL +}; + +enum command { + COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_COORDS, COMMAND_GET, + COMMAND_IDENTIFY, COMMAND_SET }; /* @@ -125,8 +161,8 @@ static Tk_ConfigSpec configSpecs[] = { static void ComputeFormat _ANSI_ARGS_((TkScale *scalePtr)); static void ComputeScaleGeometry _ANSI_ARGS_((TkScale *scalePtr)); static int ConfigureScale _ANSI_ARGS_((Tcl_Interp *interp, - TkScale *scalePtr, int argc, char **argv, - int flags)); + TkScale *scalePtr, int objc, + Tcl_Obj *CONST objv[])); static void DestroyScale _ANSI_ARGS_((char *memPtr)); static void ScaleCmdDeletedProc _ANSI_ARGS_(( ClientData clientData)); @@ -135,8 +171,9 @@ static void ScaleEventProc _ANSI_ARGS_((ClientData clientData, static char * ScaleVarProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); -static int ScaleWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); +static int ScaleWidgetObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static void ScaleWorldChanged _ANSI_ARGS_(( ClientData instanceData)); @@ -155,7 +192,7 @@ static TkClassProcs scaleClass = { /* *-------------------------------------------------------------- * - * Tk_ScaleCmd -- + * Tk_ScaleObjCmd -- * * This procedure is invoked to process the "scale" Tcl * command. See the user documentation for details on what @@ -171,28 +208,48 @@ static TkClassProcs scaleClass = { */ int -Tk_ScaleCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window associated with - * interpreter. */ +Tk_ScaleObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Either NULL or pointer to option table. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - Tk_Window tkwin = (Tk_Window) clientData; register TkScale *scalePtr; - Tk_Window new; + Tk_OptionTable optionTable; + Tk_Window tkwin; + + optionTable = (Tk_OptionTable) clientData; + if (optionTable == NULL) { + Tcl_CmdInfo info; + char *name; + + /* + * We haven't created the option table for this widget class + * yet. Do it now and save the table as the clientData for + * the command, so we'll have access to it in future + * invocations of the command. + */ - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + optionTable = Tk_CreateOptionTable(interp, optionSpecs); + name = Tcl_GetString(objv[0]); + Tcl_GetCommandInfo(interp, name, &info); + info.objClientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, name, &info); + } + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } - new = Tk_CreateWindowFromPath(interp, tkwin, argv[1], (char *) NULL); - if (new == NULL) { + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetString(objv[1]), (char *) NULL); + if (tkwin == NULL) { return TCL_ERROR; } - scalePtr = TkpCreateScale(new); + + Tk_SetClass(tkwin, "Scale"); + scalePtr = TkpCreateScale(tkwin); /* * Initialize fields that won't be initialized by ConfigureScale, @@ -200,29 +257,30 @@ Tk_ScaleCmd(clientData, interp, argc, argv) * (e.g. resource pointers). */ - scalePtr->tkwin = new; - scalePtr->display = Tk_Display(new); + scalePtr->tkwin = tkwin; + scalePtr->display = Tk_Display(tkwin); scalePtr->interp = interp; - scalePtr->widgetCmd = Tcl_CreateCommand(interp, - Tk_PathName(scalePtr->tkwin), ScaleWidgetCmd, + scalePtr->widgetCmd = Tcl_CreateObjCommand(interp, + Tk_PathName(scalePtr->tkwin), ScaleWidgetObjCmd, (ClientData) scalePtr, ScaleCmdDeletedProc); - scalePtr->orientUid = NULL; - scalePtr->vertical = 0; + scalePtr->optionTable = optionTable; + scalePtr->orient = ORIENT_VERTICAL; scalePtr->width = 0; scalePtr->length = 0; - scalePtr->value = 0; - scalePtr->varName = NULL; - scalePtr->fromValue = 0; - scalePtr->toValue = 0; - scalePtr->tickInterval = 0; + scalePtr->value = 0.0; + scalePtr->varNamePtr = NULL; + scalePtr->fromValue = 0.0; + scalePtr->toValue = 0.0; + scalePtr->tickInterval = 0.0; scalePtr->resolution = 1; + scalePtr->digits = 0; scalePtr->bigIncrement = 0.0; - scalePtr->command = NULL; + scalePtr->commandPtr = NULL; scalePtr->repeatDelay = 0; scalePtr->repeatInterval = 0; - scalePtr->label = NULL; + scalePtr->labelPtr = NULL; scalePtr->labelLength = 0; - scalePtr->state = tkNormalUid; + scalePtr->state = STATE_NORMAL; scalePtr->borderWidth = 0; scalePtr->bgBorder = NULL; scalePtr->activeBorder = NULL; @@ -235,7 +293,7 @@ Tk_ScaleCmd(clientData, interp, argc, argv) scalePtr->textGC = None; scalePtr->relief = TK_RELIEF_FLAT; scalePtr->highlightWidth = 0; - scalePtr->highlightBgColorPtr = NULL; + scalePtr->highlightBorder = NULL; scalePtr->highlightColorPtr = NULL; scalePtr->inset = 0; scalePtr->sliderLength = 0; @@ -249,30 +307,32 @@ Tk_ScaleCmd(clientData, interp, argc, argv) scalePtr->vertTroughX = 0; scalePtr->vertLabelX = 0; scalePtr->cursor = None; - scalePtr->takeFocus = NULL; + scalePtr->takeFocusPtr = NULL; scalePtr->flags = NEVER_SET; - Tk_SetClass(scalePtr->tkwin, "Scale"); TkSetClassProcs(scalePtr->tkwin, &scaleClass, (ClientData) scalePtr); Tk_CreateEventHandler(scalePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, ScaleEventProc, (ClientData) scalePtr); - if (ConfigureScale(interp, scalePtr, argc-2, argv+2, 0) != TCL_OK) { - goto error; - } - interp->result = Tk_PathName(scalePtr->tkwin); + if (Tk_InitOptions(interp, (char *) scalePtr, optionTable, tkwin) + != TCL_OK) { + Tk_DestroyWindow(scalePtr->tkwin); + return TCL_ERROR; + } + if (ConfigureScale(interp, scalePtr, objc - 2, objv + 2) != TCL_OK) { + Tk_DestroyWindow(scalePtr->tkwin); + return TCL_ERROR; + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), Tk_PathName(scalePtr->tkwin), + -1); return TCL_OK; - - error: - Tk_DestroyWindow(scalePtr->tkwin); - return TCL_ERROR; } /* *-------------------------------------------------------------- * - * ScaleWidgetCmd -- + * ScaleWidgetObjCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. @@ -288,131 +348,152 @@ Tk_ScaleCmd(clientData, interp, argc, argv) */ static int -ScaleWidgetCmd(clientData, interp, argc, argv) +ScaleWidgetObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about scale * widget. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument strings. */ { - register TkScale *scalePtr = (TkScale *) clientData; - int result = TCL_OK; - size_t length; - int c; + TkScale *scalePtr = (TkScale *) clientData; + Tcl_Obj *objPtr; + int index, result; - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; } + result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, + "option", 0, &index); + if (result != TCL_OK) { + return result; + } Tcl_Preserve((ClientData) scalePtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - goto error; - } - result = Tk_ConfigureValue(interp, scalePtr->tkwin, configSpecs, - (char *) scalePtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 3)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, scalePtr->tkwin, configSpecs, - (char *) scalePtr, (char *) NULL, 0); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, scalePtr->tkwin, configSpecs, - (char *) scalePtr, argv[2], 0); - } else { - result = ConfigureScale(interp, scalePtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); - } - } else if ((c == 'c') && (strncmp(argv[1], "coords", length) == 0) - && (length >= 3)) { - int x, y ; - double value; - - if ((argc != 2) && (argc != 3)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " coords ?value?\"", (char *) NULL); - goto error; - } - if (argc == 3) { - if (Tcl_GetDouble(interp, argv[2], &value) != TCL_OK) { + + switch (index) { + case COMMAND_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } - } else { - value = scalePtr->value; - } - if (scalePtr->vertical) { - x = scalePtr->vertTroughX + scalePtr->width/2 - + scalePtr->borderWidth; - y = TkpValueToPixel(scalePtr, value); - } else { - x = TkpValueToPixel(scalePtr, value); - y = scalePtr->horizTroughY + scalePtr->width/2 - + scalePtr->borderWidth; + objPtr = Tk_GetOptionValue(interp, (char *) scalePtr, + scalePtr->optionTable, objv[2], scalePtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + break; } - sprintf(interp->result, "%d %d", x, y); - } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { - double value; - int x, y; - - if ((argc != 2) && (argc != 4)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " get ?x y?\"", (char *) NULL); - goto error; + case COMMAND_CONFIGURE: { + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) scalePtr, + scalePtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + scalePtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + } else { + result = ConfigureScale(interp, scalePtr, objc-2, objv+2); + } + break; } - if (argc == 2) { - value = scalePtr->value; - } else { - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { + case COMMAND_COORDS: { + int x, y ; + double value; + char buf[TCL_INTEGER_SPACE * 2]; + + if ((objc != 2) && (objc != 3)) { + Tcl_WrongNumArgs(interp, 1, objv, "coords ?value?"); goto error; } - value = TkpPixelToValue(scalePtr, x, y); - } - sprintf(interp->result, scalePtr->format, value); - } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) { - int x, y, thing; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " identify x y\"", (char *) NULL); - goto error; - } - if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) - || (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) { - goto error; - } - thing = TkpScaleElement(scalePtr, x,y); - switch (thing) { - case TROUGH1: interp->result = "trough1"; break; - case SLIDER: interp->result = "slider"; break; - case TROUGH2: interp->result = "trough2"; break; - } - } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) { - double value; + if (objc == 3) { + if (Tcl_GetDoubleFromObj(interp, objv[2], &value) + != TCL_OK) { + goto error; + } + } else { + value = scalePtr->value; + } + if (scalePtr->orient == ORIENT_VERTICAL) { + x = scalePtr->vertTroughX + scalePtr->width/2 + + scalePtr->borderWidth; + y = TkpValueToPixel(scalePtr, value); + } else { + x = TkpValueToPixel(scalePtr, value); + y = scalePtr->horizTroughY + scalePtr->width/2 + + scalePtr->borderWidth; + } + sprintf(buf, "%d %d", x, y); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } + case COMMAND_GET: { + double value; + int x, y; + char buf[TCL_DOUBLE_SPACE]; + + if ((objc != 2) && (objc != 4)) { + Tcl_WrongNumArgs(interp, 1, objv, "get ?x y?"); + goto error; + } + if (objc == 2) { + value = scalePtr->value; + } else { + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) + != TCL_OK)) { + goto error; + } + value = TkpPixelToValue(scalePtr, x, y); + } + sprintf(buf, scalePtr->format, value); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } + case COMMAND_IDENTIFY: { + int x, y, thing; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "identify x y"); + goto error; + } + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) + || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { + goto error; + } + thing = TkpScaleElement(scalePtr, x,y); + switch (thing) { + case TROUGH1: + Tcl_SetResult(interp, "trough1", TCL_STATIC); + break; + case SLIDER: + Tcl_SetResult(interp, "slider", TCL_STATIC); + break; + case TROUGH2: + Tcl_SetResult(interp, "trough2", TCL_STATIC); + break; + } + break; + } + case COMMAND_SET: { + double value; - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " set value\"", (char *) NULL); - goto error; - } - if (Tcl_GetDouble(interp, argv[2], &value) != TCL_OK) { - goto error; - } - if (scalePtr->state != tkDisabledUid) { - TkpSetScaleValue(scalePtr, value, 1, 1); - } - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be cget, configure, coords, get, identify, or set", - (char *) NULL); - goto error; + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "set value"); + goto error; + } + if (Tcl_GetDoubleFromObj(interp, objv[2], &value) != TCL_OK) { + goto error; + } + if ((scalePtr->state != STATE_DISABLED)) { + TkpSetScaleValue(scalePtr, value, 1, 1); + } + break; + } } Tcl_Release((ClientData) scalePtr); return result; @@ -452,8 +533,8 @@ DestroyScale(memPtr) * stuff. */ - if (scalePtr->varName != NULL) { - Tcl_UntraceVar(scalePtr->interp, scalePtr->varName, + if (scalePtr->varNamePtr != NULL) { + Tcl_UntraceVar(scalePtr->interp, Tcl_GetString(scalePtr->varNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ScaleVarProc, (ClientData) scalePtr); } @@ -466,7 +547,8 @@ DestroyScale(memPtr) if (scalePtr->textGC != None) { Tk_FreeGC(scalePtr->display, scalePtr->textGC); } - Tk_FreeOptions(configSpecs, (char *) scalePtr, scalePtr->display, 0); + Tk_FreeConfigOptions((char *) scalePtr, scalePtr->optionTable, + scalePtr->tkwin); TkpDestroyScale(scalePtr); } @@ -481,7 +563,7 @@ DestroyScale(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, @@ -492,118 +574,135 @@ DestroyScale(memPtr) */ static int -ConfigureScale(interp, scalePtr, argc, argv, flags) +ConfigureScale(interp, scalePtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ register TkScale *scalePtr; /* Information about widget; may or may * not already have values for some fields. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Flags to pass to Tk_ConfigureWidget. */ + int objc; /* Number of valid entries in objv. */ + Tcl_Obj *CONST objv[]; /* Argument values. */ { - size_t length; + Tk_SavedOptions savedOptions; + Tcl_Obj *errorResult = NULL; + int error; + char *label; /* * Eliminate any existing trace on a variable monitored by the scale. */ - if (scalePtr->varName != NULL) { - Tcl_UntraceVar(interp, scalePtr->varName, + if (scalePtr->varNamePtr != NULL) { + Tcl_UntraceVar(interp, Tcl_GetString(scalePtr->varNamePtr), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ScaleVarProc, (ClientData) scalePtr); } - if (Tk_ConfigureWidget(interp, scalePtr->tkwin, configSpecs, - argc, argv, (char *) scalePtr, flags) != TCL_OK) { - return TCL_ERROR; - } + for (error = 0; error <= 1; error++) { + if (!error) { + /* + * First pass: set options to new values. + */ - /* - * If the scale is tied to the value of a variable, then set up - * a trace on the variable's value and set the scale's value from - * the value of the variable, if it exists. - */ + if (Tk_SetOptions(interp, (char *) scalePtr, + scalePtr->optionTable, objc, objv, + scalePtr->tkwin, &savedOptions, (int *) NULL) != TCL_OK) { + continue; + } + } else { + /* + * Second pass: restore options to old values. + */ - if (scalePtr->varName != NULL) { - char *stringValue, *end; - double value; + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); + } + + /* + * If the scale is tied to the value of a variable, then set + * the scale's value from the value of the variable, if it exists. + */ + + if (scalePtr->varNamePtr != NULL) { + char *name; + double value; + Tcl_Obj *valuePtr; - stringValue = Tcl_GetVar(interp, scalePtr->varName, TCL_GLOBAL_ONLY); - if (stringValue != NULL) { - value = strtod(stringValue, &end); - if ((end != stringValue) && (*end == 0)) { - scalePtr->value = TkRoundToResolution(scalePtr, value); + name = Tcl_GetString(scalePtr->varNamePtr); + valuePtr = Tcl_GetVar2Ex(interp, name, NULL, TCL_GLOBAL_ONLY); + if (valuePtr != NULL) { + Tcl_GetDoubleFromObj(interp, valuePtr, &value); } + scalePtr->value = TkRoundToResolution(scalePtr, value); } - Tcl_TraceVar(interp, scalePtr->varName, - TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, - ScaleVarProc, (ClientData) scalePtr); - } - /* - * Several options need special processing, such as parsing the - * orientation and creating GCs. - */ + /* + * Several options need special processing, such as parsing the + * orientation and creating GCs. + */ - length = strlen(scalePtr->orientUid); - if (strncmp(scalePtr->orientUid, "vertical", length) == 0) { - scalePtr->vertical = 1; - } else if (strncmp(scalePtr->orientUid, "horizontal", length) == 0) { - scalePtr->vertical = 0; - } else { - Tcl_AppendResult(interp, "bad orientation \"", scalePtr->orientUid, - "\": must be vertical or horizontal", (char *) NULL); - return TCL_ERROR; - } + scalePtr->fromValue = TkRoundToResolution(scalePtr, + scalePtr->fromValue); + scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue); + scalePtr->tickInterval = TkRoundToResolution(scalePtr, + scalePtr->tickInterval); - scalePtr->fromValue = TkRoundToResolution(scalePtr, scalePtr->fromValue); - scalePtr->toValue = TkRoundToResolution(scalePtr, scalePtr->toValue); - scalePtr->tickInterval = TkRoundToResolution(scalePtr, - scalePtr->tickInterval); + /* + * Make sure that the tick interval has the right sign so that + * addition moves from fromValue to toValue. + */ - /* - * Make sure that the tick interval has the right sign so that - * addition moves from fromValue to toValue. - */ + if ((scalePtr->tickInterval < 0) + ^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) { + scalePtr->tickInterval = -scalePtr->tickInterval; + } - if ((scalePtr->tickInterval < 0) - ^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) { - scalePtr->tickInterval = -scalePtr->tickInterval; - } + /* + * Set the scale value to itself; all this does is to make sure + * that the scale's value is within the new acceptable range for + * the scale and reflect the value in the associated variable, + * if any. + */ - /* - * Set the scale value to itself; all this does is to make sure - * that the scale's value is within the new acceptable range for - * the scale and reflect the value in the associated variable, - * if any. - */ + ComputeFormat(scalePtr); + TkpSetScaleValue(scalePtr, scalePtr->value, 1, 1); - ComputeFormat(scalePtr); - TkpSetScaleValue(scalePtr, scalePtr->value, 1, 1); + if (scalePtr->labelPtr != NULL) { + label = Tcl_GetString(scalePtr->labelPtr); + scalePtr->labelLength = strlen(label); + } else { + scalePtr->labelLength = 0; + } - if (scalePtr->label != NULL) { - scalePtr->labelLength = strlen(scalePtr->label); - } else { - scalePtr->labelLength = 0; - } + Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder); - if ((scalePtr->state != tkNormalUid) - && (scalePtr->state != tkDisabledUid) - && (scalePtr->state != tkActiveUid)) { - Tcl_AppendResult(interp, "bad state value \"", scalePtr->state, - "\": must be normal, active, or disabled", (char *) NULL); - scalePtr->state = tkNormalUid; - return TCL_ERROR; + if (scalePtr->highlightWidth < 0) { + scalePtr->highlightWidth = 0; + } + scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth; + break; + } + if (!error) { + Tk_FreeSavedOptions(&savedOptions); } - Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder); + /* + * Reestablish the variable trace, if it is needed. + */ - if (scalePtr->highlightWidth < 0) { - scalePtr->highlightWidth = 0; + if (scalePtr->varNamePtr != NULL) { + Tcl_TraceVar(interp, Tcl_GetString(scalePtr->varNamePtr), + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, (ClientData) scalePtr); } - scalePtr->inset = scalePtr->highlightWidth + scalePtr->borderWidth; ScaleWorldChanged((ClientData) scalePtr); - return TCL_OK; + if (error) { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); + return TCL_ERROR; + } else { + return TCL_OK; + } } /* @@ -801,6 +900,7 @@ ComputeScaleGeometry(scalePtr) char valueString[PRINT_CHARS]; int tmp, valuePixels, x, y, extraSpace; Tk_FontMetrics fm; + char *label; /* * Horizontal scales are simpler than vertical ones because @@ -809,7 +909,7 @@ ComputeScaleGeometry(scalePtr) */ Tk_GetFontMetrics(scalePtr->tkfont, &fm); - if (!scalePtr->vertical) { + if (!scalePtr->orient == ORIENT_VERTICAL) { y = scalePtr->inset; extraSpace = 0; if (scalePtr->labelLength != 0) { @@ -881,8 +981,9 @@ ComputeScaleGeometry(scalePtr) scalePtr->vertLabelX = 0; } else { scalePtr->vertLabelX = x + fm.ascent/2; + label = Tcl_GetString(scalePtr->labelPtr); x = scalePtr->vertLabelX + fm.ascent/2 - + Tk_TextWidth(scalePtr->tkfont, scalePtr->label, + + Tk_TextWidth(scalePtr->tkfont, label, scalePtr->labelLength); } Tk_GeometryRequest(scalePtr->tkwin, x + scalePtr->inset, @@ -1089,8 +1190,12 @@ ScaleVarProc(clientData, interp, name1, name2, flags) int flags; /* Information about what happened. */ { register TkScale *scalePtr = (TkScale *) clientData; - char *stringValue, *end, *result; + char *resultStr, *name; double value; + Tcl_Obj *valuePtr; + int result; + + name = Tcl_GetString(scalePtr->varNamePtr); /* * If the variable is unset, then immediately recreate it unless @@ -1099,7 +1204,7 @@ ScaleVarProc(clientData, interp, name1, name2, flags) if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { - Tcl_TraceVar(interp, scalePtr->varName, + Tcl_TraceVar(interp, name, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ScaleVarProc, clientData); scalePtr->flags |= NEVER_SET; @@ -1117,27 +1222,26 @@ ScaleVarProc(clientData, interp, name1, name2, flags) if (scalePtr->flags & SETTING_VAR) { return (char *) NULL; } - result = NULL; - stringValue = Tcl_GetVar(interp, scalePtr->varName, TCL_GLOBAL_ONLY); - if (stringValue != NULL) { - value = strtod(stringValue, &end); - if ((end == stringValue) || (*end != 0)) { - result = "can't assign non-numeric value to scale variable"; - } else { - scalePtr->value = TkRoundToResolution(scalePtr, value); - } - - /* - * This code is a bit tricky because it sets the scale's value before - * calling TkpSetScaleValue. This way, TkpSetScaleValue won't bother - * to set the variable again or to invoke the -command. However, it - * also won't redisplay the scale, so we have to ask for that - * explicitly. - */ - - TkpSetScaleValue(scalePtr, scalePtr->value, 1, 0); - TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER); + resultStr = NULL; + valuePtr = Tcl_GetVar2Ex(interp, name, NULL, + TCL_GLOBAL_ONLY); + result = Tcl_GetDoubleFromObj(interp, valuePtr, &value); + if (result != TCL_OK) { + resultStr = "can't assign non-numeric value to scale variable"; + } else { + scalePtr->value = TkRoundToResolution(scalePtr, value); + + /* + * This code is a bit tricky because it sets the scale's value before + * calling TkpSetScaleValue. This way, TkpSetScaleValue won't bother + * to set the variable again or to invoke the -command. However, it + * also won't redisplay the scale, so we have to ask for that + * explicitly. + */ + + TkpSetScaleValue(scalePtr, scalePtr->value, 1, 0); + TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER); } - return result; + return resultStr; } diff --git a/generic/tkScale.h b/generic/tkScale.h index 7200fb2..af0ca43 100644 --- a/generic/tkScale.h +++ b/generic/tkScale.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkScale.h,v 1.4 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkScale.h,v 1.5 1999/04/16 01:51:21 stanton Exp $ */ #ifndef _TKSCALE @@ -25,6 +25,22 @@ #endif /* + * Legal values for the "orient" field of TkScale records. + */ + +enum orient { + ORIENT_HORIZONTAL, ORIENT_VERTICAL +}; + +/* + * Legal values for the "state" field of TkScale records. + */ + +enum state { + STATE_ACTIVE, STATE_DISABLED, STATE_NORMAL +}; + +/* * A data structure of the following type is kept for each scale * widget managed by this file: */ @@ -39,16 +55,16 @@ typedef struct TkScale { * freed even after tkwin has gone away. */ Tcl_Interp *interp; /* Interpreter associated with scale. */ Tcl_Command widgetCmd; /* Token for scale's widget command. */ - Tk_Uid orientUid; /* Orientation for window ("vertical" or - * "horizontal"). */ - int vertical; /* Non-zero means vertical orientation, - * zero means horizontal. */ + Tk_OptionTable optionTable; /* Table that defines configuration options + * available for this widget. */ + enum orient orient; /* Orientation for window (vertical or + * horizontal). */ int width; /* Desired narrow dimension of scale, * in pixels. */ int length; /* Desired long dimension of scale, * in pixels. */ - double value; /* Current value of scale. */ - char *varName; /* Name of variable (malloc'ed) or NULL. + double value; /* Current value of scale. */ + Tcl_Obj *varNamePtr; /* Name of variable or NULL. * If non-NULL, scale's value tracks * the contents of this variable and * vice versa. */ @@ -68,19 +84,19 @@ typedef struct TkScale { * digits and other information. */ double bigIncrement; /* Amount to use for large increments to * scale value. (0 means we pick a value). */ - char *command; /* Command prefix to use when invoking Tcl + Tcl_Obj *commandPtr; /* Command prefix to use when invoking Tcl * commands because the scale value changed. - * NULL means don't invoke commands. - * Malloc'ed. */ + * NULL means don't invoke commands. */ int repeatDelay; /* How long to wait before auto-repeating * on scrolling actions (in ms). */ int repeatInterval; /* Interval between autorepeats (in ms). */ - char *label; /* Label to display above or to right of + Tcl_Obj *labelPtr; /* Label to display above or to right of * scale; NULL means don't display a - * label. Malloc'ed. */ + * label. */ int labelLength; /* Number of non-NULL chars. in label. */ - Tk_Uid state; /* Normal or disabled. Value cannot be - * changed when scale is disabled. */ + enum state state; /* Values are active, normal, or disabled. + * Value of scale cannot be changed when + * disabled. */ /* * Information used when displaying widget: @@ -90,7 +106,8 @@ typedef struct TkScale { Tk_3DBorder bgBorder; /* Used for drawing slider and other * background areas. */ Tk_3DBorder activeBorder; /* For drawing the slider when active. */ - int sliderRelief; /* Is slider to be drawn raised, sunken, etc. */ + int sliderRelief; /* Is slider to be drawn raised, sunken, + * etc. */ XColor *troughColorPtr; /* Color for drawing trough. */ GC troughGC; /* For drawing trough. */ GC copyGC; /* Used for copying from pixmap onto screen. */ @@ -102,9 +119,10 @@ typedef struct TkScale { int highlightWidth; /* Width in pixels of highlight to draw * around widget when it has the focus. * <= 0 means don't draw a highlight. */ - XColor *highlightBgColorPtr; - /* Color for drawing traversal highlight - * area when highlight is off. */ + Tk_3DBorder highlightBorder;/* Value of -highlightbackground option: + * specifies background with which to draw 3-D + * default ring and focus highlight area when + * highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ int inset; /* Total width of all borders, including * traversal highlight and 3-D border. @@ -141,9 +159,9 @@ typedef struct TkScale { */ Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *takeFocus; /* Value of -takefocus option; not used in + Tcl_Obj *takeFocusPtr; /* Value of -takefocus option; not used in * the C code, but used by keyboard traversal - * scripts. Malloc'ed, but may be NULL. */ + * scripts. May be NULL. */ int flags; /* Various flags; see below for * definitions. */ } TkScale; @@ -207,7 +225,7 @@ typedef struct TkScale { #define PRINT_CHARS 150 /* - * Declaration of procedures used in the implementation of the scrollbar + * Declaration of procedures used in the implementation of the scale * widget. */ diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c index 0b90160..e00581a 100644 --- a/generic/tkScrollbar.c +++ b/generic/tkScrollbar.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkScrollbar.c,v 1.2 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkScrollbar.c,v 1.3 1999/04/16 01:51:21 stanton Exp $ */ #include "tkPort.h" @@ -193,7 +193,7 @@ Tk_ScrollbarCmd(clientData, interp, argc, argv) return TCL_ERROR; } - interp->result = Tk_PathName(scrollPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(scrollPtr->tkwin), TCL_STATIC); return TCL_OK; } @@ -240,9 +240,15 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) int oldActiveField; if (argc == 2) { switch (scrollPtr->activeField) { - case TOP_ARROW: interp->result = "arrow1"; break; - case SLIDER: interp->result = "slider"; break; - case BOTTOM_ARROW: interp->result = "arrow2"; break; + case TOP_ARROW: + Tcl_SetResult(interp, "arrow1", TCL_STATIC); + break; + case SLIDER: + Tcl_SetResult(interp, "slider", TCL_STATIC); + break; + case BOTTOM_ARROW: + Tcl_SetResult(interp, "arrow2", TCL_STATIC); + break; } goto done; } @@ -292,6 +298,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) } else if ((c == 'd') && (strncmp(argv[1], "delta", length) == 0)) { int xDelta, yDelta, pixels, length; double fraction; + char buf[TCL_DOUBLE_SPACE]; if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -316,10 +323,12 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) } else { fraction = ((double) pixels / (double) length); } - sprintf(interp->result, "%g", fraction); + sprintf(buf, "%g", fraction); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'f') && (strncmp(argv[1], "fraction", length) == 0)) { int x, y, pos, length; double fraction; + char buf[TCL_DOUBLE_SPACE]; if (argc != 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -349,7 +358,8 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) } else if (fraction > 1.0) { fraction = 1.0; } - sprintf(interp->result, "%g", fraction); + sprintf(buf, "%g", fraction); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -363,9 +373,12 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) Tcl_PrintDouble(interp, scrollPtr->lastFraction, last); Tcl_AppendResult(interp, first, " ", last, (char *) NULL); } else { - sprintf(interp->result, "%d %d %d %d", scrollPtr->totalUnits, + char buf[TCL_INTEGER_SPACE * 4]; + + sprintf(buf, "%d %d %d %d", scrollPtr->totalUnits, scrollPtr->windowUnits, scrollPtr->firstUnit, scrollPtr->lastUnit); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 'i') && (strncmp(argv[1], "identify", length) == 0)) { int x, y, thing; @@ -381,11 +394,21 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) } thing = TkpScrollbarPosition(scrollPtr, x,y); switch (thing) { - case TOP_ARROW: interp->result = "arrow1"; break; - case TOP_GAP: interp->result = "trough1"; break; - case SLIDER: interp->result = "slider"; break; - case BOTTOM_GAP: interp->result = "trough2"; break; - case BOTTOM_ARROW: interp->result = "arrow2"; break; + case TOP_ARROW: + Tcl_SetResult(interp, "arrow1", TCL_STATIC); + break; + case TOP_GAP: + Tcl_SetResult(interp, "trough1", TCL_STATIC); + break; + case SLIDER: + Tcl_SetResult(interp, "slider", TCL_STATIC); + break; + case BOTTOM_GAP: + Tcl_SetResult(interp, "trough2", TCL_STATIC); + break; + case BOTTOM_ARROW: + Tcl_SetResult(interp, "arrow2", TCL_STATIC); + break; } } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) { int totalUnits, windowUnits, firstUnit, lastUnit; @@ -488,7 +511,7 @@ ScrollbarWidgetCmd(clientData, interp, argc, argv) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, diff --git a/generic/tkSelect.c b/generic/tkSelect.c index 01e8af4..fe8f119 100644 --- a/generic/tkSelect.c +++ b/generic/tkSelect.c @@ -6,12 +6,12 @@ * and Tcl commands. * * Copyright (c) 1990-1993 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkSelect.c,v 1.2 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkSelect.c,v 1.3 1999/04/16 01:51:21 stanton Exp $ */ #include "tkInt.h" @@ -45,12 +45,16 @@ typedef struct LostCommand { } LostCommand; /* - * Shared variables: + * The structure below is used to keep each thread's pending list + * separate. */ -TkSelInProgress *pendingPtr = NULL; +typedef struct ThreadSpecificData { + TkSelInProgress *pendingPtr; /* Topmost search in progress, or * NULL if none. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Forward declarations for procedures defined in this file: @@ -199,6 +203,8 @@ Tk_DeleteSelHandler(tkwin, selection, target) TkWindow *winPtr = (TkWindow *) tkwin; register TkSelHandler *selPtr, *prevPtr; register TkSelInProgress *ipPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the selection handler to be deleted, or return if it doesn't @@ -220,7 +226,8 @@ Tk_DeleteSelHandler(tkwin, selection, target) * handler is dead. */ - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; + ipPtr = ipPtr->nextPtr) { if (ipPtr->selPtr == selPtr) { ipPtr->selPtr = NULL; } @@ -431,7 +438,7 @@ Tk_ClearSelection(tkwin, selection) * Results: * The return value is a standard Tcl return value. * If an error occurs (such as no selection exists) - * then an error message is left in interp->result. + * then an error message is left in the interp's result. * * Side effects: * The standard X11 protocols are used to retrieve the @@ -457,7 +464,7 @@ Tk_ClearSelection(tkwin, selection) * the "portion" arguments in separate calls will contain * successive parts of the selection. Proc should normally * return TCL_OK. If it detects an error then it should return - * TCL_ERROR and leave an error message in interp->result; the + * TCL_ERROR and leave an error message in the interp's result; the * remainder of the selection retrieval will be aborted. * *-------------------------------------------------------------- @@ -480,6 +487,8 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData) TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (dispPtr->multipleAtom == None) { TkSelInit(tkwin); @@ -528,13 +537,13 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData) offset = 0; result = TCL_OK; ip.selPtr = selPtr; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = tsdPtr->pendingPtr; + tsdPtr->pendingPtr = &ip; while (1) { count = (selPtr->proc)(selPtr->clientData, offset, buffer, TK_SEL_BYTES_AT_ONCE); if ((count < 0) || (ip.selPtr == NULL)) { - pendingPtr = ip.nextPtr; + tsdPtr->pendingPtr = ip.nextPtr; goto cantget; } if (count > TK_SEL_BYTES_AT_ONCE) { @@ -548,7 +557,7 @@ Tk_GetSelection(interp, tkwin, selection, target, proc, clientData) } offset += count; } - pendingPtr = ip.nextPtr; + tsdPtr->pendingPtr = ip.nextPtr; } return result; } @@ -602,9 +611,8 @@ Tk_SelectionCmd(clientData, interp, argc, argv) char **args; if (argc < 2) { - sprintf(interp->result, - "wrong # args: should be \"%.50s option ?arg arg ...?\"", - argv[0]); + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " option ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } c = argv[1][0]; @@ -854,7 +862,7 @@ Tk_SelectionCmd(clientData, interp, argc, argv) if ((infoPtr != NULL) && (infoPtr->owner != winPtr->dispPtr->clipWindow)) { - interp->result = Tk_PathName(infoPtr->owner); + Tcl_SetResult(interp, Tk_PathName(infoPtr->owner), TCL_STATIC); } return TCL_OK; } @@ -878,9 +886,8 @@ Tk_SelectionCmd(clientData, interp, argc, argv) Tk_OwnSelection(tkwin, selection, LostSelection, (ClientData) lostPtr); return TCL_OK; } else { - sprintf(interp->result, - "bad option \"%.50s\": must be clear, get, handle, or own", - argv[1]); + Tcl_AppendResult(interp, "bad option \"", argv[1], + "\": must be clear, get, handle, or own", (char *) NULL); return TCL_ERROR; } } @@ -888,6 +895,60 @@ Tk_SelectionCmd(clientData, interp, argc, argv) /* *---------------------------------------------------------------------- * + * TkSelGetInProgress -- + * + * This procedure returns a pointer to the thread-local + * list of pending searches. + * + * Results: + * The return value is a pointer to the first search in progress, + * or NULL if there are none. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TkSelInProgress * +TkSelGetInProgress(void) +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + return tsdPtr->pendingPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TkSelSetInProgress -- + * + * This procedure is used to set the thread-local list of pending + * searches. It is required because the pending list is kept + * in thread local storage. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TkSelSetInProgress(pendingPtr) + TkSelInProgress *pendingPtr; +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + tsdPtr->pendingPtr = pendingPtr; +} + +/* + *---------------------------------------------------------------------- + * * TkSelDeadWindow -- * * This procedure is invoked just before a TkWindow is deleted. @@ -909,6 +970,8 @@ TkSelDeadWindow(winPtr) register TkSelHandler *selPtr; register TkSelInProgress *ipPtr; TkSelectionInfo *infoPtr, *prevPtr, *nextPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * While deleting all the handlers, be careful to check whether @@ -919,7 +982,8 @@ TkSelDeadWindow(winPtr) while (winPtr->selHandlerList != NULL) { selPtr = winPtr->selHandlerList; winPtr->selHandlerList = selPtr->nextPtr; - for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { + for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; + ipPtr = ipPtr->nextPtr) { if (ipPtr->selPtr == selPtr) { ipPtr->selPtr = NULL; } @@ -1155,11 +1219,12 @@ HandleTclCommand(clientData, offset, buffer, maxBytes) Tcl_DStringInit(&oldResult); Tcl_DStringGetResult(interp, &oldResult); if (TkCopyAndGlobalEval(interp, command) == TCL_OK) { - length = strlen(interp->result); + length = strlen(Tcl_GetStringResult(interp)); if (length > maxBytes) { length = maxBytes; } - memcpy((VOID *) buffer, (VOID *) interp->result, (size_t) length); + memcpy((VOID *) buffer, (VOID *) Tcl_GetStringResult(interp), + (size_t) length); buffer[length] = '\0'; } else { length = -1; @@ -1302,8 +1367,7 @@ LostSelection(clientData) ClientData clientData; /* Pointer to CommandInfo structure. */ { LostCommand *lostPtr = (LostCommand *) clientData; - char *oldResultString; - Tcl_FreeProc *oldFreeProc; + Tcl_Obj *objPtr; Tcl_Interp *interp; interp = lostPtr->interp; @@ -1314,22 +1378,16 @@ LostSelection(clientData) * restore it after executing the command. */ - oldFreeProc = interp->freeProc; - if (oldFreeProc != TCL_STATIC) { - oldResultString = interp->result; - } else { - oldResultString = (char *) ckalloc((unsigned) - (strlen(interp->result) + 1)); - strcpy(oldResultString, interp->result); - oldFreeProc = TCL_DYNAMIC; - } - interp->freeProc = TCL_STATIC; + objPtr = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(objPtr); + Tcl_ResetResult(interp); + if (TkCopyAndGlobalEval(interp, lostPtr->command) != TCL_OK) { Tcl_BackgroundError(interp); } - Tcl_FreeResult(interp); - interp->result = oldResultString; - interp->freeProc = oldFreeProc; + + Tcl_SetObjResult(interp, objPtr); + Tcl_DecrRefCount(objPtr); Tcl_Release((ClientData) interp); diff --git a/generic/tkSelect.h b/generic/tkSelect.h index 4963f71..0d8c644 100644 --- a/generic/tkSelect.h +++ b/generic/tkSelect.h @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkSelect.h,v 1.2 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkSelect.h,v 1.3 1999/04/16 01:51:22 stanton Exp $ */ #ifndef _TKSELECT @@ -146,14 +146,6 @@ typedef struct TkSelInProgress { } TkSelInProgress; /* - * Declarations for variables shared among the selection-related files: - */ - -extern TkSelInProgress *pendingPtr; - /* Topmost search in progress, or - * NULL if none. */ - -/* * Chunk size for retrieving selection. It's defined both in * words and in bytes; the word size is used to allocate * buffer space that's guaranteed to be word-aligned and that @@ -168,6 +160,11 @@ extern TkSelInProgress *pendingPtr; * but shouldn't be used anywhere else in Tk (or by Tk clients): */ +extern TkSelInProgress * + TkSelGetInProgress _ANSI_ARGS_((void)); +extern void TkSelSetInProgress _ANSI_ARGS_(( + TkSelInProgress *pendingPtr)); + extern void TkSelClearSelection _ANSI_ARGS_((Tk_Window tkwin, XEvent *eventPtr)); extern int TkSelDefaultSelection _ANSI_ARGS_(( diff --git a/generic/tkSquare.c b/generic/tkSquare.c index e7cc047..a835e31 100644 --- a/generic/tkSquare.c +++ b/generic/tkSquare.c @@ -1,23 +1,24 @@ /* * tkSquare.c -- * - * This module implements "square" widgets. A "square" is - * a widget that displays a single square that can be moved - * around and resized. This file is intended as an example + * This module implements "square" widgets that are object + * based. A "square" is a widget that displays a single square that can + * be moved around and resized. This file is intended as an example * of how to build a widget; it isn't included in the * normal wish, but it is included in "tktest". * - * Copyright (c) 1991-1994 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkSquare.c,v 1.2 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkSquare.c,v 1.3 1999/04/16 01:51:22 stanton Exp $ */ #include "tkPort.h" +#define __NO_OLD_CONFIG #include "tk.h" +#include "tkInt.h" /* * A data structure of the following type is kept for each square @@ -31,22 +32,24 @@ typedef struct { Display *display; /* X's token for the window's display. */ Tcl_Interp *interp; /* Interpreter associated with widget. */ Tcl_Command widgetCmd; /* Token for square's widget command. */ - int x, y; /* Position of square's upper-left corner + Tk_OptionTable optionTable; /* Token representing the configuration + * specifications. */ + Tcl_Obj *xPtr, *yPtr; /* Position of square's upper-left corner * within widget. */ - int size; /* Width and height of square. */ + int x, y; + Tcl_Obj *sizeObjPtr; /* Width and height of square. */ /* * Information used when displaying widget: */ - int borderWidth; /* Width of 3-D border around whole widget. */ - Tk_3DBorder bgBorder; /* Used for drawing background. */ - Tk_3DBorder fgBorder; /* For drawing square. */ - int relief; /* Indicates whether window as a whole is - * raised, sunken, or flat. */ + Tcl_Obj *borderWidthPtr; /* Width of 3-D border around whole widget. */ + Tcl_Obj *bgBorderPtr; + Tcl_Obj *fgBorderPtr; + Tcl_Obj *reliefPtr; GC gc; /* Graphics context for copying from * off-screen pixmap onto screen. */ - int doubleBuffer; /* Non-zero means double-buffer redisplay + Tcl_Obj *doubleBufferPtr; /* Non-zero means double-buffer redisplay * with pixmap; zero means draw straight * onto the display. */ int updatePending; /* Non-zero means a call to SquareDisplay @@ -57,49 +60,52 @@ typedef struct { * Information used for argv parsing. */ -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_BORDER, "-background", "background", "Background", - "#d9d9d9", Tk_Offset(Square, bgBorder), TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-background", "background", "Background", - "white", Tk_Offset(Square, bgBorder), TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - "2", Tk_Offset(Square, borderWidth), 0}, - {TK_CONFIG_INT, "-dbl", "doubleBuffer", "DoubleBuffer", - "1", Tk_Offset(Square, doubleBuffer), 0}, - {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL, - (char *) NULL, 0, 0}, - {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", - "#b03060", Tk_Offset(Square, fgBorder), TK_CONFIG_COLOR_ONLY}, - {TK_CONFIG_BORDER, "-foreground", "foreground", "Foreground", - "black", Tk_Offset(Square, fgBorder), TK_CONFIG_MONO_ONLY}, - {TK_CONFIG_RELIEF, "-relief", "relief", "Relief", - "raised", Tk_Offset(Square, relief), 0}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} +static Tk_OptionSpec configSpecs[] = { + {TK_OPTION_BORDER, "-background", "background", "Background", + "#d9d9d9", Tk_Offset(Square, bgBorderPtr), -1, 0, + (ClientData) "white"}, + {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth"}, + {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-background"}, + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + "2", Tk_Offset(Square, borderWidthPtr), -1}, + {TK_OPTION_BOOLEAN, "-dbl", "doubleBuffer", "DoubleBuffer", + "1", Tk_Offset(Square, doubleBufferPtr), -1}, + {TK_OPTION_SYNONYM, "-fg", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-foreground"}, + {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground", + "#b03060", Tk_Offset(Square, fgBorderPtr), -1, 0, + (ClientData) "black"}, + {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0", + Tk_Offset(Square, xPtr), -1}, + {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0", + Tk_Offset(Square, yPtr), -1}, + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", + "raised", Tk_Offset(Square, reliefPtr), -1}, + {TK_OPTION_PIXELS, "-size", "size", "Size", "20", + Tk_Offset(Square, sizeObjPtr), -1}, + {TK_OPTION_END} }; /* * Forward declarations for procedures defined later in this file: */ -int SquareCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char **argv)); -static void SquareCmdDeletedProc _ANSI_ARGS_(( +int SquareObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static void SquareDeletedProc _ANSI_ARGS_(( ClientData clientData)); static int SquareConfigure _ANSI_ARGS_((Tcl_Interp *interp, - Square *squarePtr, int argc, char **argv, - int flags)); + Square *squarePtr)); static void SquareDestroy _ANSI_ARGS_((char *memPtr)); static void SquareDisplay _ANSI_ARGS_((ClientData clientData)); static void KeepInWindow _ANSI_ARGS_((Square *squarePtr)); -static void SquareEventProc _ANSI_ARGS_((ClientData clientData, +static void SquareObjEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static int SquareWidgetCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *, int argc, char **argv)); + Tcl_Interp *, int objc, Tcl_Obj * CONST objv[])); /* *-------------------------------------------------------------- @@ -119,24 +125,41 @@ static int SquareWidgetCmd _ANSI_ARGS_((ClientData clientData, */ int -SquareCmd(clientData, interp, argc, argv) +SquareObjCmd(clientData, interp, objc, objv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj * CONST objv[]; /* Argument objects. */ { - Tk_Window main = (Tk_Window) clientData; Square *squarePtr; Tk_Window tkwin; + Tk_OptionTable optionTable = (Tk_OptionTable) clientData; + Tcl_CmdInfo info; + char *commandName; + + if (optionTable == NULL) { + /* + * The first time this procedure is invoked, optionTable will + * be NULL. We then create the option table from the template + * and store the table pointer as the command's clinical so + * we'll have easy access to it in the future. + */ + + optionTable = Tk_CreateOptionTable(interp, configSpecs); + commandName = Tcl_GetStringFromObj(objv[0], (int *) NULL); + Tcl_GetCommandInfo(interp, commandName, &info); + info.clientData = (ClientData) optionTable; + Tcl_SetCommandInfo(interp, commandName, &info); + } - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " pathName ?options?\"", (char *) NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?"); return TCL_ERROR; } - tkwin = Tk_CreateWindowFromPath(interp, main, argv[1], (char *) NULL); + tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), + Tcl_GetStringFromObj(objv[1], NULL), (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } @@ -150,29 +173,47 @@ SquareCmd(clientData, interp, argc, argv) squarePtr->tkwin = tkwin; squarePtr->display = Tk_Display(tkwin); squarePtr->interp = interp; - squarePtr->widgetCmd = Tcl_CreateCommand(interp, + squarePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(squarePtr->tkwin), SquareWidgetCmd, - (ClientData) squarePtr, SquareCmdDeletedProc); + (ClientData) squarePtr, SquareDeletedProc); + squarePtr->xPtr = NULL; + squarePtr->yPtr = NULL; squarePtr->x = 0; squarePtr->y = 0; - squarePtr->size = 20; - squarePtr->borderWidth = 0; - squarePtr->bgBorder = NULL; - squarePtr->fgBorder = NULL; - squarePtr->relief = TK_RELIEF_FLAT; + squarePtr->sizeObjPtr = NULL; + squarePtr->borderWidthPtr = NULL; + squarePtr->bgBorderPtr = NULL; + squarePtr->fgBorderPtr = NULL; + squarePtr->reliefPtr = NULL; squarePtr->gc = None; - squarePtr->doubleBuffer = 1; + squarePtr->doubleBufferPtr = NULL; squarePtr->updatePending = 0; + squarePtr->optionTable = optionTable; - Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask, - SquareEventProc, (ClientData) squarePtr); - if (SquareConfigure(interp, squarePtr, argc-2, argv+2, 0) != TCL_OK) { + if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin) + != TCL_OK) { Tk_DestroyWindow(squarePtr->tkwin); + ckfree((char *) squarePtr); return TCL_ERROR; } - interp->result = Tk_PathName(squarePtr->tkwin); + Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask, + SquareObjEventProc, (ClientData) squarePtr); + if (Tk_SetOptions(interp, (char *) squarePtr, optionTable, objc - 2, + objv + 2, tkwin, NULL, (int *) NULL) != TCL_OK) { + goto error; + } + if (SquareConfigure(interp, squarePtr) != TCL_OK) { + goto error; + } + + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(squarePtr->tkwin), + -1)); return TCL_OK; + +error: + Tk_DestroyWindow(squarePtr->tkwin); + return TCL_ERROR; } /* @@ -194,92 +235,79 @@ SquareCmd(clientData, interp, argc, argv) */ static int -SquareWidgetCmd(clientData, interp, argc, argv) +SquareWidgetCmd(clientData, interp, objc, objv) ClientData clientData; /* Information about square widget. */ Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ + int objc; /* Number of arguments. */ + Tcl_Obj * CONST objv[]; /* Argument objects. */ { Square *squarePtr = (Square *) clientData; int result = TCL_OK; - size_t length; - char c; + static char *squareOptions[] = {"cget", "configure", (char *) NULL}; + enum { + SQUARE_CGET, SQUARE_CONFIGURE + }; + Tcl_Obj *resultObjPtr; + int index; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?"); + return TCL_ERROR; + } - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", (char *) NULL); + if (Tcl_GetIndexFromObj(interp, objv[1], squareOptions, "command", + 0, &index) != TCL_OK) { return TCL_ERROR; } + Tcl_Preserve((ClientData) squarePtr); - c = argv[1][0]; - length = strlen(argv[1]); - if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - goto error; - } - result = Tk_ConfigureValue(interp, squarePtr->tkwin, configSpecs, - (char *) squarePtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - result = Tk_ConfigureInfo(interp, squarePtr->tkwin, configSpecs, - (char *) squarePtr, (char *) NULL, 0); - } else if (argc == 3) { - result = Tk_ConfigureInfo(interp, squarePtr->tkwin, configSpecs, - (char *) squarePtr, argv[2], 0); - } else { - result = SquareConfigure(interp, squarePtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); - } - } else if ((c == 'p') && (strncmp(argv[1], "position", length) == 0)) { - if ((argc != 2) && (argc != 4)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " position ?x y?\"", (char *) NULL); - goto error; - } - if (argc == 4) { - if ((Tk_GetPixels(interp, squarePtr->tkwin, argv[2], - &squarePtr->x) != TCL_OK) || (Tk_GetPixels(interp, - squarePtr->tkwin, argv[3], &squarePtr->y) != TCL_OK)) { + + switch (index) { + case SQUARE_CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); goto error; } - KeepInWindow(squarePtr); - } - sprintf(interp->result, "%d %d", squarePtr->x, squarePtr->y); - } else if ((c == 's') && (strncmp(argv[1], "size", length) == 0)) { - if ((argc != 2) && (argc != 3)) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " size ?amount?\"", (char *) NULL); - goto error; + resultObjPtr = Tk_GetOptionValue(interp, (char *) squarePtr, + squarePtr->optionTable, objv[2], squarePtr->tkwin); + if (resultObjPtr == NULL) { + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, resultObjPtr); + } + break; } - if (argc == 3) { - int i; - - if (Tk_GetPixels(interp, squarePtr->tkwin, argv[2], &i) != TCL_OK) { - goto error; + case SQUARE_CONFIGURE: { + resultObjPtr = NULL; + if (objc == 2) { + resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr, + squarePtr->optionTable, (Tcl_Obj *) NULL, + squarePtr->tkwin); + if (resultObjPtr == NULL) { + result = TCL_ERROR; + } + } else if (objc == 3) { + resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr, + squarePtr->optionTable, objv[2], squarePtr->tkwin); + if (resultObjPtr == NULL) { + result = TCL_ERROR; + } + } else { + result = Tk_SetOptions(interp, (char *) squarePtr, + squarePtr->optionTable, objc - 2, objv + 2, + squarePtr->tkwin, NULL, (int *) NULL); + if (result == TCL_OK) { + result = SquareConfigure(interp, squarePtr); + } + if (!squarePtr->updatePending) { + Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); + squarePtr->updatePending = 1; + } } - if ((i <= 0) || (i > 100)) { - Tcl_AppendResult(interp, "bad size \"", argv[2], - "\"", (char *) NULL); - goto error; + if (resultObjPtr != NULL) { + Tcl_SetObjResult(interp, resultObjPtr); } - squarePtr->size = i; - KeepInWindow(squarePtr); } - sprintf(interp->result, "%d", squarePtr->size); - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be cget, configure, position, or size", - (char *) NULL); - goto error; - } - if (!squarePtr->updatePending) { - Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); - squarePtr->updatePending = 1; } Tcl_Release((ClientData) squarePtr); return result; @@ -300,7 +328,7 @@ SquareWidgetCmd(clientData, interp, argc, argv) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as colors, border width, @@ -311,27 +339,25 @@ SquareWidgetCmd(clientData, interp, argc, argv) */ static int -SquareConfigure(interp, squarePtr, argc, argv, flags) +SquareConfigure(interp, squarePtr) Tcl_Interp *interp; /* Used for error reporting. */ Square *squarePtr; /* Information about widget. */ - int argc; /* Number of valid entries in argv. */ - char **argv; /* Arguments. */ - int flags; /* Flags to pass to - * Tk_ConfigureWidget. */ { - if (Tk_ConfigureWidget(interp, squarePtr->tkwin, configSpecs, - argc, argv, (char *) squarePtr, flags) != TCL_OK) { - return TCL_ERROR; - } + int borderWidth; + Tk_3DBorder bgBorder; + int doubleBuffer; /* * Set the background for the window and create a graphics context * for use during redisplay. */ + bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin, + squarePtr->bgBorderPtr); Tk_SetWindowBackground(squarePtr->tkwin, - Tk_3DBorderColor(squarePtr->bgBorder)->pixel); - if ((squarePtr->gc == None) && (squarePtr->doubleBuffer)) { + Tk_3DBorderColor(bgBorder)->pixel); + Tcl_GetBooleanFromObj(NULL, squarePtr->doubleBufferPtr, &doubleBuffer); + if ((squarePtr->gc == None) && (doubleBuffer)) { XGCValues gcValues; gcValues.function = GXcopy; gcValues.graphics_exposures = False; @@ -345,18 +371,21 @@ SquareConfigure(interp, squarePtr, argc, argv, flags) */ Tk_GeometryRequest(squarePtr->tkwin, 200, 150); - Tk_SetInternalBorder(squarePtr->tkwin, squarePtr->borderWidth); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr, + &borderWidth); + Tk_SetInternalBorder(squarePtr->tkwin, borderWidth); if (!squarePtr->updatePending) { Tcl_DoWhenIdle(SquareDisplay, (ClientData) squarePtr); squarePtr->updatePending = 1; } + KeepInWindow(squarePtr); return TCL_OK; } /* *-------------------------------------------------------------- * - * SquareEventProc -- + * SquareObjEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on squares. @@ -372,7 +401,7 @@ SquareConfigure(interp, squarePtr, argc, argv, flags) */ static void -SquareEventProc(clientData, eventPtr) +SquareObjEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */ { @@ -391,6 +420,11 @@ SquareEventProc(clientData, eventPtr) } } else if (eventPtr->type == DestroyNotify) { if (squarePtr->tkwin != NULL) { + Tk_FreeConfigOptions((char *) squarePtr, squarePtr->optionTable, + squarePtr->tkwin); + if (squarePtr->gc != None) { + Tk_FreeGC(squarePtr->display, squarePtr->gc); + } squarePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(squarePtr->interp, squarePtr->widgetCmd); @@ -405,7 +439,7 @@ SquareEventProc(clientData, eventPtr) /* *---------------------------------------------------------------------- * - * SquareCmdDeletedProc -- + * SquareDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, @@ -421,7 +455,7 @@ SquareEventProc(clientData, eventPtr) */ static void -SquareCmdDeletedProc(clientData) +SquareDeletedProc(clientData) ClientData clientData; /* Pointer to widget record for widget. */ { Square *squarePtr = (Square *) clientData; @@ -435,7 +469,6 @@ SquareCmdDeletedProc(clientData) */ if (tkwin != NULL) { - squarePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); } } @@ -466,6 +499,9 @@ SquareDisplay(clientData) Tk_Window tkwin = squarePtr->tkwin; Pixmap pm = None; Drawable d; + int borderWidth, size, relief; + Tk_3DBorder bgBorder, fgBorder; + int doubleBuffer; squarePtr->updatePending = 0; if (!Tk_IsMapped(tkwin)) { @@ -476,7 +512,8 @@ SquareDisplay(clientData) * Create a pixmap for double-buffering, if necessary. */ - if (squarePtr->doubleBuffer) { + Tcl_GetBooleanFromObj(NULL, squarePtr->doubleBufferPtr, &doubleBuffer); + if (doubleBuffer) { pm = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), DefaultDepthOfScreen(Tk_Screen(tkwin))); @@ -489,22 +526,29 @@ SquareDisplay(clientData) * Redraw the widget's background and border. */ - Tk_Fill3DRectangle(tkwin, d, squarePtr->bgBorder, 0, 0, Tk_Width(tkwin), - Tk_Height(tkwin), squarePtr->borderWidth, squarePtr->relief); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr, + &borderWidth); + bgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin, + squarePtr->bgBorderPtr); + Tk_GetReliefFromObj(NULL, squarePtr->reliefPtr, &relief); + Tk_Fill3DRectangle(tkwin, d, bgBorder, 0, 0, Tk_Width(tkwin), + Tk_Height(tkwin), borderWidth, relief); /* * Display the square. */ - Tk_Fill3DRectangle(tkwin, d, squarePtr->fgBorder, squarePtr->x, - squarePtr->y, squarePtr->size, squarePtr->size, - squarePtr->borderWidth, TK_RELIEF_RAISED); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->sizeObjPtr, &size); + fgBorder = Tk_Get3DBorderFromObj(squarePtr->tkwin, + squarePtr->fgBorderPtr); + Tk_Fill3DRectangle(tkwin, d, fgBorder, squarePtr->x, squarePtr->y, size, + size, borderWidth, TK_RELIEF_RAISED); /* * If double-buffered, copy to the screen and release the pixmap. */ - if (squarePtr->doubleBuffer) { + if (doubleBuffer) { XCopyArea(Tk_Display(tkwin), pm, Tk_WindowId(tkwin), squarePtr->gc, 0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0); @@ -535,11 +579,7 @@ SquareDestroy(memPtr) char *memPtr; /* Info about square widget. */ { Square *squarePtr = (Square *) memPtr; - - Tk_FreeOptions(configSpecs, (char *) squarePtr, squarePtr->display, 0); - if (squarePtr->gc != None) { - Tk_FreeGC(squarePtr->display, squarePtr->gc); - } + ckfree((char *) squarePtr); } @@ -565,16 +605,26 @@ static void KeepInWindow(squarePtr) register Square *squarePtr; /* Pointer to widget record. */ { - int i, bd; + int i, bd, relief; + int borderWidth, size; + + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->borderWidthPtr, + &borderWidth); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->xPtr, + &squarePtr->x); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->yPtr, + &squarePtr->y); + Tk_GetPixelsFromObj(NULL, squarePtr->tkwin, squarePtr->sizeObjPtr, &size); + Tk_GetReliefFromObj(NULL, squarePtr->reliefPtr, &relief); bd = 0; - if (squarePtr->relief != TK_RELIEF_FLAT) { - bd = squarePtr->borderWidth; + if (relief != TK_RELIEF_FLAT) { + bd = borderWidth; } - i = (Tk_Width(squarePtr->tkwin) - bd) - (squarePtr->x + squarePtr->size); + i = (Tk_Width(squarePtr->tkwin) - bd) - (squarePtr->x + size); if (i < 0) { squarePtr->x += i; } - i = (Tk_Height(squarePtr->tkwin) - bd) - (squarePtr->y + squarePtr->size); + i = (Tk_Height(squarePtr->tkwin) - bd) - (squarePtr->y + size); if (i < 0) { squarePtr->y += i; } diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index b3a0ff2..4e685c5 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkStubInit.c,v 1.4 1999/03/12 03:17:48 stanton Exp $ + * RCS: @(#) $Id: tkStubInit.c,v 1.5 1999/04/16 01:51:22 stanton Exp $ */ #include "tkInt.h" @@ -226,10 +226,38 @@ TkStubs tkStubs = { Tk_UnmapWindow, /* 182 */ Tk_UnsetGrid, /* 183 */ Tk_UpdatePointer, /* 184 */ + Tk_AllocBitmapFromObj, /* 185 */ + Tk_Alloc3DBorderFromObj, /* 186 */ + Tk_AllocColorFromObj, /* 187 */ + Tk_AllocCursorFromObj, /* 188 */ + Tk_AllocFontFromObj, /* 189 */ + Tk_CreateOptionTable, /* 190 */ + Tk_DeleteOptionTable, /* 191 */ + Tk_Free3DBorderFromObj, /* 192 */ + Tk_FreeBitmapFromObj, /* 193 */ + Tk_FreeColorFromObj, /* 194 */ + Tk_FreeConfigOptions, /* 195 */ + Tk_FreeSavedOptions, /* 196 */ + Tk_FreeCursorFromObj, /* 197 */ + Tk_FreeFontFromObj, /* 198 */ + Tk_Get3DBorderFromObj, /* 199 */ + Tk_GetAnchorFromObj, /* 200 */ + Tk_GetBitmapFromObj, /* 201 */ + Tk_GetColorFromObj, /* 202 */ + Tk_GetCursorFromObj, /* 203 */ + Tk_GetOptionInfo, /* 204 */ + Tk_GetOptionValue, /* 205 */ + Tk_GetJustifyFromObj, /* 206 */ + Tk_GetMMFromObj, /* 207 */ + Tk_GetPixelsFromObj, /* 208 */ + Tk_GetReliefFromObj, /* 209 */ + Tk_GetScrollInfoObj, /* 210 */ + Tk_InitOptions, /* 211 */ + Tk_MainEx, /* 212 */ + Tk_RestoreSavedOptions, /* 213 */ + Tk_SetOptions, /* 214 */ }; -TkStubs *tkStubsPtr = &tkStubs; - TkIntStubs tkIntStubs = { TCL_STUB_MAGIC, NULL, @@ -262,7 +290,7 @@ TkIntStubs tkIntStubs = { TkFontPkgInit, /* 26 */ TkFontPkgFree, /* 27 */ TkFreeBindingTags, /* 28 */ - TkFreeCursor, /* 29 */ + TkpFreeCursor, /* 29 */ TkGetBitmapData, /* 30 */ TkGetButtPoints, /* 31 */ TkGetCursorByName, /* 32 */ @@ -331,10 +359,23 @@ TkIntStubs tkIntStubs = { TkWmRestackToplevel, /* 95 */ TkWmSetClass, /* 96 */ TkWmUnmapWindow, /* 97 */ + TkDebugBitmap, /* 98 */ + TkDebugBorder, /* 99 */ + TkDebugCursor, /* 100 */ + TkDebugColor, /* 101 */ + TkDebugConfig, /* 102 */ + TkDebugFont, /* 103 */ + TkFindStateNumObj, /* 104 */ + TkGetBitmapPredefTable, /* 105 */ + TkGetDisplayList, /* 106 */ + TkGetMainInfoList, /* 107 */ + TkGetWindowFromObj, /* 108 */ + TkpGetString, /* 109 */ + TkpGetSubFonts, /* 110 */ + TkpGetSystemDefault, /* 111 */ + TkpMenuThreadInit, /* 112 */ }; -TkIntStubs *tkIntStubsPtr = &tkIntStubs; - TkIntPlatStubs tkIntPlatStubs = { TCL_STUB_MAGIC, NULL, @@ -385,6 +426,10 @@ TkIntPlatStubs tkIntPlatStubs = { TkWinWmCleanup, /* 33 */ TkWinXCleanup, /* 34 */ TkWinXInit, /* 35 */ + TkWinSetForegroundWindow, /* 36 */ + TkWinDialogDebug, /* 37 */ + TkWinGetMenuSystemDefault, /* 38 */ + TkWinGetPlatformId, /* 39 */ #endif /* __WIN32__ */ #ifdef MAC_TCL TkClipBox, /* 0 */ @@ -462,8 +507,6 @@ TkIntPlatStubs tkIntPlatStubs = { #endif /* MAC_TCL */ }; -TkIntPlatStubs *tkIntPlatStubsPtr = &tkIntPlatStubs; - TkIntXlibStubs tkIntXlibStubs = { TCL_STUB_MAGIC, NULL, @@ -549,6 +592,29 @@ TkIntXlibStubs tkIntXlibStubs = { XFilterEvent, /* 78 */ XmbLookupString, /* 79 */ TkPutImage, /* 80 */ + NULL, /* 81 */ + XParseColor, /* 82 */ + XCreateGC, /* 83 */ + XFreeGC, /* 84 */ + XInternAtom, /* 85 */ + XSetBackground, /* 86 */ + XSetForeground, /* 87 */ + XSetClipMask, /* 88 */ + XSetClipOrigin, /* 89 */ + XSetTSOrigin, /* 90 */ + XChangeGC, /* 91 */ + XSetFont, /* 92 */ + XSetArcMode, /* 93 */ + XSetStipple, /* 94 */ + XSetFillRule, /* 95 */ + XSetFillStyle, /* 96 */ + XSetFunction, /* 97 */ + XSetLineAttributes, /* 98 */ + _XInitImageFuncPtrs, /* 99 */ + XCreateIC, /* 100 */ + XGetVisualInfo, /* 101 */ + XSetWMClientMachine, /* 102 */ + XStringListToTextProperty, /* 103 */ #endif /* __WIN32__ */ #ifdef MAC_TCL NULL, /* 0 */ @@ -609,11 +675,31 @@ TkIntXlibStubs tkIntXlibStubs = { XUngrabPointer, /* 55 */ XUnmapWindow, /* 56 */ TkPutImage, /* 57 */ + XParseColor, /* 58 */ + XCreateGC, /* 59 */ + XFreeGC, /* 60 */ + XInternAtom, /* 61 */ + XSetBackground, /* 62 */ + XSetForeground, /* 63 */ + XSetClipMask, /* 64 */ + XSetClipOrigin, /* 65 */ + XSetTSOrigin, /* 66 */ + XChangeGC, /* 67 */ + XSetFont, /* 68 */ + XSetArcMode, /* 69 */ + XSetStipple, /* 70 */ + XSetFillRule, /* 71 */ + XSetFillStyle, /* 72 */ + XSetFunction, /* 73 */ + XSetLineAttributes, /* 74 */ + _XInitImageFuncPtrs, /* 75 */ + XCreateIC, /* 76 */ + XGetVisualInfo, /* 77 */ + XSetWMClientMachine, /* 78 */ + XStringListToTextProperty, /* 79 */ #endif /* MAC_TCL */ }; -TkIntXlibStubs *tkIntXlibStubsPtr = &tkIntXlibStubs; - TkPlatStubs tkPlatStubs = { TCL_STUB_MAGIC, NULL, @@ -640,8 +726,6 @@ TkPlatStubs tkPlatStubs = { #endif /* MAC_TCL */ }; -TkPlatStubs *tkPlatStubsPtr = &tkPlatStubs; - static TkStubHooks tkStubHooks = { &tkPlatStubs, &tkIntStubs, diff --git a/generic/tkStubLib.c b/generic/tkStubLib.c index 85e5d99..438226f 100644 --- a/generic/tkStubLib.c +++ b/generic/tkStubLib.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkStubLib.c,v 1.2 1999/03/10 07:04:43 stanton Exp $ + * RCS: @(#) $Id: tkStubLib.c,v 1.3 1999/04/16 01:51:22 stanton Exp $ */ /* @@ -21,6 +21,11 @@ */ +#ifndef USE_TCL_STUBS +#define USE_TCL_STUBS +#endif +#undef USE_TCL_STUB_PROCS + #ifndef USE_TK_STUBS #define USE_TK_STUBS #endif diff --git a/generic/tkStubs.c b/generic/tkStubs.c deleted file mode 100644 index b69022e..0000000 --- a/generic/tkStubs.c +++ /dev/null @@ -1,1933 +0,0 @@ -/* - * tkStubs.c -- - * - * This file contains the wrapper functions for the platform independent - * public Tk API. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tkStubs.c,v 1.2 1999/03/10 07:04:43 stanton Exp $ - */ - -#include "tk.h" - -/* - * Undefine function macros that will interfere with the defintions below. - */ - - -/* - * WARNING: This file is automatically generated by the tools/genStubs.tcl - * script. Any modifications to the function declarations below should be made - * in the generic/tk.decls script. - */ - -/* !BEGIN!: Do not edit below this line. */ - -/* - * Exported stub functions: - */ - -/* Slot 0 */ -void -Tk_MainLoop() -{ - (tkStubsPtr->tk_MainLoop)(); -} - -/* Slot 1 */ -XColor * -Tk_3DBorderColor(border) - Tk_3DBorder border; -{ - return (tkStubsPtr->tk_3DBorderColor)(border); -} - -/* Slot 2 */ -GC -Tk_3DBorderGC(tkwin, border, which) - Tk_Window tkwin; - Tk_3DBorder border; - int which; -{ - return (tkStubsPtr->tk_3DBorderGC)(tkwin, border, which); -} - -/* Slot 3 */ -void -Tk_3DHorizontalBevel(tkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - int x; - int y; - int width; - int height; - int leftIn; - int rightIn; - int topBevel; - int relief; -{ - (tkStubsPtr->tk_3DHorizontalBevel)(tkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief); -} - -/* Slot 4 */ -void -Tk_3DVerticalBevel(tkwin, drawable, border, x, y, width, height, leftBevel, relief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - int x; - int y; - int width; - int height; - int leftBevel; - int relief; -{ - (tkStubsPtr->tk_3DVerticalBevel)(tkwin, drawable, border, x, y, width, height, leftBevel, relief); -} - -/* Slot 5 */ -void -Tk_AddOption(tkwin, name, value, priority) - Tk_Window tkwin; - char * name; - char * value; - int priority; -{ - (tkStubsPtr->tk_AddOption)(tkwin, name, value, priority); -} - -/* Slot 6 */ -void -Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) - Tk_BindingTable bindingTable; - XEvent * eventPtr; - Tk_Window tkwin; - int numObjects; - ClientData * objectPtr; -{ - (tkStubsPtr->tk_BindEvent)(bindingTable, eventPtr, tkwin, numObjects, objectPtr); -} - -/* Slot 7 */ -void -Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr) - Tk_Canvas canvas; - double x; - double y; - short * drawableXPtr; - short * drawableYPtr; -{ - (tkStubsPtr->tk_CanvasDrawableCoords)(canvas, x, y, drawableXPtr, drawableYPtr); -} - -/* Slot 8 */ -void -Tk_CanvasEventuallyRedraw(canvas, x1, y1, x2, y2) - Tk_Canvas canvas; - int x1; - int y1; - int x2; - int y2; -{ - (tkStubsPtr->tk_CanvasEventuallyRedraw)(canvas, x1, y1, x2, y2); -} - -/* Slot 9 */ -int -Tk_CanvasGetCoord(interp, canvas, string, doublePtr) - Tcl_Interp * interp; - Tk_Canvas canvas; - char * string; - double * doublePtr; -{ - return (tkStubsPtr->tk_CanvasGetCoord)(interp, canvas, string, doublePtr); -} - -/* Slot 10 */ -Tk_CanvasTextInfo * -Tk_CanvasGetTextInfo(canvas) - Tk_Canvas canvas; -{ - return (tkStubsPtr->tk_CanvasGetTextInfo)(canvas); -} - -/* Slot 11 */ -int -Tk_CanvasPsBitmap(interp, canvas, bitmap, x, y, width, height) - Tcl_Interp * interp; - Tk_Canvas canvas; - Pixmap bitmap; - int x; - int y; - int width; - int height; -{ - return (tkStubsPtr->tk_CanvasPsBitmap)(interp, canvas, bitmap, x, y, width, height); -} - -/* Slot 12 */ -int -Tk_CanvasPsColor(interp, canvas, colorPtr) - Tcl_Interp * interp; - Tk_Canvas canvas; - XColor * colorPtr; -{ - return (tkStubsPtr->tk_CanvasPsColor)(interp, canvas, colorPtr); -} - -/* Slot 13 */ -int -Tk_CanvasPsFont(interp, canvas, font) - Tcl_Interp * interp; - Tk_Canvas canvas; - Tk_Font font; -{ - return (tkStubsPtr->tk_CanvasPsFont)(interp, canvas, font); -} - -/* Slot 14 */ -void -Tk_CanvasPsPath(interp, canvas, coordPtr, numPoints) - Tcl_Interp * interp; - Tk_Canvas canvas; - double * coordPtr; - int numPoints; -{ - (tkStubsPtr->tk_CanvasPsPath)(interp, canvas, coordPtr, numPoints); -} - -/* Slot 15 */ -int -Tk_CanvasPsStipple(interp, canvas, bitmap) - Tcl_Interp * interp; - Tk_Canvas canvas; - Pixmap bitmap; -{ - return (tkStubsPtr->tk_CanvasPsStipple)(interp, canvas, bitmap); -} - -/* Slot 16 */ -double -Tk_CanvasPsY(canvas, y) - Tk_Canvas canvas; - double y; -{ - return (tkStubsPtr->tk_CanvasPsY)(canvas, y); -} - -/* Slot 17 */ -void -Tk_CanvasSetStippleOrigin(canvas, gc) - Tk_Canvas canvas; - GC gc; -{ - (tkStubsPtr->tk_CanvasSetStippleOrigin)(canvas, gc); -} - -/* Slot 18 */ -int -Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset) - ClientData clientData; - Tcl_Interp * interp; - Tk_Window tkwin; - char * value; - char * widgRec; - int offset; -{ - return (tkStubsPtr->tk_CanvasTagsParseProc)(clientData, interp, tkwin, value, widgRec, offset); -} - -/* Slot 19 */ -char * -Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) - ClientData clientData; - Tk_Window tkwin; - char * widgRec; - int offset; - Tcl_FreeProc ** freeProcPtr; -{ - return (tkStubsPtr->tk_CanvasTagsPrintProc)(clientData, tkwin, widgRec, offset, freeProcPtr); -} - -/* Slot 20 */ -Tk_Window -Tk_CanvasTkwin(canvas) - Tk_Canvas canvas; -{ - return (tkStubsPtr->tk_CanvasTkwin)(canvas); -} - -/* Slot 21 */ -void -Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr) - Tk_Canvas canvas; - double x; - double y; - short * screenXPtr; - short * screenYPtr; -{ - (tkStubsPtr->tk_CanvasWindowCoords)(canvas, x, y, screenXPtr, screenYPtr); -} - -/* Slot 22 */ -void -Tk_ChangeWindowAttributes(tkwin, valueMask, attsPtr) - Tk_Window tkwin; - unsigned long valueMask; - XSetWindowAttributes * attsPtr; -{ - (tkStubsPtr->tk_ChangeWindowAttributes)(tkwin, valueMask, attsPtr); -} - -/* Slot 23 */ -int -Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) - Tk_TextLayout layout; - int index; - int * xPtr; - int * yPtr; - int * widthPtr; - int * heightPtr; -{ - return (tkStubsPtr->tk_CharBbox)(layout, index, xPtr, yPtr, widthPtr, heightPtr); -} - -/* Slot 24 */ -void -Tk_ClearSelection(tkwin, selection) - Tk_Window tkwin; - Atom selection; -{ - (tkStubsPtr->tk_ClearSelection)(tkwin, selection); -} - -/* Slot 25 */ -int -Tk_ClipboardAppend(interp, tkwin, target, format, buffer) - Tcl_Interp * interp; - Tk_Window tkwin; - Atom target; - Atom format; - char* buffer; -{ - return (tkStubsPtr->tk_ClipboardAppend)(interp, tkwin, target, format, buffer); -} - -/* Slot 26 */ -int -Tk_ClipboardClear(interp, tkwin) - Tcl_Interp * interp; - Tk_Window tkwin; -{ - return (tkStubsPtr->tk_ClipboardClear)(interp, tkwin); -} - -/* Slot 27 */ -int -Tk_ConfigureInfo(interp, tkwin, specs, widgRec, argvName, flags) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_ConfigSpec * specs; - char * widgRec; - char * argvName; - int flags; -{ - return (tkStubsPtr->tk_ConfigureInfo)(interp, tkwin, specs, widgRec, argvName, flags); -} - -/* Slot 28 */ -int -Tk_ConfigureValue(interp, tkwin, specs, widgRec, argvName, flags) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_ConfigSpec * specs; - char * widgRec; - char * argvName; - int flags; -{ - return (tkStubsPtr->tk_ConfigureValue)(interp, tkwin, specs, widgRec, argvName, flags); -} - -/* Slot 29 */ -int -Tk_ConfigureWidget(interp, tkwin, specs, argc, argv, widgRec, flags) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_ConfigSpec * specs; - int argc; - char ** argv; - char * widgRec; - int flags; -{ - return (tkStubsPtr->tk_ConfigureWidget)(interp, tkwin, specs, argc, argv, widgRec, flags); -} - -/* Slot 30 */ -void -Tk_ConfigureWindow(tkwin, valueMask, valuePtr) - Tk_Window tkwin; - unsigned int valueMask; - XWindowChanges * valuePtr; -{ - (tkStubsPtr->tk_ConfigureWindow)(tkwin, valueMask, valuePtr); -} - -/* Slot 31 */ -Tk_TextLayout -Tk_ComputeTextLayout(font, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr) - Tk_Font font; - CONST char * string; - int numChars; - int wrapLength; - Tk_Justify justify; - int flags; - int * widthPtr; - int * heightPtr; -{ - return (tkStubsPtr->tk_ComputeTextLayout)(font, string, numChars, wrapLength, justify, flags, widthPtr, heightPtr); -} - -/* Slot 32 */ -Tk_Window -Tk_CoordsToWindow(rootX, rootY, tkwin) - int rootX; - int rootY; - Tk_Window tkwin; -{ - return (tkStubsPtr->tk_CoordsToWindow)(rootX, rootY, tkwin); -} - -/* Slot 33 */ -unsigned long -Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; - ClientData object; - char * eventString; - char * command; - int append; -{ - return (tkStubsPtr->tk_CreateBinding)(interp, bindingTable, object, eventString, command, append); -} - -/* Slot 34 */ -Tk_BindingTable -Tk_CreateBindingTable(interp) - Tcl_Interp * interp; -{ - return (tkStubsPtr->tk_CreateBindingTable)(interp); -} - -/* Slot 35 */ -Tk_ErrorHandler -Tk_CreateErrorHandler(display, errNum, request, minorCode, errorProc, clientData) - Display * display; - int errNum; - int request; - int minorCode; - Tk_ErrorProc * errorProc; - ClientData clientData; -{ - return (tkStubsPtr->tk_CreateErrorHandler)(display, errNum, request, minorCode, errorProc, clientData); -} - -/* Slot 36 */ -void -Tk_CreateEventHandler(token, mask, proc, clientData) - Tk_Window token; - unsigned long mask; - Tk_EventProc * proc; - ClientData clientData; -{ - (tkStubsPtr->tk_CreateEventHandler)(token, mask, proc, clientData); -} - -/* Slot 37 */ -void -Tk_CreateGenericHandler(proc, clientData) - Tk_GenericProc * proc; - ClientData clientData; -{ - (tkStubsPtr->tk_CreateGenericHandler)(proc, clientData); -} - -/* Slot 38 */ -void -Tk_CreateImageType(typePtr) - Tk_ImageType * typePtr; -{ - (tkStubsPtr->tk_CreateImageType)(typePtr); -} - -/* Slot 39 */ -void -Tk_CreateItemType(typePtr) - Tk_ItemType * typePtr; -{ - (tkStubsPtr->tk_CreateItemType)(typePtr); -} - -/* Slot 40 */ -void -Tk_CreatePhotoImageFormat(formatPtr) - Tk_PhotoImageFormat * formatPtr; -{ - (tkStubsPtr->tk_CreatePhotoImageFormat)(formatPtr); -} - -/* Slot 41 */ -void -Tk_CreateSelHandler(tkwin, selection, target, proc, clientData, format) - Tk_Window tkwin; - Atom selection; - Atom target; - Tk_SelectionProc * proc; - ClientData clientData; - Atom format; -{ - (tkStubsPtr->tk_CreateSelHandler)(tkwin, selection, target, proc, clientData, format); -} - -/* Slot 42 */ -Tk_Window -Tk_CreateWindow(interp, parent, name, screenName) - Tcl_Interp * interp; - Tk_Window parent; - char * name; - char * screenName; -{ - return (tkStubsPtr->tk_CreateWindow)(interp, parent, name, screenName); -} - -/* Slot 43 */ -Tk_Window -Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName) - Tcl_Interp * interp; - Tk_Window tkwin; - char * pathName; - char * screenName; -{ - return (tkStubsPtr->tk_CreateWindowFromPath)(interp, tkwin, pathName, screenName); -} - -/* Slot 44 */ -int -Tk_DefineBitmap(interp, name, source, width, height) - Tcl_Interp * interp; - Tk_Uid name; - char * source; - int width; - int height; -{ - return (tkStubsPtr->tk_DefineBitmap)(interp, name, source, width, height); -} - -/* Slot 45 */ -void -Tk_DefineCursor(window, cursor) - Tk_Window window; - Tk_Cursor cursor; -{ - (tkStubsPtr->tk_DefineCursor)(window, cursor); -} - -/* Slot 46 */ -void -Tk_DeleteAllBindings(bindingTable, object) - Tk_BindingTable bindingTable; - ClientData object; -{ - (tkStubsPtr->tk_DeleteAllBindings)(bindingTable, object); -} - -/* Slot 47 */ -int -Tk_DeleteBinding(interp, bindingTable, object, eventString) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; - ClientData object; - char * eventString; -{ - return (tkStubsPtr->tk_DeleteBinding)(interp, bindingTable, object, eventString); -} - -/* Slot 48 */ -void -Tk_DeleteBindingTable(bindingTable) - Tk_BindingTable bindingTable; -{ - (tkStubsPtr->tk_DeleteBindingTable)(bindingTable); -} - -/* Slot 49 */ -void -Tk_DeleteErrorHandler(handler) - Tk_ErrorHandler handler; -{ - (tkStubsPtr->tk_DeleteErrorHandler)(handler); -} - -/* Slot 50 */ -void -Tk_DeleteEventHandler(token, mask, proc, clientData) - Tk_Window token; - unsigned long mask; - Tk_EventProc * proc; - ClientData clientData; -{ - (tkStubsPtr->tk_DeleteEventHandler)(token, mask, proc, clientData); -} - -/* Slot 51 */ -void -Tk_DeleteGenericHandler(proc, clientData) - Tk_GenericProc * proc; - ClientData clientData; -{ - (tkStubsPtr->tk_DeleteGenericHandler)(proc, clientData); -} - -/* Slot 52 */ -void -Tk_DeleteImage(interp, name) - Tcl_Interp * interp; - char * name; -{ - (tkStubsPtr->tk_DeleteImage)(interp, name); -} - -/* Slot 53 */ -void -Tk_DeleteSelHandler(tkwin, selection, target) - Tk_Window tkwin; - Atom selection; - Atom target; -{ - (tkStubsPtr->tk_DeleteSelHandler)(tkwin, selection, target); -} - -/* Slot 54 */ -void -Tk_DestroyWindow(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_DestroyWindow)(tkwin); -} - -/* Slot 55 */ -char * -Tk_DisplayName(tkwin) - Tk_Window tkwin; -{ - return (tkStubsPtr->tk_DisplayName)(tkwin); -} - -/* Slot 56 */ -int -Tk_DistanceToTextLayout(layout, x, y) - Tk_TextLayout layout; - int x; - int y; -{ - return (tkStubsPtr->tk_DistanceToTextLayout)(layout, x, y); -} - -/* Slot 57 */ -void -Tk_Draw3DPolygon(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - XPoint * pointPtr; - int numPoints; - int borderWidth; - int leftRelief; -{ - (tkStubsPtr->tk_Draw3DPolygon)(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief); -} - -/* Slot 58 */ -void -Tk_Draw3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - int x; - int y; - int width; - int height; - int borderWidth; - int relief; -{ - (tkStubsPtr->tk_Draw3DRectangle)(tkwin, drawable, border, x, y, width, height, borderWidth, relief); -} - -/* Slot 59 */ -void -Tk_DrawChars(display, drawable, gc, tkfont, source, numChars, x, y) - Display * display; - Drawable drawable; - GC gc; - Tk_Font tkfont; - CONST char * source; - int numChars; - int x; - int y; -{ - (tkStubsPtr->tk_DrawChars)(display, drawable, gc, tkfont, source, numChars, x, y); -} - -/* Slot 60 */ -void -Tk_DrawFocusHighlight(tkwin, gc, width, drawable) - Tk_Window tkwin; - GC gc; - int width; - Drawable drawable; -{ - (tkStubsPtr->tk_DrawFocusHighlight)(tkwin, gc, width, drawable); -} - -/* Slot 61 */ -void -Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) - Display * display; - Drawable drawable; - GC gc; - Tk_TextLayout layout; - int x; - int y; - int firstChar; - int lastChar; -{ - (tkStubsPtr->tk_DrawTextLayout)(display, drawable, gc, layout, x, y, firstChar, lastChar); -} - -/* Slot 62 */ -void -Tk_Fill3DPolygon(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - XPoint * pointPtr; - int numPoints; - int borderWidth; - int leftRelief; -{ - (tkStubsPtr->tk_Fill3DPolygon)(tkwin, drawable, border, pointPtr, numPoints, borderWidth, leftRelief); -} - -/* Slot 63 */ -void -Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width, height, borderWidth, relief) - Tk_Window tkwin; - Drawable drawable; - Tk_3DBorder border; - int x; - int y; - int width; - int height; - int borderWidth; - int relief; -{ - (tkStubsPtr->tk_Fill3DRectangle)(tkwin, drawable, border, x, y, width, height, borderWidth, relief); -} - -/* Slot 64 */ -Tk_PhotoHandle -Tk_FindPhoto(interp, imageName) - Tcl_Interp * interp; - char * imageName; -{ - return (tkStubsPtr->tk_FindPhoto)(interp, imageName); -} - -/* Slot 65 */ -Font -Tk_FontId(font) - Tk_Font font; -{ - return (tkStubsPtr->tk_FontId)(font); -} - -/* Slot 66 */ -void -Tk_Free3DBorder(border) - Tk_3DBorder border; -{ - (tkStubsPtr->tk_Free3DBorder)(border); -} - -/* Slot 67 */ -void -Tk_FreeBitmap(display, bitmap) - Display * display; - Pixmap bitmap; -{ - (tkStubsPtr->tk_FreeBitmap)(display, bitmap); -} - -/* Slot 68 */ -void -Tk_FreeColor(colorPtr) - XColor * colorPtr; -{ - (tkStubsPtr->tk_FreeColor)(colorPtr); -} - -/* Slot 69 */ -void -Tk_FreeColormap(display, colormap) - Display * display; - Colormap colormap; -{ - (tkStubsPtr->tk_FreeColormap)(display, colormap); -} - -/* Slot 70 */ -void -Tk_FreeCursor(display, cursor) - Display * display; - Tk_Cursor cursor; -{ - (tkStubsPtr->tk_FreeCursor)(display, cursor); -} - -/* Slot 71 */ -void -Tk_FreeFont(f) - Tk_Font f; -{ - (tkStubsPtr->tk_FreeFont)(f); -} - -/* Slot 72 */ -void -Tk_FreeGC(display, gc) - Display * display; - GC gc; -{ - (tkStubsPtr->tk_FreeGC)(display, gc); -} - -/* Slot 73 */ -void -Tk_FreeImage(image) - Tk_Image image; -{ - (tkStubsPtr->tk_FreeImage)(image); -} - -/* Slot 74 */ -void -Tk_FreeOptions(specs, widgRec, display, needFlags) - Tk_ConfigSpec * specs; - char * widgRec; - Display * display; - int needFlags; -{ - (tkStubsPtr->tk_FreeOptions)(specs, widgRec, display, needFlags); -} - -/* Slot 75 */ -void -Tk_FreePixmap(display, pixmap) - Display * display; - Pixmap pixmap; -{ - (tkStubsPtr->tk_FreePixmap)(display, pixmap); -} - -/* Slot 76 */ -void -Tk_FreeTextLayout(textLayout) - Tk_TextLayout textLayout; -{ - (tkStubsPtr->tk_FreeTextLayout)(textLayout); -} - -/* Slot 77 */ -void -Tk_FreeXId(display, xid) - Display * display; - XID xid; -{ - (tkStubsPtr->tk_FreeXId)(display, xid); -} - -/* Slot 78 */ -GC -Tk_GCForColor(colorPtr, drawable) - XColor * colorPtr; - Drawable drawable; -{ - return (tkStubsPtr->tk_GCForColor)(colorPtr, drawable); -} - -/* Slot 79 */ -void -Tk_GeometryRequest(tkwin, reqWidth, reqHeight) - Tk_Window tkwin; - int reqWidth; - int reqHeight; -{ - (tkStubsPtr->tk_GeometryRequest)(tkwin, reqWidth, reqHeight); -} - -/* Slot 80 */ -Tk_3DBorder -Tk_Get3DBorder(interp, tkwin, colorName) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_Uid colorName; -{ - return (tkStubsPtr->tk_Get3DBorder)(interp, tkwin, colorName); -} - -/* Slot 81 */ -void -Tk_GetAllBindings(interp, bindingTable, object) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; - ClientData object; -{ - (tkStubsPtr->tk_GetAllBindings)(interp, bindingTable, object); -} - -/* Slot 82 */ -int -Tk_GetAnchor(interp, string, anchorPtr) - Tcl_Interp * interp; - char * string; - Tk_Anchor * anchorPtr; -{ - return (tkStubsPtr->tk_GetAnchor)(interp, string, anchorPtr); -} - -/* Slot 83 */ -char * -Tk_GetAtomName(tkwin, atom) - Tk_Window tkwin; - Atom atom; -{ - return (tkStubsPtr->tk_GetAtomName)(tkwin, atom); -} - -/* Slot 84 */ -char * -Tk_GetBinding(interp, bindingTable, object, eventString) - Tcl_Interp * interp; - Tk_BindingTable bindingTable; - ClientData object; - char * eventString; -{ - return (tkStubsPtr->tk_GetBinding)(interp, bindingTable, object, eventString); -} - -/* Slot 85 */ -Pixmap -Tk_GetBitmap(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_Uid string; -{ - return (tkStubsPtr->tk_GetBitmap)(interp, tkwin, string); -} - -/* Slot 86 */ -Pixmap -Tk_GetBitmapFromData(interp, tkwin, source, width, height) - Tcl_Interp * interp; - Tk_Window tkwin; - char * source; - int width; - int height; -{ - return (tkStubsPtr->tk_GetBitmapFromData)(interp, tkwin, source, width, height); -} - -/* Slot 87 */ -int -Tk_GetCapStyle(interp, string, capPtr) - Tcl_Interp * interp; - char * string; - int * capPtr; -{ - return (tkStubsPtr->tk_GetCapStyle)(interp, string, capPtr); -} - -/* Slot 88 */ -XColor * -Tk_GetColor(interp, tkwin, name) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_Uid name; -{ - return (tkStubsPtr->tk_GetColor)(interp, tkwin, name); -} - -/* Slot 89 */ -XColor * -Tk_GetColorByValue(tkwin, colorPtr) - Tk_Window tkwin; - XColor * colorPtr; -{ - return (tkStubsPtr->tk_GetColorByValue)(tkwin, colorPtr); -} - -/* Slot 90 */ -Colormap -Tk_GetColormap(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - char * string; -{ - return (tkStubsPtr->tk_GetColormap)(interp, tkwin, string); -} - -/* Slot 91 */ -Tk_Cursor -Tk_GetCursor(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - Tk_Uid string; -{ - return (tkStubsPtr->tk_GetCursor)(interp, tkwin, string); -} - -/* Slot 92 */ -Tk_Cursor -Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, xHot, yHot, fg, bg) - Tcl_Interp * interp; - Tk_Window tkwin; - char * source; - char * mask; - int width; - int height; - int xHot; - int yHot; - Tk_Uid fg; - Tk_Uid bg; -{ - return (tkStubsPtr->tk_GetCursorFromData)(interp, tkwin, source, mask, width, height, xHot, yHot, fg, bg); -} - -/* Slot 93 */ -Tk_Font -Tk_GetFont(interp, tkwin, string) - Tcl_Interp * interp; - Tk_Window tkwin; - CONST char * string; -{ - return (tkStubsPtr->tk_GetFont)(interp, tkwin, string); -} - -/* Slot 94 */ -Tk_Font -Tk_GetFontFromObj(interp, tkwin, objPtr) - Tcl_Interp * interp; - Tk_Window tkwin; - Tcl_Obj * objPtr; -{ - return (tkStubsPtr->tk_GetFontFromObj)(interp, tkwin, objPtr); -} - -/* Slot 95 */ -void -Tk_GetFontMetrics(font, fmPtr) - Tk_Font font; - Tk_FontMetrics * fmPtr; -{ - (tkStubsPtr->tk_GetFontMetrics)(font, fmPtr); -} - -/* Slot 96 */ -GC -Tk_GetGC(tkwin, valueMask, valuePtr) - Tk_Window tkwin; - unsigned long valueMask; - XGCValues * valuePtr; -{ - return (tkStubsPtr->tk_GetGC)(tkwin, valueMask, valuePtr); -} - -/* Slot 97 */ -Tk_Image -Tk_GetImage(interp, tkwin, name, changeProc, clientData) - Tcl_Interp * interp; - Tk_Window tkwin; - char * name; - Tk_ImageChangedProc * changeProc; - ClientData clientData; -{ - return (tkStubsPtr->tk_GetImage)(interp, tkwin, name, changeProc, clientData); -} - -/* Slot 98 */ -ClientData -Tk_GetImageMasterData(interp, name, typePtrPtr) - Tcl_Interp * interp; - char * name; - Tk_ImageType ** typePtrPtr; -{ - return (tkStubsPtr->tk_GetImageMasterData)(interp, name, typePtrPtr); -} - -/* Slot 99 */ -Tk_ItemType * -Tk_GetItemTypes() -{ - return (tkStubsPtr->tk_GetItemTypes)(); -} - -/* Slot 100 */ -int -Tk_GetJoinStyle(interp, string, joinPtr) - Tcl_Interp * interp; - char * string; - int * joinPtr; -{ - return (tkStubsPtr->tk_GetJoinStyle)(interp, string, joinPtr); -} - -/* Slot 101 */ -int -Tk_GetJustify(interp, string, justifyPtr) - Tcl_Interp * interp; - char * string; - Tk_Justify * justifyPtr; -{ - return (tkStubsPtr->tk_GetJustify)(interp, string, justifyPtr); -} - -/* Slot 102 */ -int -Tk_GetNumMainWindows() -{ - return (tkStubsPtr->tk_GetNumMainWindows)(); -} - -/* Slot 103 */ -Tk_Uid -Tk_GetOption(tkwin, name, className) - Tk_Window tkwin; - char * name; - char * className; -{ - return (tkStubsPtr->tk_GetOption)(tkwin, name, className); -} - -/* Slot 104 */ -int -Tk_GetPixels(interp, tkwin, string, intPtr) - Tcl_Interp * interp; - Tk_Window tkwin; - char * string; - int * intPtr; -{ - return (tkStubsPtr->tk_GetPixels)(interp, tkwin, string, intPtr); -} - -/* Slot 105 */ -Pixmap -Tk_GetPixmap(display, d, width, height, depth) - Display * display; - Drawable d; - int width; - int height; - int depth; -{ - return (tkStubsPtr->tk_GetPixmap)(display, d, width, height, depth); -} - -/* Slot 106 */ -int -Tk_GetRelief(interp, name, reliefPtr) - Tcl_Interp * interp; - char * name; - int * reliefPtr; -{ - return (tkStubsPtr->tk_GetRelief)(interp, name, reliefPtr); -} - -/* Slot 107 */ -void -Tk_GetRootCoords(tkwin, xPtr, yPtr) - Tk_Window tkwin; - int * xPtr; - int * yPtr; -{ - (tkStubsPtr->tk_GetRootCoords)(tkwin, xPtr, yPtr); -} - -/* Slot 108 */ -int -Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr) - Tcl_Interp * interp; - int argc; - char ** argv; - double * dblPtr; - int * intPtr; -{ - return (tkStubsPtr->tk_GetScrollInfo)(interp, argc, argv, dblPtr, intPtr); -} - -/* Slot 109 */ -int -Tk_GetScreenMM(interp, tkwin, string, doublePtr) - Tcl_Interp * interp; - Tk_Window tkwin; - char * string; - double * doublePtr; -{ - return (tkStubsPtr->tk_GetScreenMM)(interp, tkwin, string, doublePtr); -} - -/* Slot 110 */ -int -Tk_GetSelection(interp, tkwin, selection, target, proc, clientData) - Tcl_Interp * interp; - Tk_Window tkwin; - Atom selection; - Atom target; - Tk_GetSelProc * proc; - ClientData clientData; -{ - return (tkStubsPtr->tk_GetSelection)(interp, tkwin, selection, target, proc, clientData); -} - -/* Slot 111 */ -Tk_Uid -Tk_GetUid(string) - CONST char * string; -{ - return (tkStubsPtr->tk_GetUid)(string); -} - -/* Slot 112 */ -Visual * -Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr) - Tcl_Interp * interp; - Tk_Window tkwin; - char * string; - int * depthPtr; - Colormap * colormapPtr; -{ - return (tkStubsPtr->tk_GetVisual)(interp, tkwin, string, depthPtr, colormapPtr); -} - -/* Slot 113 */ -void -Tk_GetVRootGeometry(tkwin, xPtr, yPtr, widthPtr, heightPtr) - Tk_Window tkwin; - int * xPtr; - int * yPtr; - int * widthPtr; - int * heightPtr; -{ - (tkStubsPtr->tk_GetVRootGeometry)(tkwin, xPtr, yPtr, widthPtr, heightPtr); -} - -/* Slot 114 */ -int -Tk_Grab(interp, tkwin, grabGlobal) - Tcl_Interp * interp; - Tk_Window tkwin; - int grabGlobal; -{ - return (tkStubsPtr->tk_Grab)(interp, tkwin, grabGlobal); -} - -/* Slot 115 */ -void -Tk_HandleEvent(eventPtr) - XEvent * eventPtr; -{ - (tkStubsPtr->tk_HandleEvent)(eventPtr); -} - -/* Slot 116 */ -Tk_Window -Tk_IdToWindow(display, window) - Display * display; - Window window; -{ - return (tkStubsPtr->tk_IdToWindow)(display, window); -} - -/* Slot 117 */ -void -Tk_ImageChanged(master, x, y, width, height, imageWidth, imageHeight) - Tk_ImageMaster master; - int x; - int y; - int width; - int height; - int imageWidth; - int imageHeight; -{ - (tkStubsPtr->tk_ImageChanged)(master, x, y, width, height, imageWidth, imageHeight); -} - -/* Slot 118 */ -int -Tk_Init(interp) - Tcl_Interp * interp; -{ - return (tkStubsPtr->tk_Init)(interp); -} - -/* Slot 119 */ -Atom -Tk_InternAtom(tkwin, name) - Tk_Window tkwin; - char * name; -{ - return (tkStubsPtr->tk_InternAtom)(tkwin, name); -} - -/* Slot 120 */ -int -Tk_IntersectTextLayout(layout, x, y, width, height) - Tk_TextLayout layout; - int x; - int y; - int width; - int height; -{ - return (tkStubsPtr->tk_IntersectTextLayout)(layout, x, y, width, height); -} - -/* Slot 121 */ -void -Tk_MaintainGeometry(slave, master, x, y, width, height) - Tk_Window slave; - Tk_Window master; - int x; - int y; - int width; - int height; -{ - (tkStubsPtr->tk_MaintainGeometry)(slave, master, x, y, width, height); -} - -/* Slot 122 */ -Tk_Window -Tk_MainWindow(interp) - Tcl_Interp * interp; -{ - return (tkStubsPtr->tk_MainWindow)(interp); -} - -/* Slot 123 */ -void -Tk_MakeWindowExist(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_MakeWindowExist)(tkwin); -} - -/* Slot 124 */ -void -Tk_ManageGeometry(tkwin, mgrPtr, clientData) - Tk_Window tkwin; - Tk_GeomMgr * mgrPtr; - ClientData clientData; -{ - (tkStubsPtr->tk_ManageGeometry)(tkwin, mgrPtr, clientData); -} - -/* Slot 125 */ -void -Tk_MapWindow(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_MapWindow)(tkwin); -} - -/* Slot 126 */ -int -Tk_MeasureChars(tkfont, source, maxChars, maxPixels, flags, lengthPtr) - Tk_Font tkfont; - CONST char * source; - int maxChars; - int maxPixels; - int flags; - int * lengthPtr; -{ - return (tkStubsPtr->tk_MeasureChars)(tkfont, source, maxChars, maxPixels, flags, lengthPtr); -} - -/* Slot 127 */ -void -Tk_MoveResizeWindow(tkwin, x, y, width, height) - Tk_Window tkwin; - int x; - int y; - int width; - int height; -{ - (tkStubsPtr->tk_MoveResizeWindow)(tkwin, x, y, width, height); -} - -/* Slot 128 */ -void -Tk_MoveWindow(tkwin, x, y) - Tk_Window tkwin; - int x; - int y; -{ - (tkStubsPtr->tk_MoveWindow)(tkwin, x, y); -} - -/* Slot 129 */ -void -Tk_MoveToplevelWindow(tkwin, x, y) - Tk_Window tkwin; - int x; - int y; -{ - (tkStubsPtr->tk_MoveToplevelWindow)(tkwin, x, y); -} - -/* Slot 130 */ -char * -Tk_NameOf3DBorder(border) - Tk_3DBorder border; -{ - return (tkStubsPtr->tk_NameOf3DBorder)(border); -} - -/* Slot 131 */ -char * -Tk_NameOfAnchor(anchor) - Tk_Anchor anchor; -{ - return (tkStubsPtr->tk_NameOfAnchor)(anchor); -} - -/* Slot 132 */ -char * -Tk_NameOfBitmap(display, bitmap) - Display * display; - Pixmap bitmap; -{ - return (tkStubsPtr->tk_NameOfBitmap)(display, bitmap); -} - -/* Slot 133 */ -char * -Tk_NameOfCapStyle(cap) - int cap; -{ - return (tkStubsPtr->tk_NameOfCapStyle)(cap); -} - -/* Slot 134 */ -char * -Tk_NameOfColor(colorPtr) - XColor * colorPtr; -{ - return (tkStubsPtr->tk_NameOfColor)(colorPtr); -} - -/* Slot 135 */ -char * -Tk_NameOfCursor(display, cursor) - Display * display; - Tk_Cursor cursor; -{ - return (tkStubsPtr->tk_NameOfCursor)(display, cursor); -} - -/* Slot 136 */ -char * -Tk_NameOfFont(font) - Tk_Font font; -{ - return (tkStubsPtr->tk_NameOfFont)(font); -} - -/* Slot 137 */ -char * -Tk_NameOfImage(imageMaster) - Tk_ImageMaster imageMaster; -{ - return (tkStubsPtr->tk_NameOfImage)(imageMaster); -} - -/* Slot 138 */ -char * -Tk_NameOfJoinStyle(join) - int join; -{ - return (tkStubsPtr->tk_NameOfJoinStyle)(join); -} - -/* Slot 139 */ -char * -Tk_NameOfJustify(justify) - Tk_Justify justify; -{ - return (tkStubsPtr->tk_NameOfJustify)(justify); -} - -/* Slot 140 */ -char * -Tk_NameOfRelief(relief) - int relief; -{ - return (tkStubsPtr->tk_NameOfRelief)(relief); -} - -/* Slot 141 */ -Tk_Window -Tk_NameToWindow(interp, pathName, tkwin) - Tcl_Interp * interp; - char * pathName; - Tk_Window tkwin; -{ - return (tkStubsPtr->tk_NameToWindow)(interp, pathName, tkwin); -} - -/* Slot 142 */ -void -Tk_OwnSelection(tkwin, selection, proc, clientData) - Tk_Window tkwin; - Atom selection; - Tk_LostSelProc * proc; - ClientData clientData; -{ - (tkStubsPtr->tk_OwnSelection)(tkwin, selection, proc, clientData); -} - -/* Slot 143 */ -int -Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) - Tcl_Interp * interp; - Tk_Window tkwin; - int * argcPtr; - char ** argv; - Tk_ArgvInfo * argTable; - int flags; -{ - return (tkStubsPtr->tk_ParseArgv)(interp, tkwin, argcPtr, argv, argTable, flags); -} - -/* Slot 144 */ -void -Tk_PhotoPutBlock(handle, blockPtr, x, y, width, height) - Tk_PhotoHandle handle; - Tk_PhotoImageBlock * blockPtr; - int x; - int y; - int width; - int height; -{ - (tkStubsPtr->tk_PhotoPutBlock)(handle, blockPtr, x, y, width, height); -} - -/* Slot 145 */ -void -Tk_PhotoPutZoomedBlock(handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY) - Tk_PhotoHandle handle; - Tk_PhotoImageBlock * blockPtr; - int x; - int y; - int width; - int height; - int zoomX; - int zoomY; - int subsampleX; - int subsampleY; -{ - (tkStubsPtr->tk_PhotoPutZoomedBlock)(handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY); -} - -/* Slot 146 */ -int -Tk_PhotoGetImage(handle, blockPtr) - Tk_PhotoHandle handle; - Tk_PhotoImageBlock * blockPtr; -{ - return (tkStubsPtr->tk_PhotoGetImage)(handle, blockPtr); -} - -/* Slot 147 */ -void -Tk_PhotoBlank(handle) - Tk_PhotoHandle handle; -{ - (tkStubsPtr->tk_PhotoBlank)(handle); -} - -/* Slot 148 */ -void -Tk_PhotoExpand(handle, width, height) - Tk_PhotoHandle handle; - int width; - int height; -{ - (tkStubsPtr->tk_PhotoExpand)(handle, width, height); -} - -/* Slot 149 */ -void -Tk_PhotoGetSize(handle, widthPtr, heightPtr) - Tk_PhotoHandle handle; - int * widthPtr; - int * heightPtr; -{ - (tkStubsPtr->tk_PhotoGetSize)(handle, widthPtr, heightPtr); -} - -/* Slot 150 */ -void -Tk_PhotoSetSize(handle, width, height) - Tk_PhotoHandle handle; - int width; - int height; -{ - (tkStubsPtr->tk_PhotoSetSize)(handle, width, height); -} - -/* Slot 151 */ -int -Tk_PointToChar(layout, x, y) - Tk_TextLayout layout; - int x; - int y; -{ - return (tkStubsPtr->tk_PointToChar)(layout, x, y); -} - -/* Slot 152 */ -int -Tk_PostscriptFontName(tkfont, dsPtr) - Tk_Font tkfont; - Tcl_DString * dsPtr; -{ - return (tkStubsPtr->tk_PostscriptFontName)(tkfont, dsPtr); -} - -/* Slot 153 */ -void -Tk_PreserveColormap(display, colormap) - Display * display; - Colormap colormap; -{ - (tkStubsPtr->tk_PreserveColormap)(display, colormap); -} - -/* Slot 154 */ -void -Tk_QueueWindowEvent(eventPtr, position) - XEvent * eventPtr; - Tcl_QueuePosition position; -{ - (tkStubsPtr->tk_QueueWindowEvent)(eventPtr, position); -} - -/* Slot 155 */ -void -Tk_RedrawImage(image, imageX, imageY, width, height, drawable, drawableX, drawableY) - Tk_Image image; - int imageX; - int imageY; - int width; - int height; - Drawable drawable; - int drawableX; - int drawableY; -{ - (tkStubsPtr->tk_RedrawImage)(image, imageX, imageY, width, height, drawable, drawableX, drawableY); -} - -/* Slot 156 */ -void -Tk_ResizeWindow(tkwin, width, height) - Tk_Window tkwin; - int width; - int height; -{ - (tkStubsPtr->tk_ResizeWindow)(tkwin, width, height); -} - -/* Slot 157 */ -int -Tk_RestackWindow(tkwin, aboveBelow, other) - Tk_Window tkwin; - int aboveBelow; - Tk_Window other; -{ - return (tkStubsPtr->tk_RestackWindow)(tkwin, aboveBelow, other); -} - -/* Slot 158 */ -Tk_RestrictProc * -Tk_RestrictEvents(proc, arg, prevArgPtr) - Tk_RestrictProc * proc; - ClientData arg; - ClientData * prevArgPtr; -{ - return (tkStubsPtr->tk_RestrictEvents)(proc, arg, prevArgPtr); -} - -/* Slot 159 */ -int -Tk_SafeInit(interp) - Tcl_Interp * interp; -{ - return (tkStubsPtr->tk_SafeInit)(interp); -} - -/* Slot 160 */ -char * -Tk_SetAppName(tkwin, name) - Tk_Window tkwin; - char * name; -{ - return (tkStubsPtr->tk_SetAppName)(tkwin, name); -} - -/* Slot 161 */ -void -Tk_SetBackgroundFromBorder(tkwin, border) - Tk_Window tkwin; - Tk_3DBorder border; -{ - (tkStubsPtr->tk_SetBackgroundFromBorder)(tkwin, border); -} - -/* Slot 162 */ -void -Tk_SetClass(tkwin, className) - Tk_Window tkwin; - char * className; -{ - (tkStubsPtr->tk_SetClass)(tkwin, className); -} - -/* Slot 163 */ -void -Tk_SetGrid(tkwin, reqWidth, reqHeight, gridWidth, gridHeight) - Tk_Window tkwin; - int reqWidth; - int reqHeight; - int gridWidth; - int gridHeight; -{ - (tkStubsPtr->tk_SetGrid)(tkwin, reqWidth, reqHeight, gridWidth, gridHeight); -} - -/* Slot 164 */ -void -Tk_SetInternalBorder(tkwin, width) - Tk_Window tkwin; - int width; -{ - (tkStubsPtr->tk_SetInternalBorder)(tkwin, width); -} - -/* Slot 165 */ -void -Tk_SetWindowBackground(tkwin, pixel) - Tk_Window tkwin; - unsigned long pixel; -{ - (tkStubsPtr->tk_SetWindowBackground)(tkwin, pixel); -} - -/* Slot 166 */ -void -Tk_SetWindowBackgroundPixmap(tkwin, pixmap) - Tk_Window tkwin; - Pixmap pixmap; -{ - (tkStubsPtr->tk_SetWindowBackgroundPixmap)(tkwin, pixmap); -} - -/* Slot 167 */ -void -Tk_SetWindowBorder(tkwin, pixel) - Tk_Window tkwin; - unsigned long pixel; -{ - (tkStubsPtr->tk_SetWindowBorder)(tkwin, pixel); -} - -/* Slot 168 */ -void -Tk_SetWindowBorderWidth(tkwin, width) - Tk_Window tkwin; - int width; -{ - (tkStubsPtr->tk_SetWindowBorderWidth)(tkwin, width); -} - -/* Slot 169 */ -void -Tk_SetWindowBorderPixmap(tkwin, pixmap) - Tk_Window tkwin; - Pixmap pixmap; -{ - (tkStubsPtr->tk_SetWindowBorderPixmap)(tkwin, pixmap); -} - -/* Slot 170 */ -void -Tk_SetWindowColormap(tkwin, colormap) - Tk_Window tkwin; - Colormap colormap; -{ - (tkStubsPtr->tk_SetWindowColormap)(tkwin, colormap); -} - -/* Slot 171 */ -int -Tk_SetWindowVisual(tkwin, visual, depth, colormap) - Tk_Window tkwin; - Visual * visual; - int depth; - Colormap colormap; -{ - return (tkStubsPtr->tk_SetWindowVisual)(tkwin, visual, depth, colormap); -} - -/* Slot 172 */ -void -Tk_SizeOfBitmap(display, bitmap, widthPtr, heightPtr) - Display * display; - Pixmap bitmap; - int * widthPtr; - int * heightPtr; -{ - (tkStubsPtr->tk_SizeOfBitmap)(display, bitmap, widthPtr, heightPtr); -} - -/* Slot 173 */ -void -Tk_SizeOfImage(image, widthPtr, heightPtr) - Tk_Image image; - int * widthPtr; - int * heightPtr; -{ - (tkStubsPtr->tk_SizeOfImage)(image, widthPtr, heightPtr); -} - -/* Slot 174 */ -int -Tk_StrictMotif(tkwin) - Tk_Window tkwin; -{ - return (tkStubsPtr->tk_StrictMotif)(tkwin); -} - -/* Slot 175 */ -void -Tk_TextLayoutToPostscript(interp, layout) - Tcl_Interp * interp; - Tk_TextLayout layout; -{ - (tkStubsPtr->tk_TextLayoutToPostscript)(interp, layout); -} - -/* Slot 176 */ -int -Tk_TextWidth(font, string, numChars) - Tk_Font font; - CONST char * string; - int numChars; -{ - return (tkStubsPtr->tk_TextWidth)(font, string, numChars); -} - -/* Slot 177 */ -void -Tk_UndefineCursor(window) - Tk_Window window; -{ - (tkStubsPtr->tk_UndefineCursor)(window); -} - -/* Slot 178 */ -void -Tk_UnderlineChars(display, drawable, gc, tkfont, source, x, y, firstChar, lastChar) - Display * display; - Drawable drawable; - GC gc; - Tk_Font tkfont; - CONST char * source; - int x; - int y; - int firstChar; - int lastChar; -{ - (tkStubsPtr->tk_UnderlineChars)(display, drawable, gc, tkfont, source, x, y, firstChar, lastChar); -} - -/* Slot 179 */ -void -Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) - Display * display; - Drawable drawable; - GC gc; - Tk_TextLayout layout; - int x; - int y; - int underline; -{ - (tkStubsPtr->tk_UnderlineTextLayout)(display, drawable, gc, layout, x, y, underline); -} - -/* Slot 180 */ -void -Tk_Ungrab(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_Ungrab)(tkwin); -} - -/* Slot 181 */ -void -Tk_UnmaintainGeometry(slave, master) - Tk_Window slave; - Tk_Window master; -{ - (tkStubsPtr->tk_UnmaintainGeometry)(slave, master); -} - -/* Slot 182 */ -void -Tk_UnmapWindow(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_UnmapWindow)(tkwin); -} - -/* Slot 183 */ -void -Tk_UnsetGrid(tkwin) - Tk_Window tkwin; -{ - (tkStubsPtr->tk_UnsetGrid)(tkwin); -} - -/* Slot 184 */ -void -Tk_UpdatePointer(tkwin, x, y, state) - Tk_Window tkwin; - int x; - int y; - int state; -{ - (tkStubsPtr->tk_UpdatePointer)(tkwin, x, y, state); -} - - -/* !END!: Do not edit above this line. */ diff --git a/generic/tkTest.c b/generic/tkTest.c index 0415e67..4b2fa93 100644 --- a/generic/tkTest.c +++ b/generic/tkTest.c @@ -8,15 +8,17 @@ * * Copyright (c) 1993-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 by Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTest.c,v 1.4 1999/02/04 20:57:17 stanton Exp $ + * RCS: @(#) $Id: tkTest.c,v 1.5 1999/04/16 01:51:23 stanton Exp $ */ #include "tkInt.h" -#include "tkPort.h" +#include "tkPort.h" +#include "tkText.h" #ifdef __WIN32__ #include "tkWinInt.h" @@ -102,8 +104,8 @@ static NewApp *newAppPtr = NULL; * Declaration for the square widget's class command procedure: */ -extern int SquareCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char *argv[])); +extern int SquareObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[])); typedef struct CBinding { Tcl_Interp *interp; @@ -112,6 +114,32 @@ typedef struct CBinding { } CBinding; /* + * Header for trivial configuration command items. + */ + +#define ODD TK_CONFIG_USER_BIT +#define EVEN (TK_CONFIG_USER_BIT << 1) + +enum { + NONE, + ODD_TYPE, + EVEN_TYPE +}; + +typedef struct TrivialCommandHeader { + Tcl_Interp *interp; /* The interp that this command + * lives in. */ + Tk_OptionTable optionTable; /* The option table that go with + * this command. */ + Tk_Window tkwin; /* For widgets, the window associated + * with this widget. */ + Tcl_Command widgetCmd; /* For widgets, the command associated + * with this widget. */ +} TrivialCommandHeader; + + + +/* * Forward declarations for procedures defined later in this file: */ @@ -124,12 +152,23 @@ static int ImageCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); static int TestcbindCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); -#ifdef __WIN32__ -static int TestclipboardCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -#endif +static int TestbitmapObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static int TestborderObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static int TestcolorObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static int TestcursorObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); static int TestdeleteappsCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); +static int TestfontObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[])); static int TestmakeexistCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); static int TestmenubarCmd _ANSI_ARGS_((ClientData dummy, @@ -138,14 +177,26 @@ static int TestmenubarCmd _ANSI_ARGS_((ClientData dummy, static int TestmetricsCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); #endif +static int TestobjconfigObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static int TestpropCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int argc, char **argv)); static int TestsendCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); -static int TestpropCmd _ANSI_ARGS_((ClientData dummy, +static int TesttextCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); #if !(defined(__WIN32__) || defined(MAC_TCL)) static int TestwrapperCmd _ANSI_ARGS_((ClientData dummy, Tcl_Interp *interp, int argc, char **argv)); #endif +static void TrivialCmdDeletedProc _ANSI_ARGS_(( + ClientData clientData)); +static int TrivialConfigObjCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * CONST objv[])); +static void TrivialEventProc _ANSI_ARGS_((ClientData clientData, + XEvent *eventPtr)); /* * External (platform specific) initialization routine: @@ -153,7 +204,9 @@ static int TestwrapperCmd _ANSI_ARGS_((ClientData dummy, extern int TkplatformtestInit _ANSI_ARGS_(( Tcl_Interp *interp)); -#ifndef MAC_TCL +extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp)); + +#if !(defined(__WIN32__) || defined(MAC_TCL)) #define TkplatformtestInit(x) TCL_OK #endif @@ -167,7 +220,7 @@ extern int TkplatformtestInit _ANSI_ARGS_(( * * Results: * Returns a standard Tcl completion code, and leaves an error - * message in interp->result if an error occurs. + * message in the interp's result if an error occurs. * * Side effects: * Creates several test commands. @@ -189,18 +242,26 @@ Tktest_Init(interp) return TCL_ERROR; } - Tcl_CreateCommand(interp, "square", SquareCmd, + Tcl_CreateObjCommand(interp, "square", SquareObjCmd, + (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, "testcbind", TestcbindCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); -#ifdef __WIN32__ - Tcl_CreateCommand(interp, "testclipboard", TestclipboardCmd, + Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); -#endif - Tcl_CreateCommand(interp, "testcbind", TestcbindCmd, + Tcl_CreateObjCommand(interp, "testborder", TestborderObjCmd, + (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "testcolor", TestcolorObjCmd, + (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "testcursor", TestcursorObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testdeleteapps", TestdeleteappsCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testembed", TkpTestembedCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "testobjconfig", TestobjconfigObjCmd, + (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateObjCommand(interp, "testfont", TestfontObjCmd, + (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testmakeexist", TestmakeexistCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testmenubar", TestmenubarCmd, @@ -213,12 +274,20 @@ Tktest_Init(interp) (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "testsend", TestsendCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, "testtext", TesttextCmd, + (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); #if !(defined(__WIN32__) || defined(MAC_TCL)) Tcl_CreateCommand(interp, "testwrapper", TestwrapperCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); #endif -/* +#ifdef TCL_THREADS + if (TclThread_Init(interp) != TCL_OK) { + return TCL_ERROR; + } +#endif + + /* * Create test image type. */ @@ -237,48 +306,6 @@ Tktest_Init(interp) /* *---------------------------------------------------------------------- * - * TestclipboardCmd -- - * - * This procedure implements the testclipboard command. It provides - * a way to determine the actual contents of the Windows clipboard. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -#ifdef __WIN32__ -static int -TestclipboardCmd(clientData, interp, argc, argv) - ClientData clientData; /* Main window for application. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ -{ - TkWindow *winPtr = (TkWindow *) clientData; - HGLOBAL handle; - char *data; - - if (OpenClipboard(NULL)) { - handle = GetClipboardData(CF_TEXT); - if (handle != NULL) { - data = GlobalLock(handle); - Tcl_AppendResult(interp, data, (char *) NULL); - GlobalUnlock(handle); - } - CloseClipboard(); - } - return TCL_OK; -} -#endif - -/* - *---------------------------------------------------------------------- - * * TestcbindCmd -- * * This procedure implements the "testcbinding" command. It provides @@ -386,6 +413,146 @@ CBindingFreeProc(clientData) /* *---------------------------------------------------------------------- * + * TestbitmapObjCmd -- + * + * This procedure implements the "testbitmap" command, which is used + * to test color resource handling in tkBitmap tmp.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestbitmapObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "bitmap"); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TkDebugBitmap(Tk_MainWindow(interp), + Tcl_GetString(objv[1]))); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TestborderObjCmd -- + * + * This procedure implements the "testborder" command, which is used + * to test color resource handling in tkBorder.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestborderObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "border"); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TkDebugBorder(Tk_MainWindow(interp), + Tcl_GetString(objv[1]))); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TestcolorObjCmd -- + * + * This procedure implements the "testcolor" command, which is used + * to test color resource handling in tkColor.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestcolorObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "color"); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TkDebugColor(Tk_MainWindow(interp), + Tcl_GetString(objv[1]))); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TestcursorObjCmd -- + * + * This procedure implements the "testcursor" command, which is used + * to test color resource handling in tkCursor.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestcursorObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "cursor"); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TkDebugCursor(Tk_MainWindow(interp), + Tcl_GetString(objv[1]))); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * TestdeleteappsCmd -- * * This procedure implements the "testdeleteapps" command. It cleans @@ -424,6 +591,956 @@ TestdeleteappsCmd(clientData, interp, argc, argv) /* *---------------------------------------------------------------------- * + * TestobjconfigObjCmd -- + * + * This procedure implements the "testobjconfig" command, + * which is used to test the procedures in tkConfig.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestobjconfigObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + static char *options[] = {"alltypes", "chain1", "chain2", + "configerror", "delete", "info", "internal", "new", + "notenoughparams", "twowindows", (char *) NULL}; + enum { + ALL_TYPES, + CHAIN1, + CHAIN2, + CONFIG_ERROR, + DEL, /* Can't use DELETE: VC++ compiler barfs. */ + INFO, + INTERNAL, + NEW, + NOT_ENOUGH_PARAMS, + TWO_WINDOWS + }; + static Tk_OptionTable tables[11]; /* Holds pointers to option tables + * created by commands below; indexed + * with same values as "options" + * array. */ + Tk_Window mainWin = (Tk_Window) clientData; + Tk_Window tkwin; + int index, result = TCL_OK; + + /* + * Structures used by the "chain1" subcommand and also shared by + * the "chain2" subcommand: + */ + + typedef struct ExtensionWidgetRecord { + TrivialCommandHeader header; + Tcl_Obj *base1ObjPtr; + Tcl_Obj *base2ObjPtr; + Tcl_Obj *extension3ObjPtr; + Tcl_Obj *extension4ObjPtr; + Tcl_Obj *extension5ObjPtr; + } ExtensionWidgetRecord; + static Tk_OptionSpec baseSpecs[] = { + {TK_OPTION_STRING, + "-one", "one", "One", "one", + Tk_Offset(ExtensionWidgetRecord, base1ObjPtr), -1}, + {TK_OPTION_STRING, + "-two", "two", "Two", "two", + Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1}, + {TK_OPTION_END} + }; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "command"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index) + != TCL_OK) { + return TCL_ERROR; + } + + switch (index) { + case ALL_TYPES: { + typedef struct TypesRecord { + TrivialCommandHeader header; + Tcl_Obj *booleanPtr; + Tcl_Obj *integerPtr; + Tcl_Obj *doublePtr; + Tcl_Obj *stringPtr; + Tcl_Obj *stringTablePtr; + Tcl_Obj *colorPtr; + Tcl_Obj *fontPtr; + Tcl_Obj *bitmapPtr; + Tcl_Obj *borderPtr; + Tcl_Obj *reliefPtr; + Tcl_Obj *cursorPtr; + Tcl_Obj *activeCursorPtr; + Tcl_Obj *justifyPtr; + Tcl_Obj *anchorPtr; + Tcl_Obj *pixelPtr; + Tcl_Obj *mmPtr; + } TypesRecord; + TypesRecord *recordPtr; + static char *stringTable[] = {"one", "two", "three", "four", + (char *) NULL}; + static Tk_OptionSpec typesSpecs[] = { + {TK_OPTION_BOOLEAN, + "-boolean", "boolean", "Boolean", + "1", Tk_Offset(TypesRecord, booleanPtr), -1, 0, 0, 0x1}, + {TK_OPTION_INT, + "-integer", "integer", "Integer", + "7", Tk_Offset(TypesRecord, integerPtr), -1, 0, 0, 0x2}, + {TK_OPTION_DOUBLE, + "-double", "double", "Double", + "3.14159", Tk_Offset(TypesRecord, doublePtr), -1, 0, 0, + 0x4}, + {TK_OPTION_STRING, + "-string", "string", "String", + "foo", Tk_Offset(TypesRecord, stringPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x8}, + {TK_OPTION_STRING_TABLE, + "-stringtable", "StringTable", "stringTable", + "one", Tk_Offset(TypesRecord, stringTablePtr), -1, + TK_CONFIG_NULL_OK, (ClientData) stringTable, 0x10}, + {TK_OPTION_COLOR, + "-color", "color", "Color", + "red", Tk_Offset(TypesRecord, colorPtr), -1, + TK_CONFIG_NULL_OK, (ClientData) "black", 0x20}, + {TK_OPTION_FONT, + "-font", "font", "Font", + "Helvetica 12", + Tk_Offset(TypesRecord, fontPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x40}, + {TK_OPTION_BITMAP, + "-bitmap", "bitmap", "Bitmap", + "gray50", + Tk_Offset(TypesRecord, bitmapPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x80}, + {TK_OPTION_BORDER, + "-border", "border", "Border", + "blue", Tk_Offset(TypesRecord, borderPtr), -1, + TK_CONFIG_NULL_OK, (ClientData) "white", 0x100}, + {TK_OPTION_RELIEF, + "-relief", "relief", "Relief", + "raised", + Tk_Offset(TypesRecord, reliefPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x200}, + {TK_OPTION_CURSOR, + "-cursor", "cursor", "Cursor", + "xterm", + Tk_Offset(TypesRecord, cursorPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x400}, + {TK_OPTION_JUSTIFY, + "-justify", (char *) NULL, (char *) NULL, + "left", + Tk_Offset(TypesRecord, justifyPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x800}, + {TK_OPTION_ANCHOR, + "-anchor", "anchor", "Anchor", + (char *) NULL, + Tk_Offset(TypesRecord, anchorPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x1000}, + {TK_OPTION_PIXELS, + "-pixel", "pixel", "Pixel", + "1", Tk_Offset(TypesRecord, pixelPtr), -1, + TK_CONFIG_NULL_OK, 0, 0x2000}, + {TK_OPTION_SYNONYM, + "-synonym", (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) "-color", + 0x8000}, + {TK_OPTION_END} + }; + Tk_OptionTable optionTable; + Tk_Window tkwin; + optionTable = Tk_CreateOptionTable(interp, + typesSpecs); + tables[index] = optionTable; + tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData, + Tcl_GetStringFromObj(objv[2], NULL), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + Tk_SetClass(tkwin, "Test"); + + recordPtr = (TypesRecord *) ckalloc(sizeof(TypesRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = optionTable; + recordPtr->header.tkwin = tkwin; + recordPtr->booleanPtr = NULL; + recordPtr->integerPtr = NULL; + recordPtr->doublePtr = NULL; + recordPtr->stringPtr = NULL; + recordPtr->colorPtr = NULL; + recordPtr->fontPtr = NULL; + recordPtr->bitmapPtr = NULL; + recordPtr->borderPtr = NULL; + recordPtr->reliefPtr = NULL; + recordPtr->cursorPtr = NULL; + recordPtr->justifyPtr = NULL; + recordPtr->anchorPtr = NULL; + recordPtr->pixelPtr = NULL; + recordPtr->mmPtr = NULL; + recordPtr->stringTablePtr = NULL; + result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + tkwin); + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + Tk_CreateEventHandler(tkwin, StructureNotifyMask, + TrivialEventProc, (ClientData) recordPtr); + result = Tk_SetOptions(interp, (char *) recordPtr, + optionTable, objc - 3, objv + 3, tkwin, + (Tk_SavedOptions *) NULL, (int *) NULL); + if (result != TCL_OK) { + Tk_DestroyWindow(tkwin); + } + } else { + Tk_DestroyWindow(tkwin); + ckfree((char *) recordPtr); + } + if (result == TCL_OK) { + Tcl_SetObjResult(interp, objv[2]); + } + break; + } + + case CHAIN1: { + ExtensionWidgetRecord *recordPtr; + Tk_Window tkwin; + Tk_OptionTable optionTable; + + tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData, + Tcl_GetStringFromObj(objv[2], NULL), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + Tk_SetClass(tkwin, "Test"); + optionTable = Tk_CreateOptionTable(interp, baseSpecs); + tables[index] = optionTable; + + recordPtr = (ExtensionWidgetRecord *) ckalloc( + sizeof(ExtensionWidgetRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = optionTable; + recordPtr->header.tkwin = tkwin; + recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL; + recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL; + result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + tkwin); + if (result == TCL_OK) { + result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + objc - 3, objv + 3, tkwin, (Tk_SavedOptions *) NULL, + (int *) NULL); + if (result != TCL_OK) { + Tk_FreeConfigOptions((char *) recordPtr, optionTable, + tkwin); + } + } + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + Tk_CreateEventHandler(tkwin, StructureNotifyMask, + TrivialEventProc, (ClientData) recordPtr); + Tcl_SetObjResult(interp, objv[2]); + } + break; + } + + case CHAIN2: { + ExtensionWidgetRecord *recordPtr; + static Tk_OptionSpec extensionSpecs[] = { + {TK_OPTION_STRING, + "-three", "three", "Three", "three", + Tk_Offset(ExtensionWidgetRecord, extension3ObjPtr), + -1}, + {TK_OPTION_STRING, + "-four", "four", "Four", "four", + Tk_Offset(ExtensionWidgetRecord, extension4ObjPtr), + -1}, + {TK_OPTION_STRING, + "-two", "two", "Two", "two and a half", + Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), + -1}, + {TK_OPTION_STRING, + "-oneAgain", "oneAgain", "OneAgain", "one again", + Tk_Offset(ExtensionWidgetRecord, extension5ObjPtr), + -1}, + {TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL, + (char *) NULL, 0, -1, 0, (ClientData) baseSpecs} + }; + Tk_Window tkwin; + Tk_OptionTable optionTable; + + tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData, + Tcl_GetStringFromObj(objv[2], NULL), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + Tk_SetClass(tkwin, "Test"); + optionTable = Tk_CreateOptionTable(interp, extensionSpecs); + tables[index] = optionTable; + + recordPtr = (ExtensionWidgetRecord *) ckalloc( + sizeof(ExtensionWidgetRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = optionTable; + recordPtr->header.tkwin = tkwin; + recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL; + recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL; + recordPtr->extension5ObjPtr = NULL; + result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + tkwin); + if (result == TCL_OK) { + result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + objc - 3, objv + 3, tkwin, (Tk_SavedOptions *) NULL, + (int *) NULL); + if (result != TCL_OK) { + Tk_FreeConfigOptions((char *) recordPtr, optionTable, + tkwin); + } + } + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + Tk_CreateEventHandler(tkwin, StructureNotifyMask, + TrivialEventProc, (ClientData) recordPtr); + Tcl_SetObjResult(interp, objv[2]); + } + break; + } + + case CONFIG_ERROR: { + typedef struct ErrorWidgetRecord { + Tcl_Obj *intPtr; + } ErrorWidgetRecord; + ErrorWidgetRecord widgetRecord; + static Tk_OptionSpec errorSpecs[] = { + {TK_OPTION_INT, + "-int", "integer", "Integer", + "bogus", Tk_Offset(ErrorWidgetRecord, intPtr)}, + {TK_OPTION_END} + }; + Tk_OptionTable optionTable; + + widgetRecord.intPtr = NULL; + optionTable = Tk_CreateOptionTable(interp, errorSpecs); + tables[index] = optionTable; + return Tk_InitOptions(interp, (char *) &widgetRecord, optionTable, + (Tk_Window) NULL); + } + + case DEL: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "tableName"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + if (tables[index] != NULL) { + Tk_DeleteOptionTable(tables[index]); + } + break; + } + + case INFO: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "tableName"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[2], options, "table", 0, + &index) != TCL_OK) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TkDebugConfig(interp, tables[index])); + break; + } + + case INTERNAL: { + /* + * This command is similar to the "alltypes" command except + * that it stores all the configuration options as internal + * forms instead of objects. + */ + + typedef struct InternalRecord { + TrivialCommandHeader header; + int boolean; + int integer; + double doubleValue; + char *string; + int index; + XColor *colorPtr; + Tk_Font tkfont; + Pixmap bitmap; + Tk_3DBorder border; + int relief; + Tk_Cursor cursor; + Tk_Justify justify; + Tk_Anchor anchor; + int pixels; + double mm; + Tk_Window tkwin; + } InternalRecord; + InternalRecord *recordPtr; + static char *internalStringTable[] = { + "one", "two", "three", "four", (char *) NULL + }; + static Tk_OptionSpec internalSpecs[] = { + {TK_OPTION_BOOLEAN, + "-boolean", "boolean", "Boolean", + "1", -1, Tk_Offset(InternalRecord, boolean), 0, 0, 0x1}, + {TK_OPTION_INT, + "-integer", "integer", "Integer", + "148962237", -1, Tk_Offset(InternalRecord, integer), + 0, 0, 0x2}, + {TK_OPTION_DOUBLE, + "-double", "double", "Double", + "3.14159", -1, Tk_Offset(InternalRecord, doubleValue), + 0, 0, 0x4}, + {TK_OPTION_STRING, + "-string", "string", "String", + "foo", -1, Tk_Offset(InternalRecord, string), + TK_CONFIG_NULL_OK, 0, 0x8}, + {TK_OPTION_STRING_TABLE, + "-stringtable", "StringTable", "stringTable", + "one", -1, Tk_Offset(InternalRecord, index), + TK_CONFIG_NULL_OK, (ClientData) internalStringTable, + 0x10}, + {TK_OPTION_COLOR, + "-color", "color", "Color", + "red", -1, Tk_Offset(InternalRecord, colorPtr), + TK_CONFIG_NULL_OK, (ClientData) "black", 0x20}, + {TK_OPTION_FONT, + "-font", "font", "Font", + "Helvetica 12", -1, Tk_Offset(InternalRecord, tkfont), + TK_CONFIG_NULL_OK, 0, 0x40}, + {TK_OPTION_BITMAP, + "-bitmap", "bitmap", "Bitmap", + "gray50", -1, Tk_Offset(InternalRecord, bitmap), + TK_CONFIG_NULL_OK, 0, 0x80}, + {TK_OPTION_BORDER, + "-border", "border", "Border", + "blue", -1, Tk_Offset(InternalRecord, border), + TK_CONFIG_NULL_OK, (ClientData) "white", 0x100}, + {TK_OPTION_RELIEF, + "-relief", "relief", "Relief", + "raised", -1, Tk_Offset(InternalRecord, relief), + TK_CONFIG_NULL_OK, 0, 0x200}, + {TK_OPTION_CURSOR, + "-cursor", "cursor", "Cursor", + "xterm", -1, Tk_Offset(InternalRecord, cursor), + TK_CONFIG_NULL_OK, 0, 0x400}, + {TK_OPTION_JUSTIFY, + "-justify", (char *) NULL, (char *) NULL, + "left", -1, Tk_Offset(InternalRecord, justify), + TK_CONFIG_NULL_OK, 0, 0x800}, + {TK_OPTION_ANCHOR, + "-anchor", "anchor", "Anchor", + (char *) NULL, -1, Tk_Offset(InternalRecord, anchor), + TK_CONFIG_NULL_OK, 0, 0x1000}, + {TK_OPTION_PIXELS, + "-pixel", "pixel", "Pixel", + "1", -1, Tk_Offset(InternalRecord, pixels), + TK_CONFIG_NULL_OK, 0, 0x2000}, + {TK_OPTION_WINDOW, + "-window", "window", "Window", + (char *) NULL, -1, Tk_Offset(InternalRecord, tkwin), + TK_CONFIG_NULL_OK, 0, 0}, + {TK_OPTION_SYNONYM, + "-synonym", (char *) NULL, (char *) NULL, + (char *) NULL, -1, -1, 0, (ClientData) "-color", + 0x8000}, + {TK_OPTION_END} + }; + Tk_OptionTable optionTable; + Tk_Window tkwin; + optionTable = Tk_CreateOptionTable(interp, internalSpecs); + tables[index] = optionTable; + tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window) clientData, + Tcl_GetStringFromObj(objv[2], NULL), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + Tk_SetClass(tkwin, "Test"); + + recordPtr = (InternalRecord *) ckalloc(sizeof(InternalRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = optionTable; + recordPtr->header.tkwin = tkwin; + recordPtr->boolean = 0; + recordPtr->integer = 0; + recordPtr->doubleValue = 0.0; + recordPtr->string = NULL; + recordPtr->index = 0; + recordPtr->colorPtr = NULL; + recordPtr->tkfont = NULL; + recordPtr->bitmap = None; + recordPtr->border = NULL; + recordPtr->relief = TK_RELIEF_FLAT; + recordPtr->cursor = NULL; + recordPtr->justify = TK_JUSTIFY_LEFT; + recordPtr->anchor = TK_ANCHOR_N; + recordPtr->pixels = 0; + recordPtr->mm = 0.0; + recordPtr->tkwin = NULL; + result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + tkwin); + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + Tk_CreateEventHandler(tkwin, StructureNotifyMask, + TrivialEventProc, (ClientData) recordPtr); + result = Tk_SetOptions(interp, (char *) recordPtr, + optionTable, objc - 3, objv + 3, tkwin, + (Tk_SavedOptions *) NULL, (int *) NULL); + if (result != TCL_OK) { + Tk_DestroyWindow(tkwin); + } + } else { + Tk_DestroyWindow(tkwin); + ckfree((char *) recordPtr); + } + if (result == TCL_OK) { + Tcl_SetObjResult(interp, objv[2]); + } + break; + } + + case NEW: { + typedef struct FiveRecord { + TrivialCommandHeader header; + Tcl_Obj *one; + Tcl_Obj *two; + Tcl_Obj *three; + Tcl_Obj *four; + Tcl_Obj *five; + } FiveRecord; + FiveRecord *recordPtr; + static Tk_OptionSpec smallSpecs[] = { + {TK_OPTION_INT, + "-one", "one", "One", + "1", + Tk_Offset(FiveRecord, one), -1}, + {TK_OPTION_INT, + "-two", "two", "Two", + "2", + Tk_Offset(FiveRecord, two), -1}, + {TK_OPTION_INT, + "-three", "three", "Three", + "3", + Tk_Offset(FiveRecord, three), -1}, + {TK_OPTION_INT, + "-four", "four", "Four", + "4", + Tk_Offset(FiveRecord, four), -1}, + {TK_OPTION_STRING, + "-five", NULL, NULL, + NULL, + Tk_Offset(FiveRecord, five), -1}, + {TK_OPTION_END} + }; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "new name ?options?"); + return TCL_ERROR; + } + + recordPtr = (FiveRecord *) ckalloc(sizeof(FiveRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = Tk_CreateOptionTable(interp, + smallSpecs); + tables[index] = recordPtr->header.optionTable; + recordPtr->header.tkwin = NULL; + recordPtr->one = recordPtr->two = recordPtr->three = NULL; + recordPtr->four = recordPtr->five = NULL; + Tcl_SetObjResult(interp, objv[2]); + result = Tk_InitOptions(interp, (char *) recordPtr, + recordPtr->header.optionTable, (Tk_Window) NULL); + if (result == TCL_OK) { + result = Tk_SetOptions(interp, (char *) recordPtr, + recordPtr->header.optionTable, objc - 3, objv + 3, + (Tk_Window) NULL, (Tk_SavedOptions *) NULL, + (int *) NULL); + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + } else { + Tk_FreeConfigOptions((char *) recordPtr, + recordPtr->header.optionTable, (Tk_Window) NULL); + } + } + if (result != TCL_OK) { + ckfree((char *) recordPtr); + } + + break; + } + case NOT_ENOUGH_PARAMS: { + typedef struct NotEnoughRecord { + Tcl_Obj *fooObjPtr; + } NotEnoughRecord; + NotEnoughRecord record; + static Tk_OptionSpec errorSpecs[] = { + {TK_OPTION_INT, + "-foo", "foo", "Foo", + "0", Tk_Offset(NotEnoughRecord, fooObjPtr)}, + {TK_OPTION_END} + }; + Tcl_Obj *newObjPtr = Tcl_NewStringObj("-foo", -1); + Tk_OptionTable optionTable; + + record.fooObjPtr = NULL; + + tkwin = Tk_CreateWindowFromPath(interp, mainWin, + ".config", (char *) NULL); + Tk_SetClass(tkwin, "Config"); + optionTable = Tk_CreateOptionTable(interp, errorSpecs); + tables[index] = optionTable; + Tk_InitOptions(interp, (char *) &record, optionTable, tkwin); + if (Tk_SetOptions(interp, (char *) &record, optionTable, + 1, &newObjPtr, tkwin, (Tk_SavedOptions *) NULL, + (int *) NULL) + != TCL_OK) { + result = TCL_ERROR; + } + Tcl_DecrRefCount(newObjPtr); + Tk_FreeConfigOptions( (char *) &record, optionTable, tkwin); + Tk_DestroyWindow(tkwin); + return result; + } + + case TWO_WINDOWS: { + typedef struct SlaveRecord { + TrivialCommandHeader header; + Tcl_Obj *windowPtr; + } SlaveRecord; + SlaveRecord *recordPtr; + static Tk_OptionSpec slaveSpecs[] = { + {TK_OPTION_WINDOW, + "-window", "window", "Window", + ".bar", Tk_Offset(SlaveRecord, windowPtr), -1, + TK_CONFIG_NULL_OK}, + {TK_OPTION_END} + }; + Tk_Window tkwin = Tk_CreateWindowFromPath(interp, + (Tk_Window) clientData, + Tcl_GetStringFromObj(objv[2], NULL), (char *) NULL); + if (tkwin == NULL) { + return TCL_ERROR; + } + Tk_SetClass(tkwin, "Test"); + + recordPtr = (SlaveRecord *) ckalloc(sizeof(SlaveRecord)); + recordPtr->header.interp = interp; + recordPtr->header.optionTable = Tk_CreateOptionTable(interp, + slaveSpecs); + tables[index] = recordPtr->header.optionTable; + recordPtr->header.tkwin = tkwin; + recordPtr->windowPtr = NULL; + + result = Tk_InitOptions(interp, (char *) recordPtr, + recordPtr->header.optionTable, tkwin); + if (result == TCL_OK) { + result = Tk_SetOptions(interp, (char *) recordPtr, + recordPtr->header.optionTable, objc - 3, objv + 3, + tkwin, (Tk_SavedOptions *) NULL, (int *) NULL); + if (result == TCL_OK) { + recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, + Tcl_GetStringFromObj(objv[2], NULL), + TrivialConfigObjCmd, (ClientData) recordPtr, + TrivialCmdDeletedProc); + Tk_CreateEventHandler(tkwin, StructureNotifyMask, + TrivialEventProc, (ClientData) recordPtr); + Tcl_SetObjResult(interp, objv[2]); + } else { + Tk_FreeConfigOptions((char *) recordPtr, + recordPtr->header.optionTable, tkwin); + } + } + if (result != TCL_OK) { + Tk_DestroyWindow(tkwin); + ckfree((char *) recordPtr); + } + + } + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TrivialConfigObjCmd -- + * + * This command is used to test the configuration package. It only + * handles the "configure" and "cget" subcommands. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TrivialConfigObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + int result = TCL_OK; + static char *options[] = {"cget", "configure", "csave", (char *) NULL}; + enum { + CGET, CONFIGURE, CSAVE + }; + Tcl_Obj *resultObjPtr; + int index, mask; + TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData; + Tk_Window tkwin = headerPtr->tkwin; + Tk_SavedOptions saved; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", + 0, &index) != TCL_OK) { + return TCL_ERROR; + } + + Tcl_Preserve(clientData); + + switch (index) { + case CGET: { + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); + result = TCL_ERROR; + goto done; + } + resultObjPtr = Tk_GetOptionValue(interp, (char *) clientData, + headerPtr->optionTable, objv[2], tkwin); + if (resultObjPtr != NULL) { + Tcl_SetObjResult(interp, resultObjPtr); + result = TCL_OK; + } else { + result = TCL_ERROR; + } + break; + } + case CONFIGURE: { + if (objc == 2) { + resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData, + headerPtr->optionTable, (Tcl_Obj *) NULL, tkwin); + if (resultObjPtr == NULL) { + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, resultObjPtr); + } + } else if (objc == 3) { + resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData, + headerPtr->optionTable, objv[2], tkwin); + if (resultObjPtr == NULL) { + result = TCL_ERROR; + } else { + Tcl_SetObjResult(interp, resultObjPtr); + } + } else { + result = Tk_SetOptions(interp, (char *) clientData, + headerPtr->optionTable, objc - 2, objv + 2, + tkwin, (Tk_SavedOptions *) NULL, &mask); + if (result == TCL_OK) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), mask); + } + } + break; + } + case CSAVE: { + result = Tk_SetOptions(interp, (char *) clientData, + headerPtr->optionTable, objc - 2, objv + 2, + tkwin, &saved, &mask); + Tk_FreeSavedOptions(&saved); + if (result == TCL_OK) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), mask); + } + break; + } + } +done: + Tcl_Release(clientData); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TrivialCmdDeletedProc -- + * + * This procedure is invoked when a widget command is deleted. If + * the widget isn't already in the process of being destroyed, + * this command destroys it. + * + * Results: + * None. + * + * Side effects: + * The widget is destroyed. + * + *---------------------------------------------------------------------- + */ + +static void +TrivialCmdDeletedProc(clientData) + ClientData clientData; /* Pointer to widget record for widget. */ +{ + TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData; + Tk_Window tkwin = headerPtr->tkwin; + + if (tkwin != NULL) { + Tk_DestroyWindow(tkwin); + } else if (headerPtr->optionTable != NULL) { + /* + * This is a "new" object, which doesn't have a window, so + * we can't depend on cleaning up in the event procedure. + * Free its resources here. + */ + + Tk_FreeConfigOptions((char *) clientData, + headerPtr->optionTable, (Tk_Window) NULL); + Tcl_EventuallyFree(clientData, TCL_DYNAMIC); + } +} + +/* + *-------------------------------------------------------------- + * + * TrivialEventProc -- + * + * A dummy event proc. + * + * Results: + * None. + * + * Side effects: + * When the window gets deleted, internal structures get + * cleaned up. + * + *-------------------------------------------------------------- + */ + +static void +TrivialEventProc(clientData, eventPtr) + ClientData clientData; /* Information about window. */ + XEvent *eventPtr; /* Information about event. */ +{ + TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData; + + if (eventPtr->type == DestroyNotify) { + if (headerPtr->tkwin != NULL) { + Tk_FreeConfigOptions((char *) clientData, + headerPtr->optionTable, headerPtr->tkwin); + headerPtr->optionTable = NULL; + headerPtr->tkwin = NULL; + Tcl_DeleteCommandFromToken(headerPtr->interp, + headerPtr->widgetCmd); + } + Tcl_EventuallyFree(clientData, TCL_DYNAMIC); + } +} + +/* + *---------------------------------------------------------------------- + * + * TestfontObjCmd -- + * + * This procedure implements the "testfont" command, which is used + * to test TkFont objects. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestfontObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ +{ + static char *options[] = {"counts", "subfonts", (char *) NULL}; + enum option {COUNTS, SUBFONTS}; + int index; + Tk_Window tkwin; + Tk_Font tkfont; + + tkwin = (Tk_Window) clientData; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 1, objv, "option fontName"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[1], options, "command", 0, &index) + != TCL_OK) { + return TCL_ERROR; + } + + switch ((enum option) index) { + case COUNTS: { + Tcl_SetObjResult(interp, TkDebugFont(Tk_MainWindow(interp), + Tcl_GetString(objv[2]))); + break; + } + case SUBFONTS: { + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); + if (tkfont == NULL) { + return TCL_ERROR; + } + TkpGetSubFonts(interp, tkfont); + Tk_FreeFont(tkfont); + break; + } + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * ImageCreate -- * * This procedure is called by the Tk image code to create "test" @@ -523,7 +1640,8 @@ ImageCmd(clientData, interp, argc, argv) if (strcmp(argv[1], "changed") == 0) { if (argc != 8) { Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " changed x y width height imageWidth imageHeight", + argv[0], + " changed x y width height imageWidth imageHeight", (char *) NULL); return TCL_ERROR; } @@ -617,7 +1735,7 @@ ImageDisplay(clientData, display, drawable, imageX, imageY, width, height, * imageX and imageY. */ { TImageInstance *instPtr = (TImageInstance *) clientData; - char buffer[200]; + char buffer[200 + TCL_INTEGER_SPACE * 6]; sprintf(buffer, "%s display %d %d %d %d %d %d", instPtr->masterPtr->imageName, imageX, imageY, width, height, @@ -734,12 +1852,12 @@ TestmakeexistCmd(clientData, interp, argc, argv) int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { - Tk_Window mainwin = (Tk_Window) clientData; + Tk_Window mainWin = (Tk_Window) clientData; int i; Tk_Window tkwin; for (i = 1; i < argc; i++) { - tkwin = Tk_NameToWindow(interp, argv[i], mainwin); + tkwin = Tk_NameToWindow(interp, argv[i], mainWin); if (tkwin == NULL) { return TCL_ERROR; } @@ -776,7 +1894,7 @@ TestmenubarCmd(clientData, interp, argc, argv) char **argv; /* Argument strings. */ { #ifdef __UNIX__ - Tk_Window mainwin = (Tk_Window) clientData; + Tk_Window mainWin = (Tk_Window) clientData; Tk_Window tkwin, menubar; if (argc < 2) { @@ -791,14 +1909,14 @@ TestmenubarCmd(clientData, interp, argc, argv) "window toplevel menubar\"", (char *) NULL); return TCL_ERROR; } - tkwin = Tk_NameToWindow(interp, argv[2], mainwin); + tkwin = Tk_NameToWindow(interp, argv[2], mainWin); if (tkwin == NULL) { return TCL_ERROR; } if (argv[3][0] == 0) { TkUnixSetMenubar(tkwin, NULL); } else { - menubar = Tk_NameToWindow(interp, argv[3], mainwin); + menubar = Tk_NameToWindow(interp, argv[3], mainWin); if (menubar == NULL) { return TCL_ERROR; } @@ -812,7 +1930,8 @@ TestmenubarCmd(clientData, interp, argc, argv) return TCL_OK; #else - interp->result = "testmenubar is supported only under Unix"; + Tcl_SetResult(interp, "testmenubar is supported only under Unix", + TCL_STATIC); return TCL_ERROR; #endif } @@ -842,7 +1961,7 @@ TestmetricsCmd(clientData, interp, argc, argv) int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { - char buf[200]; + char buf[TCL_INTEGER_SPACE]; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], @@ -874,7 +1993,7 @@ TestmetricsCmd(clientData, interp, argc, argv) { Tk_Window tkwin = (Tk_Window) clientData; TkWindow *winPtr; - char buf[200]; + char buf[TCL_INTEGER_SPACE]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], @@ -927,7 +2046,7 @@ TestpropCmd(clientData, interp, argc, argv) int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { - Tk_Window mainwin = (Tk_Window) clientData; + Tk_Window mainWin = (Tk_Window) clientData; int result, actualFormat; unsigned long bytesAfter, length, value; Atom actualType, propName; @@ -942,9 +2061,9 @@ TestpropCmd(clientData, interp, argc, argv) } w = strtoul(argv[1], &end, 0); - propName = Tk_InternAtom(mainwin, argv[2]); + propName = Tk_InternAtom(mainWin, argv[2]); property = NULL; - result = XGetWindowProperty(Tk_Display(mainwin), + result = XGetWindowProperty(Tk_Display(mainWin), w, propName, 0, 100000, False, AnyPropertyType, &actualType, &actualFormat, &length, &bytesAfter, (unsigned char **) &property); @@ -1005,7 +2124,9 @@ TestsendCmd(clientData, interp, argc, argv) int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { +#if !(defined(__WIN32__) || defined(MAC_TCL)) TkWindow *winPtr = (TkWindow *) clientData; +#endif if (argc < 2) { Tcl_AppendResult(interp, "wrong # args; must be \"", argv[0], @@ -1073,7 +2194,10 @@ TestsendCmd(clientData, interp, argc, argv) } } } else if (strcmp(argv[1], "serial") == 0) { - sprintf(interp->result, "%d", tkSendSerial+1); + char buf[TCL_INTEGER_SPACE]; + + sprintf(buf, "%d", tkSendSerial+1); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be bogus, prop, or serial", (char *) NULL); @@ -1083,6 +2207,85 @@ TestsendCmd(clientData, interp, argc, argv) return TCL_OK; } +/* + *---------------------------------------------------------------------- + * + * TesttextCmd -- + * + * This procedure implements the "testtext" command. It provides + * a set of functions for testing text widgets and the associated + * functions in tkText*.c. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Depends on option; see below. + * + *---------------------------------------------------------------------- + */ + +static int +TesttextCmd(clientData, interp, argc, argv) + ClientData clientData; /* Main window for application. */ + Tcl_Interp *interp; /* Current interpreter. */ + int argc; /* Number of arguments. */ + char **argv; /* Argument strings. */ +{ + TkText *textPtr; + size_t len; + int lineIndex, byteIndex, byteOffset; + TkTextIndex index; + char buf[64]; + Tcl_CmdInfo info; + + if (argc < 3) { + return TCL_ERROR; + } + + if (Tcl_GetCommandInfo(interp, argv[1], &info) == 0) { + return TCL_ERROR; + } + textPtr = (TkText *) info.clientData; + len = strlen(argv[2]); + if (strncmp(argv[2], "byteindex", len) == 0) { + if (argc != 5) { + return TCL_ERROR; + } + lineIndex = atoi(argv[3]) - 1; + byteIndex = atoi(argv[4]); + + TkTextMakeByteIndex(textPtr->tree, lineIndex, byteIndex, &index); + } else if (strncmp(argv[2], "forwbytes", len) == 0) { + if (argc != 5) { + return TCL_ERROR; + } + if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { + return TCL_ERROR; + } + byteOffset = atoi(argv[4]); + TkTextIndexForwBytes(&index, byteOffset, &index); + } else if (strncmp(argv[2], "backbytes", len) == 0) { + if (argc != 5) { + return TCL_ERROR; + } + if (TkTextGetIndex(interp, textPtr, argv[3], &index) != TCL_OK) { + return TCL_ERROR; + } + byteOffset = atoi(argv[4]); + TkTextIndexBackBytes(&index, byteOffset, &index); + } else { + return TCL_ERROR; + } + + TkTextSetMark(textPtr, "insert", &index); + TkTextPrintIndex(&index, buf); + sprintf(buf + strlen(buf), " %d", index.byteIndex); + Tcl_AppendResult(interp, buf, NULL); + + return TCL_OK; +} + #if !(defined(__WIN32__) || defined(MAC_TCL)) /* *---------------------------------------------------------------------- @@ -1127,7 +2330,10 @@ TestwrapperCmd(clientData, interp, argc, argv) wrapperPtr = TkpGetWrapperWindow(winPtr); if (wrapperPtr != NULL) { - TkpPrintWindowId(interp->result, Tk_WindowId(wrapperPtr)); + char buf[TCL_INTEGER_SPACE]; + + TkpPrintWindowId(buf, Tk_WindowId(wrapperPtr)); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } return TCL_OK; } diff --git a/generic/tkText.c b/generic/tkText.c index 67232fb..ee19f8a 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.c,v 1.2 1998/09/14 18:23:17 stanton Exp $ + * RCS: @(#) $Id: tkText.c,v 1.3 1999/04/16 01:51:23 stanton Exp $ */ #include "default.h" @@ -134,16 +134,6 @@ static Tk_ConfigSpec configSpecs[] = { }; /* - * Tk_Uid's used to represent text states: - */ - -Tk_Uid tkTextCharUid = NULL; -Tk_Uid tkTextDisabledUid = NULL; -Tk_Uid tkTextNoneUid = NULL; -Tk_Uid tkTextNormalUid = NULL; -Tk_Uid tkTextWordUid = NULL; - -/* * Boolean variable indicating whether or not special debugging code * should be executed. */ @@ -232,18 +222,6 @@ Tk_TextCmd(clientData, interp, argc, argv) } /* - * Perform once-only initialization: - */ - - if (tkTextNormalUid == NULL) { - tkTextCharUid = Tk_GetUid("char"); - tkTextDisabledUid = Tk_GetUid("disabled"); - tkTextNoneUid = Tk_GetUid("none"); - tkTextNormalUid = Tk_GetUid("normal"); - tkTextWordUid = Tk_GetUid("word"); - } - - /* * Create the window. */ @@ -265,7 +243,7 @@ Tk_TextCmd(clientData, interp, argc, argv) Tcl_InitHashTable(&textPtr->markTable, TCL_STRING_KEYS); Tcl_InitHashTable(&textPtr->windowTable, TCL_STRING_KEYS); Tcl_InitHashTable(&textPtr->imageTable, TCL_STRING_KEYS); - textPtr->state = tkTextNormalUid; + textPtr->state = Tk_GetUid("normal"); textPtr->border = NULL; textPtr->borderWidth = 0; textPtr->padX = 0; @@ -283,14 +261,14 @@ Tk_TextCmd(clientData, interp, argc, argv) textPtr->spacing3 = 0; textPtr->tabOptionString = NULL; textPtr->tabArrayPtr = NULL; - textPtr->wrapMode = tkTextCharUid; + textPtr->wrapMode = Tk_GetUid("char"); textPtr->width = 0; textPtr->height = 0; textPtr->setGrid = 0; textPtr->prevWidth = Tk_Width(new); textPtr->prevHeight = Tk_Height(new); TkTextCreateDInfo(textPtr); - TkTextMakeIndex(textPtr->tree, 0, 0, &startIndex); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &startIndex); TkTextSetYView(textPtr, &startIndex, 0); textPtr->selTagPtr = NULL; textPtr->selBorder = NULL; @@ -322,7 +300,8 @@ Tk_TextCmd(clientData, interp, argc, argv) */ textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel"); - textPtr->selTagPtr->reliefString = (char *) ckalloc(7); + textPtr->selTagPtr->reliefString = + (char *) ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF)); strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF); textPtr->selTagPtr->relief = TK_RELIEF_RAISED; textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &startIndex); @@ -343,7 +322,7 @@ Tk_TextCmd(clientData, interp, argc, argv) Tk_DestroyWindow(textPtr->tkwin); return TCL_ERROR; } - interp->result = Tk_PathName(textPtr->tkwin); + Tcl_SetResult(interp, Tk_PathName(textPtr->tkwin), TCL_STATIC); return TCL_OK; } @@ -401,7 +380,10 @@ TextWidgetCmd(clientData, interp, argc, argv) goto done; } if (TkTextCharBbox(textPtr, &index1, &x, &y, &width, &height) == 0) { - sprintf(interp->result, "%d %d %d %d", x, y, width, height); + char buf[TCL_INTEGER_SPACE * 4]; + + sprintf(buf, "%d %d %d %d", x, y, width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) && (length >= 2)) { @@ -459,7 +441,7 @@ TextWidgetCmd(clientData, interp, argc, argv) } else { goto compareError; } - interp->result = (value) ? "1" : "0"; + Tcl_SetResult(interp, ((value) ? "1" : "0"), TCL_STATIC); } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) && (length >= 3)) { if (argc == 2) { @@ -481,7 +463,7 @@ TextWidgetCmd(clientData, interp, argc, argv) goto done; } if (argc == 2) { - interp->result = (tkBTreeDebug) ? "1" : "0"; + Tcl_SetResult(interp, ((tkBTreeDebug) ? "1" : "0"), TCL_STATIC); } else { if (Tcl_GetBoolean(interp, argv[2], &tkBTreeDebug) != TCL_OK) { result = TCL_ERROR; @@ -497,7 +479,7 @@ TextWidgetCmd(clientData, interp, argc, argv) result = TCL_ERROR; goto done; } - if (textPtr->state == tkTextNormalUid) { + if (textPtr->state == Tk_GetUid("normal")) { result = DeleteChars(textPtr, argv[2], (argc == 4) ? argv[3] : (char *) NULL); } @@ -517,8 +499,10 @@ TextWidgetCmd(clientData, interp, argc, argv) } if (TkTextDLineInfo(textPtr, &index1, &x, &y, &width, &height, &base) == 0) { - sprintf(interp->result, "%d %d %d %d %d", x, y, width, - height, base); + char buf[TCL_INTEGER_SPACE * 5]; + + sprintf(buf, "%d %d %d %d %d", x, y, width, height, base); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) { if ((argc != 3) && (argc != 4)) { @@ -551,10 +535,10 @@ TextWidgetCmd(clientData, interp, argc, argv) if (index1.linePtr == index2.linePtr) { int last2; - if (index2.charIndex == index1.charIndex) { + if (index2.byteIndex == index1.byteIndex) { break; } - last2 = index2.charIndex - index1.charIndex + offset; + last2 = index2.byteIndex - index1.byteIndex + offset; if (last2 < last) { last = last2; } @@ -566,10 +550,12 @@ TextWidgetCmd(clientData, interp, argc, argv) (char *) NULL); segPtr->body.chars[last] = savedChar; } - TkTextIndexForwChars(&index1, last-offset, &index1); + TkTextIndexForwBytes(&index1, last-offset, &index1); } } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0) && (length >= 3)) { + char buf[200]; + if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " index index\"", @@ -581,7 +567,8 @@ TextWidgetCmd(clientData, interp, argc, argv) result = TCL_ERROR; goto done; } - TkTextPrintIndex(&index1, interp->result); + TkTextPrintIndex(&index1, buf); + Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if ((c == 'i') && (strncmp(argv[1], "insert", length) == 0) && (length >= 3)) { int i, j, numTags; @@ -600,11 +587,11 @@ TextWidgetCmd(clientData, interp, argc, argv) result = TCL_ERROR; goto done; } - if (textPtr->state == tkTextNormalUid) { + if (textPtr->state == Tk_GetUid("normal")) { for (j = 3; j < argc; j += 2) { InsertChars(textPtr, &index1, argv[j]); if (argc > (j+1)) { - TkTextIndexForwChars(&index1, (int) strlen(argv[j]), + TkTextIndexForwBytes(&index1, (int) strlen(argv[j]), &index2); oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags); if (oldTagArrayPtr != NULL) { @@ -745,7 +732,7 @@ DestroyText(memPtr) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message. + * returned, then the interp's result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, @@ -776,20 +763,20 @@ ConfigureText(interp, textPtr, argc, argv, flags) * the geometry and setting the background from a 3-D border. */ - if ((textPtr->state != tkTextNormalUid) - && (textPtr->state != tkTextDisabledUid)) { + if ((textPtr->state != Tk_GetUid("normal")) + && (textPtr->state != Tk_GetUid("disabled"))) { Tcl_AppendResult(interp, "bad state value \"", textPtr->state, "\": must be normal or disabled", (char *) NULL); - textPtr->state = tkTextNormalUid; + textPtr->state = Tk_GetUid("normal"); return TCL_ERROR; } - if ((textPtr->wrapMode != tkTextCharUid) - && (textPtr->wrapMode != tkTextNoneUid) - && (textPtr->wrapMode != tkTextWordUid)) { + if ((textPtr->wrapMode != Tk_GetUid("char")) + && (textPtr->wrapMode != Tk_GetUid("none")) + && (textPtr->wrapMode != Tk_GetUid("word"))) { Tcl_AppendResult(interp, "bad wrap mode \"", textPtr->wrapMode, "\": must be char, none, or word", (char *) NULL); - textPtr->wrapMode = tkTextCharUid; + textPtr->wrapMode = Tk_GetUid("char"); return TCL_ERROR; } @@ -882,8 +869,8 @@ ConfigureText(interp, textPtr, argc, argv, flags) TkTextSearch search; TkTextIndex first, last; - TkTextMakeIndex(textPtr->tree, 0, 0, &first); - TkTextMakeIndex(textPtr->tree, + TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &last); TkBTreeStartSearch(&first, &last, textPtr->selTagPtr, &search); if (TkBTreeCharTagged(&first, textPtr->selTagPtr) @@ -1114,7 +1101,7 @@ InsertChars(textPtr, indexPtr, string) lineIndex = TkBTreeLineIndex(indexPtr->linePtr); if (lineIndex == TkBTreeNumLines(textPtr->tree)) { lineIndex--; - TkTextMakeIndex(textPtr->tree, lineIndex, 1000000, indexPtr); + TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, indexPtr); } /* @@ -1127,16 +1114,16 @@ InsertChars(textPtr, indexPtr, string) resetView = offset = 0; if (indexPtr->linePtr == textPtr->topIndex.linePtr) { resetView = 1; - offset = textPtr->topIndex.charIndex; - if (offset > indexPtr->charIndex) { + offset = textPtr->topIndex.byteIndex; + if (offset > indexPtr->byteIndex) { offset += strlen(string); } } TkTextChanged(textPtr, indexPtr, indexPtr); TkBTreeInsertChars(indexPtr, string); if (resetView) { - TkTextMakeIndex(textPtr->tree, lineIndex, 0, &newTop); - TkTextIndexForwChars(&newTop, offset, &newTop); + TkTextMakeByteIndex(textPtr->tree, lineIndex, 0, &newTop); + TkTextIndexForwBytes(&newTop, offset, &newTop); TkTextSetYView(textPtr, &newTop, 0); } @@ -1175,7 +1162,7 @@ DeleteChars(textPtr, index1String, index2String) * delete the one character given by * index1String. */ { - int line1, line2, line, charIndex, resetView; + int line1, line2, line, byteIndex, resetView; TkTextIndex index1, index2; /* @@ -1226,7 +1213,7 @@ DeleteChars(textPtr, index1String, index2String) oldIndex2 = index2; TkTextIndexBackChars(&oldIndex2, 1, &index2); line2--; - if ((index1.charIndex == 0) && (line1 != 0)) { + if ((index1.byteIndex == 0) && (line1 != 0)) { TkTextIndexBackChars(&index1, 1, &index1); line1--; } @@ -1249,7 +1236,9 @@ DeleteChars(textPtr, index1String, index2String) */ TkTextChanged(textPtr, &index1, &index2); - resetView = line = charIndex = 0; + resetView = 0; + line = 0; + byteIndex = 0; if (TkTextIndexCmp(&index2, &textPtr->topIndex) >= 0) { if (TkTextIndexCmp(&index1, &textPtr->topIndex) <= 0) { /* @@ -1259,7 +1248,7 @@ DeleteChars(textPtr, index1String, index2String) resetView = 1; line = line1; - charIndex = index1.charIndex; + byteIndex = index1.byteIndex; } else if (index1.linePtr == textPtr->topIndex.linePtr) { /* * Deletion range starts on top line but after topIndex. @@ -1268,7 +1257,7 @@ DeleteChars(textPtr, index1String, index2String) resetView = 1; line = line1; - charIndex = textPtr->topIndex.charIndex; + byteIndex = textPtr->topIndex.byteIndex; } } else if (index2.linePtr == textPtr->topIndex.linePtr) { /* @@ -1279,16 +1268,16 @@ DeleteChars(textPtr, index1String, index2String) resetView = 1; line = line2; - charIndex = textPtr->topIndex.charIndex; + byteIndex = textPtr->topIndex.byteIndex; if (index1.linePtr != index2.linePtr) { - charIndex -= index2.charIndex; + byteIndex -= index2.byteIndex; } else { - charIndex -= (index2.charIndex - index1.charIndex); + byteIndex -= (index2.byteIndex - index1.byteIndex); } } TkBTreeDeleteChars(&index1, &index2); if (resetView) { - TkTextMakeIndex(textPtr->tree, line, charIndex, &index1); + TkTextMakeByteIndex(textPtr->tree, line, byteIndex, &index1); TkTextSetYView(textPtr, &index1, 0); } @@ -1352,12 +1341,12 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) */ if (offset == 0) { - TkTextMakeIndex(textPtr->tree, 0, 0, &textPtr->selIndex); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &textPtr->selIndex); textPtr->abortSelections = 0; } else if (textPtr->abortSelections) { return 0; } - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &eof); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &eof); TkBTreeStartSearch(&textPtr->selIndex, &eof, textPtr->selTagPtr, &search); if (!TkBTreeCharTagged(&textPtr->selIndex, textPtr->selTagPtr)) { if (!TkBTreeNextTag(&search)) { @@ -1404,8 +1393,8 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) if (textPtr->selIndex.linePtr == search.curIndex.linePtr) { int leftInRange; - leftInRange = search.curIndex.charIndex - - textPtr->selIndex.charIndex; + leftInRange = search.curIndex.byteIndex + - textPtr->selIndex.byteIndex; if (leftInRange < chunkSize) { chunkSize = leftInRange; if (chunkSize <= 0) { @@ -1420,7 +1409,7 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) maxBytes -= chunkSize; count += chunkSize; } - TkTextIndexForwChars(&textPtr->selIndex, chunkSize, + TkTextIndexForwBytes(&textPtr->selIndex, chunkSize, &textPtr->selIndex); } @@ -1477,8 +1466,8 @@ TkTextLostSelection(clientData) * just remove the "sel" tag from everything in the widget. */ - TkTextMakeIndex(textPtr->tree, 0, 0, &start); - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &end); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &start); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &end); TkTextRedrawTag(textPtr, &start, &end, textPtr->selTagPtr, 1); TkBTreeTag(&start, &end, textPtr->selTagPtr, 0); #endif @@ -1556,8 +1545,8 @@ TextSearchCmd(textPtr, interp, argc, argv) { int backwards, exact, c, i, argsLeft, noCase, leftToScan; size_t length; - int numLines, startingLine, startingChar, lineNum, firstChar, lastChar; - int code, matchLength, matchChar, passes, stopLine, searchWholeText; + int numLines, startingLine, startingByte, lineNum, firstByte, lastByte; + int code, matchLength, matchByte, passes, stopLine, searchWholeText; int patLength; char *arg, *pattern, *varName, *p, *startOfLine; char buffer[20]; @@ -1594,7 +1583,8 @@ TextSearchCmd(textPtr, interp, argc, argv) backwards = 1; } else if ((c == 'c') && (strncmp(argv[i], "-count", length) == 0)) { if (i >= (argc-1)) { - interp->result = "no value given for \"-count\" option"; + Tcl_SetResult(interp, "no value given for \"-count\" option", + TCL_STATIC); return TCL_ERROR; } i++; @@ -1631,11 +1621,7 @@ TextSearchCmd(textPtr, interp, argc, argv) Tcl_DStringInit(&patDString); Tcl_DStringAppend(&patDString, pattern, -1); pattern = Tcl_DStringValue(&patDString); - for (p = pattern; *p != 0; p++) { - if (isupper(UCHAR(*p))) { - *p = tolower(UCHAR(*p)); - } - } + Tcl_UtfToLower(pattern); } if (TkTextGetIndex(interp, textPtr, argv[i+1], &index) != TCL_OK) { @@ -1643,15 +1629,15 @@ TextSearchCmd(textPtr, interp, argc, argv) } numLines = TkBTreeNumLines(textPtr->tree); startingLine = TkBTreeLineIndex(index.linePtr); - startingChar = index.charIndex; + startingByte = index.byteIndex; if (startingLine >= numLines) { if (backwards) { startingLine = TkBTreeNumLines(textPtr->tree) - 1; - startingChar = TkBTreeCharsInLine(TkBTreeFindLine(textPtr->tree, + startingByte = TkBTreeBytesInLine(TkBTreeFindLine(textPtr->tree, startingLine)); } else { startingLine = 0; - startingChar = 0; + startingByte = 0; } } if (argsLeft == 1) { @@ -1719,11 +1705,8 @@ TextSearchCmd(textPtr, interp, argc, argv) */ if (noCase) { - for (p = Tcl_DStringValue(&line); *p != 0; p++) { - if (isupper(UCHAR(*p))) { - *p = tolower(UCHAR(*p)); - } - } + Tcl_DStringSetLength(&line, + Tcl_UtfToLower(Tcl_DStringValue(&line))); } /* @@ -1732,9 +1715,9 @@ TextSearchCmd(textPtr, interp, argc, argv) * in the line. */ - matchChar = -1; - firstChar = 0; - lastChar = INT_MAX; + matchByte = -1; + firstByte = 0; + lastByte = INT_MAX; if (lineNum == startingLine) { int indexInDString; @@ -1748,8 +1731,8 @@ TextSearchCmd(textPtr, interp, argc, argv) * character. */ - indexInDString = startingChar; - for (segPtr = linePtr->segPtr, leftToScan = startingChar; + indexInDString = startingByte; + for (segPtr = linePtr->segPtr, leftToScan = startingByte; leftToScan > 0; segPtr = segPtr->nextPtr) { if (segPtr->typePtr != &tkTextCharType) { indexInDString -= segPtr->size; @@ -1763,8 +1746,8 @@ TextSearchCmd(textPtr, interp, argc, argv) * Only use the last part of the line. */ - firstChar = indexInDString; - if (firstChar >= Tcl_DStringLength(&line)) { + firstByte = indexInDString; + if (firstByte >= Tcl_DStringLength(&line)) { goto nextLine; } } else { @@ -1772,13 +1755,16 @@ TextSearchCmd(textPtr, interp, argc, argv) * Use only the first part of the line. */ - lastChar = indexInDString; + lastByte = indexInDString; } } do { int thisLength; + Tcl_UniChar ch; + if (exact) { - p = strstr(startOfLine + firstChar, pattern); + p = strstr(startOfLine + firstByte, /* INTL: Native. */ + pattern); if (p == NULL) { break; } @@ -1789,7 +1775,7 @@ TextSearchCmd(textPtr, interp, argc, argv) int match; match = Tcl_RegExpExec(interp, regexp, - startOfLine + firstChar, startOfLine); + startOfLine + firstByte, startOfLine); if (match < 0) { code = TCL_ERROR; goto done; @@ -1801,12 +1787,12 @@ TextSearchCmd(textPtr, interp, argc, argv) i = start - startOfLine; thisLength = end - start; } - if (i >= lastChar) { + if (i >= lastByte) { break; } - matchChar = i; + matchByte = i; matchLength = thisLength; - firstChar = matchChar+1; + firstByte += Tcl_UtfToUniChar(startOfLine + matchByte, &ch); } while (backwards); /* @@ -1815,7 +1801,16 @@ TextSearchCmd(textPtr, interp, argc, argv) * specified. */ - if (matchChar >= 0) { + if (matchByte >= 0) { + int numChars; + + /* + * Convert the byte length to a character count. + */ + + numChars = Tcl_NumUtfChars(startOfLine + matchByte, + matchLength); + /* * The index information returned by the regular expression * parser only considers textual information: it doesn't @@ -1824,10 +1819,10 @@ TextSearchCmd(textPtr, interp, argc, argv) * matchChar and matchCount. */ - for (segPtr = linePtr->segPtr, leftToScan = matchChar; + for (segPtr = linePtr->segPtr, leftToScan = matchByte; leftToScan >= 0; segPtr = segPtr->nextPtr) { if (segPtr->typePtr != &tkTextCharType) { - matchChar += segPtr->size; + matchByte += segPtr->size; continue; } leftToScan -= segPtr->size; @@ -1835,12 +1830,12 @@ TextSearchCmd(textPtr, interp, argc, argv) for (leftToScan += matchLength; leftToScan > 0; segPtr = segPtr->nextPtr) { if (segPtr->typePtr != &tkTextCharType) { - matchLength += segPtr->size; + numChars += segPtr->size; continue; } leftToScan -= segPtr->size; } - TkTextMakeIndex(textPtr->tree, lineNum, matchChar, &index); + TkTextMakeByteIndex(textPtr->tree, lineNum, matchByte, &index); if (!searchWholeText) { if (!backwards && (TkTextIndexCmp(&index, &stopIndex) >= 0)) { goto done; @@ -1850,14 +1845,15 @@ TextSearchCmd(textPtr, interp, argc, argv) } } if (varName != NULL) { - sprintf(buffer, "%d", matchLength); + sprintf(buffer, "%d", numChars); if (Tcl_SetVar(interp, varName, buffer, TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; goto done; } } - TkTextPrintIndex(&index, interp->result); + TkTextPrintIndex(&index, buffer); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); goto done; } @@ -1906,7 +1902,7 @@ TextSearchCmd(textPtr, interp, argc, argv) * The return value is a pointer to a malloc'ed structure holding * parsed information about the tab stops. If an error occurred * then the return value is NULL and an error message is left in - * interp->result. + * the interp's result. * * Side effects: * Memory is allocated for the structure that is returned. It is @@ -1928,6 +1924,7 @@ TkTextGetTabs(interp, tkwin, string) char **argv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; + Tcl_UniChar ch; if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { return NULL; @@ -1970,11 +1967,12 @@ TkTextGetTabs(interp, tkwin, string) if ((i+1) == argc) { continue; } - c = UCHAR(argv[i+1][0]); - if (!isalpha(c)) { + Tcl_UtfToUniChar(argv[i+1], &ch); + if (!Tcl_UniCharIsAlpha(ch)) { continue; } i += 1; + c = argv[i][0]; if ((c == 'l') && (strncmp(argv[i], "left", strlen(argv[i])) == 0)) { tabPtr->alignment = LEFT; @@ -2104,10 +2102,10 @@ TextDumpCmd(textPtr, interp, argc, argv) } if (index1.linePtr == index2.linePtr) { DumpLine(interp, textPtr, what, index1.linePtr, - index1.charIndex, index2.charIndex, lineno, command); + index1.byteIndex, index2.byteIndex, lineno, command); } else { DumpLine(interp, textPtr, what, index1.linePtr, - index1.charIndex, 32000000, lineno, command); + index1.byteIndex, 32000000, lineno, command); linePtr = index1.linePtr; while ((linePtr = TkBTreeNextLine(linePtr)) != (TkTextLine *)NULL) { lineno++; @@ -2118,14 +2116,14 @@ TextDumpCmd(textPtr, interp, argc, argv) lineno, command); } DumpLine(interp, textPtr, what, index2.linePtr, 0, - index2.charIndex, lineno, command); + index2.byteIndex, lineno, command); } /* * Special case to get the leftovers hiding at the end mark. */ if (atEnd) { DumpLine(interp, textPtr, what & ~TK_DUMP_TEXT, index2.linePtr, - 0, 1, lineno, command); + 0, 1, lineno, command); } return TCL_OK; @@ -2143,12 +2141,12 @@ TextDumpCmd(textPtr, interp, argc, argv) * None, but see DumpSegment. */ static void -DumpLine(interp, textPtr, what, linePtr, start, end, lineno, command) +DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command) Tcl_Interp *interp; TkText *textPtr; int what; /* bit flags to select segment types */ TkTextLine *linePtr; /* The current line */ - int start, end; /* Character range to dump */ + int startByte, endByte; /* Byte range to dump */ int lineno; /* Line number for indices dump */ char *command; /* Script to apply to the segment */ { @@ -2163,25 +2161,25 @@ DumpLine(interp, textPtr, what, linePtr, start, end, lineno, command) * window */ for (offset = 0, segPtr = linePtr->segPtr ; - (offset < end) && (segPtr != (TkTextSegment *)NULL) ; + (offset < endByte) && (segPtr != (TkTextSegment *)NULL) ; offset += segPtr->size, segPtr = segPtr->nextPtr) { if ((what & TK_DUMP_TEXT) && (segPtr->typePtr == &tkTextCharType) && - (offset + segPtr->size > start)) { + (offset + segPtr->size > startByte)) { char savedChar; /* Last char used in the seg */ int last = segPtr->size; /* Index of savedChar */ int first = 0; /* Index of first char in seg */ - if (offset + segPtr->size > end) { - last = end - offset; + if (offset + segPtr->size > endByte) { + last = endByte - offset; } - if (start > offset) { - first = start - offset; + if (startByte > offset) { + first = startByte - offset; } savedChar = segPtr->body.chars[last]; segPtr->body.chars[last] = '\0'; DumpSegment(interp, "text", segPtr->body.chars + first, command, lineno, offset + first, what); segPtr->body.chars[last] = savedChar; - } else if ((offset >= start)) { + } else if ((offset >= startByte)) { if ((what & TK_DUMP_MARK) && (segPtr->typePtr->name[0] == 'm')) { TkTextMark *markPtr = (TkTextMark *)&segPtr->body; char *name = Tcl_GetHashKey(&textPtr->markTable, markPtr->hPtr); @@ -2237,11 +2235,11 @@ DumpSegment(interp, key, value, command, lineno, offset, what) char *value; /* Segment value */ char *command; /* Script callback */ int lineno; /* Line number for indices dump */ - int offset; /* Character position */ + int offset; /* Byte position */ int what; /* Look for TK_DUMP_INDEX bit */ { char buffer[30]; - sprintf(buffer, "%d.%d", lineno, offset); + sprintf(buffer, "%d.%d", lineno, offset); if (command == (char *) NULL) { Tcl_AppendElement(interp, key); Tcl_AppendElement(interp, value); diff --git a/generic/tkText.h b/generic/tkText.h index ad30c99..68cfff5 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.h,v 1.2 1998/09/14 18:23:18 stanton Exp $ + * RCS: @(#) $Id: tkText.h,v 1.3 1999/04/16 01:51:23 stanton Exp $ */ #ifndef _TKTEXT @@ -176,7 +176,7 @@ typedef struct TkTextIndex { TkTextBTree tree; /* Tree containing desired position. */ TkTextLine *linePtr; /* Pointer to line containing position * of interest. */ - int charIndex; /* Index within line of desired + int byteIndex; /* Index within line of desired * character (0 means first one). */ } TkTextIndex; @@ -241,7 +241,7 @@ struct TkTextDispChunk { * a given x-location. */ Tk_ChunkBboxProc *bboxProc; /* Procedure to find bounding box * of character in chunk. */ - int numChars; /* Number of characters that will be + int numBytes; /* Number of bytes that will be * displayed in the chunk. */ int minAscent; /* Minimum space above the baseline * needed by this chunk. */ @@ -256,7 +256,7 @@ struct TkTextDispChunk { * of line. */ int breakIndex; /* Index within chunk of last * acceptable position for a line - * (break just before this character). + * (break just before this byte index). * <= 0 means don't break during or * immediately after this chunk. */ ClientData clientData; /* Additional information for use @@ -470,8 +470,8 @@ typedef struct TkText { * image segment doesn't yet have an * associated image, there is no entry for * it here. */ - Tk_Uid state; /* Normal or disabled. Text is read-only - * when disabled. */ + Tk_Uid state; /* Either normal or disabled. A text + * widget is read-only when disabled. */ /* * Default information for displaying (may be overridden by tags @@ -730,6 +730,7 @@ extern int TkBTreeCharTagged _ANSI_ARGS_((TkTextIndex *indexPtr, TkTextTag *tagPtr)); extern void TkBTreeCheck _ANSI_ARGS_((TkTextBTree tree)); extern int TkBTreeCharsInLine _ANSI_ARGS_((TkTextLine *linePtr)); +extern int TkBTreeBytesInLine _ANSI_ARGS_((TkTextLine *linePtr)); extern TkTextBTree TkBTreeCreate _ANSI_ARGS_((TkText *textPtr)); extern void TkBTreeDestroy _ANSI_ARGS_((TkTextBTree tree)); extern void TkBTreeDeleteChars _ANSI_ARGS_((TkTextIndex *index1Ptr, @@ -784,23 +785,35 @@ extern int TkTextGetIndex _ANSI_ARGS_((Tcl_Interp *interp, TkTextIndex *indexPtr)); extern TkTextTabArray * TkTextGetTabs _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, char *string)); -extern void TkTextIndexBackChars _ANSI_ARGS_((TkTextIndex *srcPtr, - int count, TkTextIndex *dstPtr)); -extern int TkTextIndexCmp _ANSI_ARGS_((TkTextIndex *index1Ptr, - TkTextIndex *index2Ptr)); -extern void TkTextIndexForwChars _ANSI_ARGS_((TkTextIndex *srcPtr, - int count, TkTextIndex *dstPtr)); -extern TkTextSegment * TkTextIndexToSeg _ANSI_ARGS_((TkTextIndex *indexPtr, - int *offsetPtr)); +extern void TkTextIndexBackBytes _ANSI_ARGS_(( + CONST TkTextIndex *srcPtr, int count, + TkTextIndex *dstPtr)); +extern void TkTextIndexBackChars _ANSI_ARGS_(( + CONST TkTextIndex *srcPtr, int count, + TkTextIndex *dstPtr)); +extern int TkTextIndexCmp _ANSI_ARGS_(( + CONST TkTextIndex *index1Ptr, + CONST TkTextIndex *index2Ptr)); +extern void TkTextIndexForwBytes _ANSI_ARGS_(( + CONST TkTextIndex *srcPtr, int count, + TkTextIndex *dstPtr)); +extern void TkTextIndexForwChars _ANSI_ARGS_(( + CONST TkTextIndex *srcPtr, int count, + TkTextIndex *dstPtr)); +extern TkTextSegment * TkTextIndexToSeg _ANSI_ARGS_(( + CONST TkTextIndex *indexPtr, int *offsetPtr)); extern void TkTextInsertDisplayProc _ANSI_ARGS_(( TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY)); extern void TkTextLostSelection _ANSI_ARGS_(( ClientData clientData)); -extern TkTextIndex * TkTextMakeIndex _ANSI_ARGS_((TkTextBTree tree, +extern TkTextIndex * TkTextMakeCharIndex _ANSI_ARGS_((TkTextBTree tree, int lineIndex, int charIndex, TkTextIndex *indexPtr)); +extern TkTextIndex * TkTextMakeByteIndex _ANSI_ARGS_((TkTextBTree tree, + int lineIndex, int byteIndex, + TkTextIndex *indexPtr)); extern int TkTextMarkCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); extern int TkTextMarkNameToIndex _ANSI_ARGS_((TkText *textPtr, @@ -812,8 +825,8 @@ extern void TkTextPickCurrent _ANSI_ARGS_((TkText *textPtr, XEvent *eventPtr)); extern void TkTextPixelIndex _ANSI_ARGS_((TkText *textPtr, int x, int y, TkTextIndex *indexPtr)); -extern void TkTextPrintIndex _ANSI_ARGS_((TkTextIndex *indexPtr, - char *string)); +extern void TkTextPrintIndex _ANSI_ARGS_(( + CONST TkTextIndex *indexPtr, char *string)); extern void TkTextRedrawRegion _ANSI_ARGS_((TkText *textPtr, int x, int y, int width, int height)); extern void TkTextRedrawTag _ANSI_ARGS_((TkText *textPtr, @@ -824,8 +837,9 @@ extern int TkTextScanCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); extern int TkTextSeeCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); -extern int TkTextSegToOffset _ANSI_ARGS_((TkTextSegment *segPtr, - TkTextLine *linePtr)); +extern int TkTextSegToOffset _ANSI_ARGS_(( + CONST TkTextSegment *segPtr, + CONST TkTextLine *linePtr)); extern TkTextSegment * TkTextSetMark _ANSI_ARGS_((TkText *textPtr, char *name, TkTextIndex *indexPtr)); extern void TkTextSetYView _ANSI_ARGS_((TkText *textPtr, diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index 44b021f..6f7beb6 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.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: tkTextBTree.c,v 1.2 1998/09/14 18:23:18 stanton Exp $ + * RCS: @(#) $Id: tkTextBTree.c,v 1.3 1999/04/16 01:51:23 stanton Exp $ */ #include "tkInt.h" @@ -535,7 +535,7 @@ SplitSeg(indexPtr) TkTextSegment *prevPtr, *segPtr; int count; - for (count = indexPtr->charIndex, prevPtr = NULL, + for (count = indexPtr->byteIndex, prevPtr = NULL, segPtr = indexPtr->linePtr->segPtr; segPtr != NULL; count -= segPtr->size, prevPtr = segPtr, segPtr = segPtr->nextPtr) { if (segPtr->size > count) { @@ -1530,7 +1530,7 @@ FindTagStart(tree, tagPtr, indexPtr) */ indexPtr->tree = tree; indexPtr->linePtr = linePtr; - indexPtr->charIndex = offset; + indexPtr->byteIndex = offset; return segPtr; } } @@ -1619,7 +1619,7 @@ FindTagEnd(tree, tagPtr, indexPtr) } indexPtr->tree = tree; indexPtr->linePtr = lastLinePtr; - indexPtr->charIndex = lastoffset2; + indexPtr->byteIndex = lastoffset2; return last2SegPtr; } @@ -1694,7 +1694,7 @@ TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr) searchPtr->curIndex = *index1Ptr; searchPtr->segPtr = NULL; searchPtr->nextPtr = TkTextIndexToSeg(index1Ptr, &offset); - searchPtr->curIndex.charIndex -= offset; + searchPtr->curIndex.byteIndex -= offset; } searchPtr->lastPtr = TkTextIndexToSeg(index2Ptr, (int *) NULL); searchPtr->tagPtr = tagPtr; @@ -1709,9 +1709,9 @@ TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, searchPtr) * the range, unless the range is artificially moved up to index0. */ if (((index1Ptr == &index0) && - (index1Ptr->charIndex > index2Ptr->charIndex)) || + (index1Ptr->byteIndex > index2Ptr->byteIndex)) || ((index1Ptr != &index0) && - (index1Ptr->charIndex >= index2Ptr->charIndex))) { + (index1Ptr->byteIndex >= index2Ptr->byteIndex))) { searchPtr->linesLeft = 0; } } @@ -1793,7 +1793,7 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr) } searchPtr->segPtr = NULL; searchPtr->nextPtr = TkTextIndexToSeg(&searchPtr->curIndex, &offset); - searchPtr->curIndex.charIndex -= offset; + searchPtr->curIndex.byteIndex -= offset; /* * Adjust the end of the search so it does find toggles that are right @@ -1801,7 +1801,7 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr) */ if ((TkBTreeLineIndex(index2Ptr->linePtr) == 0) && - (index2Ptr->charIndex == 0)) { + (index2Ptr->byteIndex == 0)) { backOne = *index2Ptr; searchPtr->lastPtr = NULL; /* Signals special case for 1.0 */ } else { @@ -1819,7 +1819,7 @@ TkBTreeStartSearchBack(index1Ptr, index2Ptr, tagPtr, searchPtr) * first. */ - if (index1Ptr->charIndex <= backOne.charIndex) { + if (index1Ptr->byteIndex <= backOne.byteIndex) { searchPtr->linesLeft = 0; } } @@ -1889,7 +1889,7 @@ TkBTreeNextTag(searchPtr) searchPtr->tagPtr = segPtr->body.toggle.tagPtr; return 1; } - searchPtr->curIndex.charIndex += segPtr->size; + searchPtr->curIndex.byteIndex += segPtr->size; } /* @@ -1906,7 +1906,7 @@ TkBTreeNextTag(searchPtr) } if (searchPtr->curIndex.linePtr != NULL) { segPtr = searchPtr->curIndex.linePtr->segPtr; - searchPtr->curIndex.charIndex = 0; + searchPtr->curIndex.byteIndex = 0; continue; } if (nodePtr == searchPtr->tagPtr->tagRootPtr) { @@ -1972,7 +1972,7 @@ TkBTreeNextTag(searchPtr) */ searchPtr->curIndex.linePtr = nodePtr->children.linePtr; - searchPtr->curIndex.charIndex = 0; + searchPtr->curIndex.byteIndex = 0; segPtr = searchPtr->curIndex.linePtr->segPtr; if (searchPtr->linesLeft <= 0) { goto searchOver; @@ -2022,7 +2022,7 @@ TkBTreePrevTag(searchPtr) register TkTextLine *linePtr, *prevLinePtr; register Node *nodePtr, *node2Ptr, *prevNodePtr; register Summary *summaryPtr; - int charIndex; + int byteIndex; int pastLast; /* Saw last marker during scan */ int linesSkipped; @@ -2041,7 +2041,7 @@ TkBTreePrevTag(searchPtr) /* * Check for the last toggle before the current segment on this line. */ - charIndex = 0; + byteIndex = 0; if (searchPtr->lastPtr == NULL) { /* * Search back to the very beginning, so pastLast is irrelevent. @@ -2058,13 +2058,13 @@ TkBTreePrevTag(searchPtr) && (searchPtr->allTags || (segPtr->body.toggle.tagPtr == searchPtr->tagPtr))) { prevPtr = segPtr; - searchPtr->curIndex.charIndex = charIndex; + searchPtr->curIndex.byteIndex = byteIndex; } if (segPtr == searchPtr->lastPtr) { prevPtr = NULL; /* Segments earlier than last don't count */ pastLast = 1; } - charIndex += segPtr->size; + byteIndex += segPtr->size; } if (prevPtr != NULL) { if (searchPtr->linesLeft == 1 && !pastLast) { @@ -2191,7 +2191,7 @@ TkBTreePrevTag(searchPtr) /* empty loop body */ ; } searchPtr->curIndex.linePtr = prevLinePtr; - searchPtr->curIndex.charIndex = 0; + searchPtr->curIndex.byteIndex = 0; if (searchPtr->linesLeft <= 0) { goto searchOver; } @@ -2241,7 +2241,7 @@ TkBTreeCharTagged(indexPtr, tagPtr) toggleSegPtr = NULL; for (index = 0, segPtr = indexPtr->linePtr->segPtr; - (index + segPtr->size) <= indexPtr->charIndex; + (index + segPtr->size) <= indexPtr->byteIndex; index += segPtr->size, segPtr = segPtr->nextPtr) { if (((segPtr->typePtr == &tkTextToggleOnType) || (segPtr->typePtr == &tkTextToggleOffType)) @@ -2360,7 +2360,7 @@ TkBTreeGetTags(indexPtr, numTagsPtr) */ for (index = 0, segPtr = indexPtr->linePtr->segPtr; - (index + segPtr->size) <= indexPtr->charIndex; + (index + segPtr->size) <= indexPtr->byteIndex; index += segPtr->size, segPtr = segPtr->nextPtr) { if ((segPtr->typePtr == &tkTextToggleOnType) || (segPtr->typePtr == &tkTextToggleOffType)) { @@ -3588,6 +3588,25 @@ TkBTreeCharsInLine(linePtr) count = 0; for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { + if (segPtr->typePtr == &tkTextCharType) { + count += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size); + } else { + count += segPtr->size; + } + } + return count; +} + +int +TkBTreeBytesInLine(linePtr) + TkTextLine *linePtr; /* Line whose characters should be + * counted. */ +{ + TkTextSegment *segPtr; + int count; + + count = 0; + for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { count += segPtr->size; } return count; diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 8cbdd27..d1f05fa 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.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: tkTextDisp.c,v 1.3 1999/03/10 07:04:44 stanton Exp $ + * RCS: @(#) $Id: tkTextDisp.c,v 1.4 1999/04/16 01:51:23 stanton Exp $ */ #include "tkPort.h" @@ -60,8 +60,7 @@ typedef struct StyleValues { int underline; /* Non-zero means draw underline underneath * text. */ Tk_Uid wrapMode; /* How to handle wrap-around for this tag. - * One of tkTextCharUid, tkTextNoneUid, - * or tkTextWordUid. */ + * One of char, none, or text. */ } StyleValues; /* @@ -102,7 +101,7 @@ typedef struct TextStyle { typedef struct DLine { TkTextIndex index; /* Identifies first character in text * that is displayed on this line. */ - int count; /* Number of characters accounted for by this + int byteCount; /* Number of bytes accounted for by this * display line, including a trailing space * or newline that isn't actually displayed. */ int y; /* Y-position at which line is supposed to @@ -203,7 +202,7 @@ typedef struct TextDInfo { * Information used for scrolling: */ - int newCharOffset; /* Desired x scroll position, measured as the + int newByteOffset; /* Desired x scroll position, measured as the * number of average-size characters off-screen * to the left for a line with no left * margin. */ @@ -226,8 +225,9 @@ typedef struct TextDInfo { * The following information is used to implement scanning: */ - int scanMarkChar; /* Character that was at the left edge of - * the window when the scan started. */ + int scanMarkIndex; /* Byte index of character that was at the + * left edge of the window when the scan + * started. */ int scanMarkX; /* X-position of mouse at time scan started. */ int scanTotalScroll; /* Total scrolling (in screen lines) that has * occurred since scanMarkY was set. */ @@ -258,9 +258,9 @@ typedef struct TextDInfo { */ typedef struct CharInfo { - int numChars; /* Number of characters to display. */ - char chars[4]; /* Characters to display. Actual size - * will be numChars, not 4. THIS MUST BE + int numBytes; /* Number of bytes to display. */ + char chars[4]; /* UTF characters to display. Actual size + * will be numBytes, not 4. THIS MUST BE * THE LAST FIELD IN THE STRUCTURE. */ } CharInfo; @@ -335,7 +335,7 @@ static void GetYView _ANSI_ARGS_((Tcl_Interp *interp, static DLine * LayoutDLine _ANSI_ARGS_((TkText *textPtr, TkTextIndex *indexPtr)); static int MeasureChars _ANSI_ARGS_((Tk_Font tkfont, - CONST char *source, int maxChars, int startX, + CONST char *source, int maxBytes, int startX, int maxX, int tabOrigin, int *nextXPtr)); static void MeasureUp _ANSI_ARGS_((TkText *textPtr, TkTextIndex *srcPtr, int distance, @@ -385,14 +385,14 @@ TkTextCreateDInfo(textPtr) dInfoPtr->scrollGC = Tk_GetGC(textPtr->tkwin, GCGraphicsExposures, &gcValues); dInfoPtr->topOfEof = 0; - dInfoPtr->newCharOffset = 0; + dInfoPtr->newByteOffset = 0; dInfoPtr->curPixelOffset = 0; dInfoPtr->maxLength = 0; dInfoPtr->xScrollFirst = -1; dInfoPtr->xScrollLast = -1; dInfoPtr->yScrollFirst = -1; dInfoPtr->yScrollLast = -1; - dInfoPtr->scanMarkChar = 0; + dInfoPtr->scanMarkIndex = 0; dInfoPtr->scanMarkX = 0; dInfoPtr->scanTotalScroll = 0; dInfoPtr->scanMarkY = 0; @@ -743,12 +743,14 @@ LayoutDLine(textPtr, indexPtr) * point, if any. */ TkTextIndex breakIndex; /* Index of first character in * breakChunkPtr. */ - int breakCharOffset; /* Character within breakChunkPtr just - * to right of best break point. */ + int breakByteOffset; /* Byte offset of character within + * breakChunkPtr just to right of best + * break point. */ int noCharsYet; /* Non-zero means that no characters * have been placed on the line yet. */ int justify; /* How to justify line: taken from - * style for first character in line. */ + * style for the first character in + * line. */ int jIndent; /* Additional indentation (beyond * margins) due to justification. */ int rMargin; /* Right margin width for line. */ @@ -762,17 +764,18 @@ LayoutDLine(textPtr, indexPtr) * contains a tab. */ TkTextDispChunk *tabChunkPtr; /* Pointer to the chunk containing * the previous tab stop. */ - int maxChars; /* Maximum number of characters to + int maxBytes; /* Maximum number of bytes to * include in this chunk. */ - TkTextTabArray *tabArrayPtr; /* Tab stops for line; taken from - * style for first character on line. */ + TkTextTabArray *tabArrayPtr; /* Tab stops for line; taken from + * style for the first character on + * line. */ int tabSize; /* Number of pixels consumed by current * tab stop. */ TkTextDispChunk *lastCharChunkPtr; /* Pointer to last chunk in display - * lines with numChars > 0. Used to + * lines with numBytes > 0. Used to * drop 0-sized chunks from the end * of the line. */ - int offset, ascent, descent, code; + int byteOffset, ascent, descent, code; StyleValues *sValuePtr; /* @@ -781,7 +784,7 @@ LayoutDLine(textPtr, indexPtr) dlPtr = (DLine *) ckalloc(sizeof(DLine)); dlPtr->index = *indexPtr; - dlPtr->count = 0; + dlPtr->byteCount = 0; dlPtr->y = 0; dlPtr->oldY = -1; dlPtr->height = 0; @@ -802,13 +805,13 @@ LayoutDLine(textPtr, indexPtr) chunkPtr = NULL; noCharsYet = 1; breakChunkPtr = NULL; - breakCharOffset = 0; + breakByteOffset = 0; justify = TK_JUSTIFY_LEFT; tabIndex = -1; tabChunkPtr = NULL; tabArrayPtr = NULL; rMargin = 0; - wrapMode = tkTextCharUid; + wrapMode = Tk_GetUid("char"); tabSize = 0; lastCharChunkPtr = NULL; @@ -818,16 +821,16 @@ LayoutDLine(textPtr, indexPtr) * with zero size (such as the insertion cursor's mark). */ - for (offset = curIndex.charIndex, segPtr = curIndex.linePtr->segPtr; - (offset > 0) && (offset >= segPtr->size); - offset -= segPtr->size, segPtr = segPtr->nextPtr) { + for (byteOffset = curIndex.byteIndex, segPtr = curIndex.linePtr->segPtr; + (byteOffset > 0) && (byteOffset >= segPtr->size); + byteOffset -= segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body. */ } while (segPtr != NULL) { if (segPtr->typePtr->layoutProc == NULL) { segPtr = segPtr->nextPtr; - offset = 0; + byteOffset = 0; continue; } if (chunkPtr == NULL) { @@ -847,11 +850,11 @@ LayoutDLine(textPtr, indexPtr) justify = chunkPtr->stylePtr->sValuePtr->justify; rMargin = chunkPtr->stylePtr->sValuePtr->rMargin; wrapMode = chunkPtr->stylePtr->sValuePtr->wrapMode; - x = ((curIndex.charIndex == 0) + x = ((curIndex.byteIndex == 0) ? chunkPtr->stylePtr->sValuePtr->lMargin1 : chunkPtr->stylePtr->sValuePtr->lMargin2); - if (wrapMode == tkTextNoneUid) { - maxX = INT_MAX; + if (wrapMode == Tk_GetUid("none")) { + maxX = -1; } else { maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x - rMargin; @@ -867,14 +870,14 @@ LayoutDLine(textPtr, indexPtr) */ gotTab = 0; - maxChars = segPtr->size - offset; + maxBytes = segPtr->size - byteOffset; if (justify == TK_JUSTIFY_LEFT) { if (segPtr->typePtr == &tkTextCharType) { char *p; - for (p = segPtr->body.chars + offset; *p != 0; p++) { + for (p = segPtr->body.chars + byteOffset; *p != 0; p++) { if (*p == '\t') { - maxChars = (p + 1 - segPtr->body.chars) - offset; + maxBytes = (p + 1 - segPtr->body.chars) - byteOffset; gotTab = 1; break; } @@ -884,7 +887,7 @@ LayoutDLine(textPtr, indexPtr) chunkPtr->x = x; code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr, - offset, maxX-tabSize, maxChars, noCharsYet, wrapMode, + byteOffset, maxX-tabSize, maxBytes, noCharsYet, wrapMode, chunkPtr); if (code <= 0) { FreeStyle(textPtr, chunkPtr->stylePtr); @@ -895,7 +898,7 @@ LayoutDLine(textPtr, indexPtr) */ segPtr = segPtr->nextPtr; - offset = 0; + byteOffset = 0; continue; } @@ -909,7 +912,7 @@ LayoutDLine(textPtr, indexPtr) } break; } - if (chunkPtr->numChars > 0) { + if (chunkPtr->numBytes > 0) { noCharsYet = 0; lastCharChunkPtr = chunkPtr; } @@ -921,11 +924,11 @@ LayoutDLine(textPtr, indexPtr) lastChunkPtr = chunkPtr; x += chunkPtr->width; if (chunkPtr->breakIndex > 0) { - breakCharOffset = chunkPtr->breakIndex; + breakByteOffset = chunkPtr->breakIndex; breakIndex = curIndex; breakChunkPtr = chunkPtr; } - if (chunkPtr->numChars != maxChars) { + if (chunkPtr->numBytes != maxBytes) { break; } @@ -944,14 +947,14 @@ LayoutDLine(textPtr, indexPtr) tabIndex++; tabChunkPtr = chunkPtr; tabSize = SizeOfTab(textPtr, tabArrayPtr, tabIndex, x, maxX); - if (tabSize >= (maxX - x)) { + if ((maxX >= 0) && (tabSize >= maxX - x)) { break; } } - curIndex.charIndex += chunkPtr->numChars; - offset += chunkPtr->numChars; - if (offset >= segPtr->size) { - offset = 0; + curIndex.byteIndex += chunkPtr->numBytes; + byteOffset += chunkPtr->numBytes; + if (byteOffset >= segPtr->size) { + byteOffset = 0; segPtr = segPtr->nextPtr; } chunkPtr = NULL; @@ -977,10 +980,10 @@ LayoutDLine(textPtr, indexPtr) */ breakChunkPtr = lastCharChunkPtr; - breakCharOffset = breakChunkPtr->numChars; + breakByteOffset = breakChunkPtr->numBytes; } if ((breakChunkPtr != NULL) && ((lastChunkPtr != breakChunkPtr) - || (breakCharOffset != lastChunkPtr->numChars))) { + || (breakByteOffset != lastChunkPtr->numBytes))) { while (1) { chunkPtr = breakChunkPtr->nextPtr; if (chunkPtr == NULL) { @@ -991,11 +994,11 @@ LayoutDLine(textPtr, indexPtr) (*chunkPtr->undisplayProc)(textPtr, chunkPtr); ckfree((char *) chunkPtr); } - if (breakCharOffset != breakChunkPtr->numChars) { + if (breakByteOffset != breakChunkPtr->numBytes) { (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr); - segPtr = TkTextIndexToSeg(&breakIndex, &offset); + segPtr = TkTextIndexToSeg(&breakIndex, &byteOffset); (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex, - segPtr, offset, maxX, breakCharOffset, 0, + segPtr, byteOffset, maxX, breakByteOffset, 0, wrapMode, breakChunkPtr); } lastChunkPtr = breakChunkPtr; @@ -1012,7 +1015,7 @@ LayoutDLine(textPtr, indexPtr) /* * Make one more pass over the line to recompute various things - * like its height, length, and total number of characters. Also + * like its height, length, and total number of bytes. Also * modify the x-locations of chunks to reflect justification. * If we're not wrapping, I'm not sure what is the best way to * handle left and center justification: should the total length, @@ -1023,7 +1026,7 @@ LayoutDLine(textPtr, indexPtr) * what is implemented below. */ - if (wrapMode == tkTextNoneUid) { + if (wrapMode == Tk_GetUid("none")) { maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x - rMargin; } dlPtr->length = lastChunkPtr->x + lastChunkPtr->width; @@ -1038,7 +1041,7 @@ LayoutDLine(textPtr, indexPtr) for (chunkPtr = dlPtr->chunkPtr; chunkPtr != NULL; chunkPtr = chunkPtr->nextPtr) { chunkPtr->x += jIndent; - dlPtr->count += chunkPtr->numChars; + dlPtr->byteCount += chunkPtr->numBytes; if (chunkPtr->minAscent > ascent) { ascent = chunkPtr->minAscent; } @@ -1061,7 +1064,7 @@ LayoutDLine(textPtr, indexPtr) dlPtr->baseline = ascent + (dlPtr->height - ascent - descent)/2; } sValuePtr = dlPtr->chunkPtr->stylePtr->sValuePtr; - if (dlPtr->index.charIndex == 0) { + if (dlPtr->index.byteIndex == 0) { dlPtr->spaceAbove = sValuePtr->spacing1; } else { dlPtr->spaceAbove = sValuePtr->spacing2 - sValuePtr->spacing2/2; @@ -1214,7 +1217,7 @@ UpdateDisplayInfo(textPtr) * index within the line. */ - if (index.charIndex == dlPtr->index.charIndex) { + if (index.byteIndex == dlPtr->index.byteIndex) { /* * Case (a) -- can use existing display line as-is. */ @@ -1225,7 +1228,7 @@ UpdateDisplayInfo(textPtr) } goto lineOK; } - if (index.charIndex < dlPtr->index.charIndex) { + if (index.byteIndex < dlPtr->index.byteIndex) { goto makeNewDLine; } @@ -1252,7 +1255,7 @@ UpdateDisplayInfo(textPtr) lineOK: dlPtr->y = y; y += dlPtr->height; - TkTextIndexForwChars(&index, dlPtr->count, &index); + TkTextIndexForwBytes(&index, dlPtr->byteCount, &index); prevPtr = dlPtr; dlPtr = dlPtr->nextPtr; @@ -1303,7 +1306,7 @@ UpdateDisplayInfo(textPtr) */ if (y < maxY) { - int lineNum, spaceLeft, charsToCount; + int lineNum, spaceLeft, bytesToCount; DLine *lowestPtr; /* @@ -1316,22 +1319,22 @@ UpdateDisplayInfo(textPtr) spaceLeft = maxY - y; lineNum = TkBTreeLineIndex(dInfoPtr->dLinePtr->index.linePtr); - charsToCount = dInfoPtr->dLinePtr->index.charIndex; - if (charsToCount == 0) { - charsToCount = INT_MAX; + bytesToCount = dInfoPtr->dLinePtr->index.byteIndex; + if (bytesToCount == 0) { + bytesToCount = INT_MAX; lineNum--; } for ( ; (lineNum >= 0) && (spaceLeft > 0); lineNum--) { index.linePtr = TkBTreeFindLine(textPtr->tree, lineNum); - index.charIndex = 0; + index.byteIndex = 0; lowestPtr = NULL; do { dlPtr = LayoutDLine(textPtr, &index); dlPtr->nextPtr = lowestPtr; lowestPtr = dlPtr; - TkTextIndexForwChars(&index, dlPtr->count, &index); - charsToCount -= dlPtr->count; - } while ((charsToCount > 0) + TkTextIndexForwBytes(&index, dlPtr->byteCount, &index); + bytesToCount -= dlPtr->byteCount; + } while ((bytesToCount > 0) && (index.linePtr == lowestPtr->index.linePtr)); /* @@ -1358,7 +1361,7 @@ UpdateDisplayInfo(textPtr) } } FreeDLines(textPtr, lowestPtr, (DLine *) NULL, 0); - charsToCount = INT_MAX; + bytesToCount = INT_MAX; } /* @@ -1445,13 +1448,13 @@ UpdateDisplayInfo(textPtr) } maxOffset = (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) + textPtr->charWidth - 1)/textPtr->charWidth; - if (dInfoPtr->newCharOffset > maxOffset) { - dInfoPtr->newCharOffset = maxOffset; + if (dInfoPtr->newByteOffset > maxOffset) { + dInfoPtr->newByteOffset = maxOffset; } - if (dInfoPtr->newCharOffset < 0) { - dInfoPtr->newCharOffset = 0; + if (dInfoPtr->newByteOffset < 0) { + dInfoPtr->newByteOffset = 0; } - pixelOffset = dInfoPtr->newCharOffset * textPtr->charWidth; + pixelOffset = dInfoPtr->newByteOffset * textPtr->charWidth; if (pixelOffset != dInfoPtr->curPixelOffset) { dInfoPtr->curPixelOffset = pixelOffset; for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL; @@ -1581,7 +1584,7 @@ DisplayDLine(textPtr, dlPtr, prevPtr, pixmap) * to its left. */ - if (textPtr->state == tkNormalUid) { + if (textPtr->state == Tk_GetUid("normal")) { for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL); chunkPtr = chunkPtr->nextPtr) { x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset; @@ -2595,7 +2598,7 @@ TkTextChanged(textPtr, index1Ptr, index2Ptr) */ rounded = *index1Ptr; - rounded.charIndex = 0; + rounded.byteIndex = 0; firstPtr = FindDLine(dInfoPtr->dLinePtr, &rounded); if (firstPtr == NULL) { return; @@ -2671,7 +2674,7 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag) */ if (index2Ptr == NULL) { - index2Ptr = TkTextMakeIndex(textPtr->tree, + index2Ptr = TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &endOfText); } @@ -2725,13 +2728,13 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag) * previous character. */ - if (curIndexPtr->charIndex == 0) { + if (curIndexPtr->byteIndex == 0) { dlPtr = FindDLine(dlPtr, curIndexPtr); } else { TkTextIndex tmp; tmp = *curIndexPtr; - tmp.charIndex -= 1; + tmp.byteIndex -= 1; dlPtr = FindDLine(dlPtr, &tmp); } if (dlPtr == NULL) { @@ -2750,7 +2753,7 @@ TkTextRedrawTag(textPtr, index1Ptr, index2Ptr, tagPtr, withTag) } endPtr = FindDLine(dlPtr, endIndexPtr); if ((endPtr != NULL) && (endPtr->index.linePtr == endIndexPtr->linePtr) - && (endPtr->index.charIndex < endIndexPtr->charIndex)) { + && (endPtr->index.byteIndex < endIndexPtr->byteIndex)) { endPtr = endPtr->nextPtr; } @@ -2862,7 +2865,7 @@ TkTextRelayoutWindow(textPtr) * or options could change the way lines wrap. */ - if (textPtr->topIndex.charIndex != 0) { + if (textPtr->topIndex.byteIndex != 0) { MeasureUp(textPtr, &textPtr->topIndex, 0, &textPtr->topIndex); } @@ -2929,7 +2932,7 @@ TkTextSetYView(textPtr, indexPtr, pickPlace) * without redisplaying it all. */ - if (indexPtr->charIndex == 0) { + if (indexPtr->byteIndex == 0) { textPtr->topIndex = *indexPtr; } else { MeasureUp(textPtr, indexPtr, 0, &textPtr->topIndex); @@ -2957,7 +2960,7 @@ TkTextSetYView(textPtr, indexPtr, pickPlace) dlPtr = NULL; } else if ((dlPtr->index.linePtr == indexPtr->linePtr) - && (dlPtr->index.charIndex <= indexPtr->charIndex)) { + && (dlPtr->index.byteIndex <= indexPtr->byteIndex)) { return; } } @@ -3055,37 +3058,37 @@ MeasureUp(textPtr, srcPtr, distance, dstPtr) TkTextIndex *dstPtr; /* Index to fill in with result. */ { int lineNum; /* Number of current line. */ - int charsToCount; /* Maximum number of characters to measure - * in current line. */ + int bytesToCount; /* Maximum number of bytes to measure in + * current line. */ TkTextIndex bestIndex; /* Best candidate seen so far for result. */ TkTextIndex index; DLine *dlPtr, *lowestPtr; int noBestYet; /* 1 means bestIndex hasn't been set. */ noBestYet = 1; - charsToCount = srcPtr->charIndex + 1; + bytesToCount = srcPtr->byteIndex + 1; index.tree = srcPtr->tree; for (lineNum = TkBTreeLineIndex(srcPtr->linePtr); lineNum >= 0; lineNum--) { /* * Layout an entire text line (potentially > 1 display line). * For the first line, which contains srcPtr, only layout the - * part up through srcPtr (charsToCount is non-infinite to + * part up through srcPtr (bytesToCount is non-infinite to * accomplish this). Make a list of all the display lines * in backwards order (the lowest DLine on the screen is first * in the list). */ index.linePtr = TkBTreeFindLine(srcPtr->tree, lineNum); - index.charIndex = 0; + index.byteIndex = 0; lowestPtr = NULL; do { dlPtr = LayoutDLine(textPtr, &index); dlPtr->nextPtr = lowestPtr; lowestPtr = dlPtr; - TkTextIndexForwChars(&index, dlPtr->count, &index); - charsToCount -= dlPtr->count; - } while ((charsToCount > 0) && (index.linePtr == dlPtr->index.linePtr)); + TkTextIndexForwBytes(&index, dlPtr->byteCount, &index); + bytesToCount -= dlPtr->byteCount; + } while ((bytesToCount > 0) && (index.linePtr == dlPtr->index.linePtr)); /* * Scan through the display lines to see if we've covered enough @@ -3112,7 +3115,7 @@ MeasureUp(textPtr, srcPtr, distance, dstPtr) if (distance < 0) { return; } - charsToCount = INT_MAX; /* Consider all chars. in next line. */ + bytesToCount = INT_MAX; /* Consider all chars. in next line. */ } /* @@ -3120,7 +3123,7 @@ MeasureUp(textPtr, srcPtr, distance, dstPtr) * in the text. */ - TkTextMakeIndex(textPtr->tree, 0, 0, dstPtr); + TkTextMakeByteIndex(textPtr->tree, 0, 0, dstPtr); } /* @@ -3152,7 +3155,7 @@ TkTextSeeCmd(textPtr, interp, argc, argv) { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; - int x, y, width, height, lineWidth, charCount, oneThird, delta; + int x, y, width, height, lineWidth, byteCount, oneThird, delta; DLine *dlPtr; TkTextDispChunk *chunkPtr; @@ -3197,12 +3200,12 @@ TkTextSeeCmd(textPtr, interp, argc, argv) */ dlPtr = FindDLine(dInfoPtr->dLinePtr, &index); - charCount = index.charIndex - dlPtr->index.charIndex; + byteCount = index.byteIndex - dlPtr->index.byteIndex; for (chunkPtr = dlPtr->chunkPtr; ; chunkPtr = chunkPtr->nextPtr) { - if (charCount < chunkPtr->numChars) { + if (byteCount < chunkPtr->numBytes) { break; } - charCount -= chunkPtr->numChars; + byteCount -= chunkPtr->numBytes; } /* @@ -3210,7 +3213,7 @@ TkTextSeeCmd(textPtr, interp, argc, argv) * the character within the chunk. */ - (*chunkPtr->bboxProc)(chunkPtr, charCount, dlPtr->y + dlPtr->spaceAbove, + (*chunkPtr->bboxProc)(chunkPtr, byteCount, dlPtr->y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, &x, &y, &width, &height); @@ -3218,18 +3221,18 @@ TkTextSeeCmd(textPtr, interp, argc, argv) oneThird = lineWidth/3; if (delta < 0) { if (delta < -oneThird) { - dInfoPtr->newCharOffset = (x - lineWidth/2)/textPtr->charWidth; + dInfoPtr->newByteOffset = (x - lineWidth/2)/textPtr->charWidth; } else { - dInfoPtr->newCharOffset -= ((-delta) + textPtr->charWidth - 1) + dInfoPtr->newByteOffset -= ((-delta) + textPtr->charWidth - 1) / textPtr->charWidth; } } else { delta -= (lineWidth - width); if (delta > 0) { if (delta > oneThird) { - dInfoPtr->newCharOffset = (x - lineWidth/2)/textPtr->charWidth; + dInfoPtr->newByteOffset = (x - lineWidth/2)/textPtr->charWidth; } else { - dInfoPtr->newCharOffset += (delta + textPtr->charWidth - 1) + dInfoPtr->newByteOffset += (delta + textPtr->charWidth - 1) / textPtr->charWidth; } } else { @@ -3284,7 +3287,7 @@ TkTextXviewCmd(textPtr, interp, argc, argv) return TCL_OK; } - newOffset = dInfoPtr->newCharOffset; + newOffset = dInfoPtr->newByteOffset; type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count); switch (type) { case TK_SCROLL_ERROR: @@ -3305,14 +3308,14 @@ TkTextXviewCmd(textPtr, interp, argc, argv) if (charsPerPage < 1) { charsPerPage = 1; } - newOffset += charsPerPage*count; + newOffset += charsPerPage * count; break; case TK_SCROLL_UNITS: newOffset += count; break; } - dInfoPtr->newCharOffset = newOffset; + dInfoPtr->newByteOffset = newOffset; dInfoPtr->flags |= DINFO_OUT_OF_DATE; if (!(dInfoPtr->flags & REDRAW_PENDING)) { dInfoPtr->flags |= REDRAW_PENDING; @@ -3348,7 +3351,7 @@ ScrollByLines(textPtr, offset) * means that information earlier in the * text becomes visible. */ { - int i, charsToCount, lineNum; + int i, bytesToCount, lineNum; TkTextIndex new, index; TkTextLine *lastLinePtr; TextDInfo *dInfoPtr = textPtr->dInfoPtr; @@ -3361,21 +3364,21 @@ ScrollByLines(textPtr, offset) * it counts lines instead of pixels. */ - charsToCount = textPtr->topIndex.charIndex + 1; + bytesToCount = textPtr->topIndex.byteIndex + 1; index.tree = textPtr->tree; offset--; /* Skip line containing topIndex. */ for (lineNum = TkBTreeLineIndex(textPtr->topIndex.linePtr); lineNum >= 0; lineNum--) { index.linePtr = TkBTreeFindLine(textPtr->tree, lineNum); - index.charIndex = 0; + index.byteIndex = 0; lowestPtr = NULL; do { dlPtr = LayoutDLine(textPtr, &index); dlPtr->nextPtr = lowestPtr; lowestPtr = dlPtr; - TkTextIndexForwChars(&index, dlPtr->count, &index); - charsToCount -= dlPtr->count; - } while ((charsToCount > 0) + TkTextIndexForwBytes(&index, dlPtr->byteCount, &index); + bytesToCount -= dlPtr->byteCount; + } while ((bytesToCount > 0) && (index.linePtr == dlPtr->index.linePtr)); for (dlPtr = lowestPtr; dlPtr != NULL; dlPtr = dlPtr->nextPtr) { @@ -3395,7 +3398,7 @@ ScrollByLines(textPtr, offset) if (offset >= 0) { goto scheduleUpdate; } - charsToCount = INT_MAX; + bytesToCount = INT_MAX; } /* @@ -3403,7 +3406,7 @@ ScrollByLines(textPtr, offset) * in the text. */ - TkTextMakeIndex(textPtr->tree, 0, 0, &textPtr->topIndex); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &textPtr->topIndex); } else { /* * Scrolling down, to show later information in the text. @@ -3415,7 +3418,7 @@ ScrollByLines(textPtr, offset) for (i = 0; i < offset; i++) { dlPtr = LayoutDLine(textPtr, &textPtr->topIndex); dlPtr->nextPtr = NULL; - TkTextIndexForwChars(&textPtr->topIndex, dlPtr->count, &new); + TkTextIndexForwBytes(&textPtr->topIndex, dlPtr->byteCount, &new); FreeDLines(textPtr, dlPtr, (DLine *) NULL, 0); if (new.linePtr == lastLinePtr) { break; @@ -3459,7 +3462,7 @@ TkTextYviewCmd(textPtr, interp, argc, argv) * argv[1] is "yview". */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; - int pickPlace, lineNum, type, charsInLine; + int pickPlace, lineNum, type, bytesInLine; Tk_FontMetrics fm; int pixels, count; size_t switchLength; @@ -3497,7 +3500,7 @@ TkTextYviewCmd(textPtr, interp, argc, argv) } if ((argc == 3) || pickPlace) { if (Tcl_GetInt(interp, argv[2+pickPlace], &lineNum) == TCL_OK) { - TkTextMakeIndex(textPtr->tree, lineNum, 0, &index); + TkTextMakeByteIndex(textPtr->tree, lineNum, 0, &index); TkTextSetYView(textPtr, &index, 0); return TCL_OK; } @@ -3532,11 +3535,11 @@ TkTextYviewCmd(textPtr, interp, argc, argv) } fraction *= TkBTreeNumLines(textPtr->tree); lineNum = (int) fraction; - TkTextMakeIndex(textPtr->tree, lineNum, 0, &index); - charsInLine = TkBTreeCharsInLine(index.linePtr); - index.charIndex = (int)((charsInLine * (fraction-lineNum)) + 0.5); - if (index.charIndex >= charsInLine) { - TkTextMakeIndex(textPtr->tree, lineNum+1, 0, &index); + TkTextMakeByteIndex(textPtr->tree, lineNum, 0, &index); + bytesInLine = TkBTreeBytesInLine(index.linePtr); + index.byteIndex = (int)((bytesInLine * (fraction-lineNum)) + 0.5); + if (index.byteIndex >= bytesInLine) { + TkTextMakeByteIndex(textPtr->tree, lineNum + 1, 0, &index); } TkTextSetYView(textPtr, &index, 0); break; @@ -3574,7 +3577,7 @@ TkTextYviewCmd(textPtr, interp, argc, argv) do { dlPtr = LayoutDLine(textPtr, &textPtr->topIndex); dlPtr->nextPtr = NULL; - TkTextIndexForwChars(&textPtr->topIndex, dlPtr->count, + TkTextIndexForwBytes(&textPtr->topIndex, dlPtr->byteCount, &new); pixels -= dlPtr->height; FreeDLines(textPtr, dlPtr, (DLine *) NULL, 0); @@ -3626,7 +3629,7 @@ TkTextScanCmd(textPtr, interp, argc, argv) { TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextIndex index; - int c, x, y, totalScroll, newChar, maxChar; + int c, x, y, totalScroll, newByte, maxByte; Tk_FontMetrics fm; size_t length; @@ -3656,18 +3659,20 @@ TkTextScanCmd(textPtr, interp, argc, argv) * moving again). */ - newChar = dInfoPtr->scanMarkChar + (10*(dInfoPtr->scanMarkX - x)) + newByte = dInfoPtr->scanMarkIndex + (10*(dInfoPtr->scanMarkX - x)) / (textPtr->charWidth); - maxChar = 1 + (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) + maxByte = 1 + (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x) + textPtr->charWidth - 1)/textPtr->charWidth; - if (newChar < 0) { - dInfoPtr->scanMarkChar = newChar = 0; + if (newByte < 0) { + newByte = 0; + dInfoPtr->scanMarkIndex = 0; dInfoPtr->scanMarkX = x; - } else if (newChar > maxChar) { - dInfoPtr->scanMarkChar = newChar = maxChar; + } else if (newByte > maxByte) { + newByte = maxByte; + dInfoPtr->scanMarkIndex = maxByte; dInfoPtr->scanMarkX = x; } - dInfoPtr->newCharOffset = newChar; + dInfoPtr->newByteOffset = newByte; Tk_GetFontMetrics(textPtr->tkfont, &fm); totalScroll = (10*(dInfoPtr->scanMarkY - y)) / fm.linespace; @@ -3676,13 +3681,13 @@ TkTextScanCmd(textPtr, interp, argc, argv) ScrollByLines(textPtr, totalScroll-dInfoPtr->scanTotalScroll); dInfoPtr->scanTotalScroll = totalScroll; if ((index.linePtr == textPtr->topIndex.linePtr) && - (index.charIndex == textPtr->topIndex.charIndex)) { + (index.byteIndex == textPtr->topIndex.byteIndex)) { dInfoPtr->scanTotalScroll = 0; dInfoPtr->scanMarkY = y; } } } else if ((c == 'm') && (strncmp(argv[2], "mark", length) == 0)) { - dInfoPtr->scanMarkChar = dInfoPtr->newCharOffset; + dInfoPtr->scanMarkIndex = dInfoPtr->newByteOffset; dInfoPtr->scanMarkX = x; dInfoPtr->scanTotalScroll = 0; dInfoPtr->scanMarkY = y; @@ -3709,11 +3714,11 @@ TkTextScanCmd(textPtr, interp, argc, argv) * Tcl script to report them to the text's associated scrollbar. * * Results: - * If report is zero, then interp->result is filled in with + * If report is zero, then the interp's result is filled in with * two real numbers separated by a space, giving the position of * the left and right edges of the window as fractions from 0 to * 1, where 0 means the left edge of the text and 1 means the right - * edge. If report is non-zero, then interp->result isn't modified + * edge. If report is non-zero, then the interp's result isn't modified * directly, but instead a script is evaluated in interp to report * the new horizontal scroll position to the scrollbar (if the scroll * position hasn't changed then no script is invoked). @@ -3728,13 +3733,13 @@ static void GetXView(interp, textPtr, report) Tcl_Interp *interp; /* If "report" is FALSE, string * describing visible range gets - * stored in interp->result. */ + * stored in the interp's result. */ TkText *textPtr; /* Information about text widget. */ int report; /* Non-zero means report info to * scrollbar if it has changed. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; - char buffer[200]; + char buffer[TCL_DOUBLE_SPACE * 2]; double first, last; int code; @@ -3751,7 +3756,8 @@ GetXView(interp, textPtr, report) last = 1.0; } if (!report) { - sprintf(interp->result, "%g %g", first, last); + sprintf(buffer, "%g %g", first, last); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); return; } if ((first == dInfoPtr->xScrollFirst) && (last == dInfoPtr->xScrollLast)) { @@ -3779,11 +3785,11 @@ GetXView(interp, textPtr, report) * Tcl script to report them to the text's associated scrollbar. * * Results: - * If report is zero, then interp->result is filled in with + * If report is zero, then the interp's result is filled in with * two real numbers separated by a space, giving the position of * the top and bottom of the window as fractions from 0 to 1, where * 0 means the beginning of the text and 1 means the end. If - * report is non-zero, then interp->result isn't modified directly, + * report is non-zero, then the interp's result isn't modified directly, * but a script is evaluated in interp to report the new scroll * position to the scrollbar (if the scroll position hasn't changed * then no script is invoked). @@ -3798,22 +3804,22 @@ static void GetYView(interp, textPtr, report) Tcl_Interp *interp; /* If "report" is FALSE, string * describing visible range gets - * stored in interp->result. */ + * stored in the interp's result. */ TkText *textPtr; /* Information about text widget. */ int report; /* Non-zero means report info to * scrollbar if it has changed. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; - char buffer[200]; + char buffer[TCL_DOUBLE_SPACE * 2]; double first, last; DLine *dlPtr; int totalLines, code, count; dlPtr = dInfoPtr->dLinePtr; totalLines = TkBTreeNumLines(textPtr->tree); - first = ((double) TkBTreeLineIndex(dlPtr->index.linePtr)) - + ((double) dlPtr->index.charIndex) - / (TkBTreeCharsInLine(dlPtr->index.linePtr)); + first = (double) TkBTreeLineIndex(dlPtr->index.linePtr) + + (double) dlPtr->index.byteIndex + / TkBTreeBytesInLine(dlPtr->index.linePtr); first /= totalLines; while (1) { if ((dlPtr->y + dlPtr->height) > dInfoPtr->maxY) { @@ -3825,17 +3831,18 @@ GetYView(interp, textPtr, report) break; } if (dlPtr->nextPtr == NULL) { - count = dlPtr->count; + count = dlPtr->byteCount; break; } dlPtr = dlPtr->nextPtr; } last = ((double) TkBTreeLineIndex(dlPtr->index.linePtr)) - + ((double) (dlPtr->index.charIndex + count)) - / (TkBTreeCharsInLine(dlPtr->index.linePtr)); + + ((double) (dlPtr->index.byteIndex + count)) + / (TkBTreeBytesInLine(dlPtr->index.linePtr)); last /= totalLines; if (!report) { - sprintf(interp->result, "%g %g", first, last); + sprintf(buffer, "%g %g", first, last); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); return; } if ((first == dInfoPtr->yScrollFirst) && (last == dInfoPtr->yScrollLast)) { @@ -3844,8 +3851,7 @@ GetYView(interp, textPtr, report) dInfoPtr->yScrollFirst = first; dInfoPtr->yScrollLast = last; sprintf(buffer, " %g %g", first, last); - code = Tcl_VarEval(interp, textPtr->yScrollCmd, - buffer, (char *) NULL); + code = Tcl_VarEval(interp, textPtr->yScrollCmd, buffer, (char *) NULL); if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n (vertical scrolling command executed by text)"); @@ -3917,7 +3923,7 @@ FindDLine(dlPtr, indexPtr) * Now get to the right position within the text line. */ - while (indexPtr->charIndex >= (dlPtr->index.charIndex + dlPtr->count)) { + while (indexPtr->byteIndex >= (dlPtr->index.byteIndex + dlPtr->byteCount)) { dlPtr = dlPtr->nextPtr; if ((dlPtr == NULL) || (dlPtr->index.linePtr != indexPtr->linePtr)) { break; @@ -4009,21 +4015,22 @@ TkTextPixelIndex(textPtr, x, y, indexPtr) *indexPtr = dlPtr->index; x = x - dInfoPtr->x + dInfoPtr->curPixelOffset; for (chunkPtr = dlPtr->chunkPtr; x >= (chunkPtr->x + chunkPtr->width); - indexPtr->charIndex += chunkPtr->numChars, + indexPtr->byteIndex += chunkPtr->numBytes, chunkPtr = chunkPtr->nextPtr) { if (chunkPtr->nextPtr == NULL) { - indexPtr->charIndex += chunkPtr->numChars - 1; + indexPtr->byteIndex += chunkPtr->numBytes; + TkTextIndexBackChars(indexPtr, 1, indexPtr); return; } } /* - * If the chunk has more than one character in it, ask it which + * If the chunk has more than one byte in it, ask it which * character is at the desired location. */ - if (chunkPtr->numChars > 1) { - indexPtr->charIndex += (*chunkPtr->measureProc)(chunkPtr, x); + if (chunkPtr->numBytes > 1) { + indexPtr->byteIndex += (*chunkPtr->measureProc)(chunkPtr, x); } } @@ -4060,7 +4067,7 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr) TextDInfo *dInfoPtr = textPtr->dInfoPtr; DLine *dlPtr; register TkTextDispChunk *chunkPtr; - int index; + int byteIndex; /* * Make sure that all of the screen layout information is up to date. @@ -4084,15 +4091,15 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr) * index. */ - index = indexPtr->charIndex - dlPtr->index.charIndex; + byteIndex = indexPtr->byteIndex - dlPtr->index.byteIndex; for (chunkPtr = dlPtr->chunkPtr; ; chunkPtr = chunkPtr->nextPtr) { if (chunkPtr == NULL) { return -1; } - if (index < chunkPtr->numChars) { + if (byteIndex < chunkPtr->numBytes) { break; } - index -= chunkPtr->numChars; + byteIndex -= chunkPtr->numBytes; } /* @@ -4103,12 +4110,12 @@ TkTextCharBbox(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr) * horizontal scrolling. */ - (*chunkPtr->bboxProc)(chunkPtr, index, dlPtr->y + dlPtr->spaceAbove, + (*chunkPtr->bboxProc)(chunkPtr, byteIndex, dlPtr->y + dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, xPtr, yPtr, widthPtr, heightPtr); *xPtr = *xPtr + dInfoPtr->x - dInfoPtr->curPixelOffset; - if ((index == (chunkPtr->numChars-1)) && (chunkPtr->nextPtr == NULL)) { + if ((byteIndex == (chunkPtr->numBytes - 1)) && (chunkPtr->nextPtr == NULL)) { /* * Last character in display line. Give it all the space up to * the line. @@ -4207,7 +4214,7 @@ TkTextDLineInfo(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, basePtr) * * This procedure is the "layoutProc" for character segments. * - * Results: +n * Results: * If there is something to display for the chunk then a * non-zero value is returned and the fields of chunkPtr * will be filled in (see the declaration of TkTextDispChunk @@ -4224,29 +4231,29 @@ TkTextDLineInfo(textPtr, indexPtr, xPtr, yPtr, widthPtr, heightPtr, basePtr) */ int -TkTextCharLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, +TkTextCharLayoutProc(textPtr, indexPtr, segPtr, byteOffset, maxX, maxBytes, noCharsYet, wrapMode, chunkPtr) TkText *textPtr; /* Text widget being layed out. */ TkTextIndex *indexPtr; /* Index of first character to lay out * (corresponds to segPtr and offset). */ TkTextSegment *segPtr; /* Segment being layed out. */ - int offset; /* Offset within segment of first character - * to consider. */ + int byteOffset; /* Byte offset within segment of first + * character to consider. */ int maxX; /* Chunk must not occupy pixels at this * position or higher. */ - int maxChars; /* Chunk must not include more than this + int maxBytes; /* Chunk must not include more than this * many characters. */ int noCharsYet; /* Non-zero means no characters have been * assigned to this display line yet. */ - Tk_Uid wrapMode; /* How to handle line wrapping: tkTextCharUid, - * tkTextNoneUid, or tkTextWordUid. */ + Tk_Uid wrapMode; /* How to handle line wrapping: char, + * none, or text. */ register TkTextDispChunk *chunkPtr; /* Structure to fill in with information * about this chunk. The x field has already * been set by the caller. */ { Tk_Font tkfont; - int nextX, charsThatFit, count; + int nextX, bytesThatFit, count; CharInfo *ciPtr; char *p; TkTextSegment *nextPtr; @@ -4264,17 +4271,19 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, * is a white space character. */ - p = segPtr->body.chars + offset; + p = segPtr->body.chars + byteOffset; tkfont = chunkPtr->stylePtr->sValuePtr->tkfont; - charsThatFit = MeasureChars(tkfont, p, maxChars, chunkPtr->x, maxX, 0, + bytesThatFit = MeasureChars(tkfont, p, maxBytes, chunkPtr->x, maxX, 0, &nextX); - if (charsThatFit < maxChars) { - if ((charsThatFit == 0) && noCharsYet) { - charsThatFit = 1; - MeasureChars(tkfont, p, 1, chunkPtr->x, INT_MAX, 0, &nextX); + if (bytesThatFit < maxBytes) { + if ((bytesThatFit == 0) && noCharsYet) { + Tcl_UniChar ch; + + bytesThatFit = MeasureChars(tkfont, p, Tcl_UtfToUniChar(p, &ch), + chunkPtr->x, -1, 0, &nextX); } - if ((nextX < maxX) && ((p[charsThatFit] == ' ') - || (p[charsThatFit] == '\t'))) { + if ((nextX < maxX) && ((p[bytesThatFit] == ' ') + || (p[bytesThatFit] == '\t'))) { /* * Space characters are funny, in that they are considered * to fit if there is at least one pixel of space left on the @@ -4282,17 +4291,17 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, */ nextX = maxX; - charsThatFit++; + bytesThatFit++; } - if (p[charsThatFit] == '\n') { + if (p[bytesThatFit] == '\n') { /* * A newline character takes up no space, so if the previous * character fits then so does the newline. */ - charsThatFit++; + bytesThatFit++; } - if (charsThatFit == 0) { + if (bytesThatFit == 0) { return 0; } } @@ -4309,19 +4318,19 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, chunkPtr->undisplayProc = CharUndisplayProc; chunkPtr->measureProc = CharMeasureProc; chunkPtr->bboxProc = CharBboxProc; - chunkPtr->numChars = charsThatFit; + chunkPtr->numBytes = bytesThatFit; chunkPtr->minAscent = fm.ascent + chunkPtr->stylePtr->sValuePtr->offset; chunkPtr->minDescent = fm.descent - chunkPtr->stylePtr->sValuePtr->offset; chunkPtr->minHeight = 0; chunkPtr->width = nextX - chunkPtr->x; chunkPtr->breakIndex = -1; ciPtr = (CharInfo *) ckalloc((unsigned) - (sizeof(CharInfo) - 3 + charsThatFit)); + (sizeof(CharInfo) - 3 + bytesThatFit)); chunkPtr->clientData = (ClientData) ciPtr; - ciPtr->numChars = charsThatFit; - strncpy(ciPtr->chars, p, (size_t) charsThatFit); - if (p[charsThatFit-1] == '\n') { - ciPtr->numChars--; + ciPtr->numBytes = bytesThatFit; + strncpy(ciPtr->chars, p, (size_t) bytesThatFit); + if (p[bytesThatFit - 1] == '\n') { + ciPtr->numBytes--; } /* @@ -4331,22 +4340,22 @@ TkTextCharLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, * is not a character segment. */ - if (wrapMode != tkTextWordUid) { - chunkPtr->breakIndex = chunkPtr->numChars; + if (wrapMode != Tk_GetUid("word")) { + chunkPtr->breakIndex = chunkPtr->numBytes; } else { - for (count = charsThatFit, p += charsThatFit-1; count > 0; + for (count = bytesThatFit, p += bytesThatFit - 1; count > 0; count--, p--) { if (isspace(UCHAR(*p))) { chunkPtr->breakIndex = count; break; } } - if ((charsThatFit+offset) == segPtr->size) { + if ((bytesThatFit + byteOffset) == segPtr->size) { for (nextPtr = segPtr->nextPtr; nextPtr != NULL; nextPtr = nextPtr->nextPtr) { if (nextPtr->size != 0) { if (nextPtr->typePtr != &tkTextCharType) { - chunkPtr->breakIndex = chunkPtr->numChars; + chunkPtr->breakIndex = chunkPtr->numBytes; } break; } @@ -4393,7 +4402,7 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY) CharInfo *ciPtr = (CharInfo *) chunkPtr->clientData; TextStyle *stylePtr; StyleValues *sValuePtr; - int offsetChars, offsetX; + int offsetBytes, offsetX; if ((x + chunkPtr->width) <= 0) { /* @@ -4415,30 +4424,29 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY) */ offsetX = x; - offsetChars = 0; + offsetBytes = 0; if (x < 0) { - offsetChars = MeasureChars(sValuePtr->tkfont, ciPtr->chars, - ciPtr->numChars, x, 0, x - chunkPtr->x, &offsetX); + offsetBytes = MeasureChars(sValuePtr->tkfont, ciPtr->chars, + ciPtr->numBytes, x, 0, x - chunkPtr->x, &offsetX); } /* * Draw the text, underline, and overstrike for this chunk. */ - if (ciPtr->numChars > offsetChars) { - int numChars = ciPtr->numChars - offsetChars; - char *string = ciPtr->chars + offsetChars; + if (ciPtr->numBytes > offsetBytes) { + int numBytes = ciPtr->numBytes - offsetBytes; + char *string = ciPtr->chars + offsetBytes; - if ((numChars > 0) && (string[numChars - 1] == '\t')) { - numChars--; + if ((numBytes > 0) && (string[numBytes - 1] == '\t')) { + numBytes--; } Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string, - numChars, offsetX, y + baseline - sValuePtr->offset); + numBytes, offsetX, y + baseline - sValuePtr->offset); if (sValuePtr->underline) { Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, - ciPtr->chars + offsetChars, offsetX, - y + baseline - sValuePtr->offset, - 0, numChars); + ciPtr->chars + offsetBytes, offsetX, + y + baseline - sValuePtr->offset, 0, numBytes); } if (sValuePtr->overstrike) { @@ -4446,10 +4454,10 @@ CharDisplayProc(chunkPtr, x, y, height, baseline, display, dst, screenY) Tk_GetFontMetrics(sValuePtr->tkfont, &fm); Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, - ciPtr->chars + offsetChars, offsetX, + ciPtr->chars + offsetBytes, offsetX, y + baseline - sValuePtr->offset - fm.descent - (fm.ascent * 3) / 10, - 0, numChars); + 0, numBytes); } } } @@ -4511,7 +4519,8 @@ CharMeasureProc(chunkPtr, x) int endX; return MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, ciPtr->chars, - chunkPtr->numChars-1, chunkPtr->x, x, 0, &endX); + chunkPtr->numBytes - 1, chunkPtr->x, x, 0, &endX); + /* CHAR OFFSET */ } /* @@ -4538,11 +4547,11 @@ CharMeasureProc(chunkPtr, x) */ static void -CharBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, +CharBboxProc(chunkPtr, byteIndex, y, lineHeight, baseline, xPtr, yPtr, widthPtr, heightPtr) TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */ - int index; /* Index of desired character within - * the chunk. */ + int byteIndex; /* Byte offset of desired character + * within the chunk. */ int y; /* Topmost pixel in area allocated * for this line. */ int lineHeight; /* Height of line, in pixels. */ @@ -4561,10 +4570,10 @@ CharBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, int maxX; maxX = chunkPtr->width + chunkPtr->x; - MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, ciPtr->chars, index, - chunkPtr->x, 1000000, 0, xPtr); + MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, ciPtr->chars, + byteIndex, chunkPtr->x, -1, 0, xPtr); - if (index == ciPtr->numChars) { + if (byteIndex == ciPtr->numBytes) { /* * This situation only happens if the last character in a line * is a space character, in which case it absorbs all of the @@ -4572,8 +4581,8 @@ CharBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, */ *widthPtr = maxX - *xPtr; - } else if ((ciPtr->chars[index] == '\t') - && (index == (ciPtr->numChars-1))) { + } else if ((ciPtr->chars[byteIndex] == '\t') + && (byteIndex == ciPtr->numBytes - 1)) { /* * The desired character is a tab character that terminates a * chunk; give it all the space left in the chunk. @@ -4582,7 +4591,7 @@ CharBboxProc(chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, *widthPtr = maxX - *xPtr; } else { MeasureChars(chunkPtr->stylePtr->sValuePtr->tkfont, - ciPtr->chars + index, 1, *xPtr, 1000000, 0, widthPtr); + ciPtr->chars + byteIndex, 1, *xPtr, -1, 0, widthPtr); if (*widthPtr > maxX) { *widthPtr = maxX - *xPtr; } else { @@ -4717,7 +4726,7 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) continue; } ciPtr = (CharInfo *) chunkPtr2->clientData; - for (p = ciPtr->chars, i = 0; i < ciPtr->numChars; p++, i++) { + for (p = ciPtr->chars, i = 0; i < ciPtr->numBytes; p++, i++) { if (isdigit(UCHAR(*p))) { gotDigit = 1; } else if ((*p == '.') || (*p == ',')) { @@ -4738,7 +4747,7 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) ciPtr = (CharInfo *) decimalChunkPtr->clientData; MeasureChars(decimalChunkPtr->stylePtr->sValuePtr->tkfont, - ciPtr->chars, decimal, decimalChunkPtr->x, 1000000, 0, &curX); + ciPtr->chars, decimal, decimalChunkPtr->x, -1, 0, &curX); desired = tabX - (curX - x); goto update; } else { @@ -4763,7 +4772,7 @@ AdjustForTab(textPtr, tabArrayPtr, index, chunkPtr) update: delta = desired - x; - MeasureChars(textPtr->tkfont, " ", 1, 0, INT_MAX, 0, &spaceWidth); + MeasureChars(textPtr->tkfont, " ", 1, 0, -1, 0, &spaceWidth); if (delta < spaceWidth) { delta = spaceWidth; } @@ -4868,7 +4877,7 @@ SizeOfTab(textPtr, tabArrayPtr, index, x, maxX) } done: - MeasureChars(textPtr->tkfont, " ", 1, 0, INT_MAX, 0, &spaceWidth); + MeasureChars(textPtr->tkfont, " ", 1, 0, -1, 0, &spaceWidth); if (result < spaceWidth) { result = spaceWidth; } @@ -4938,7 +4947,7 @@ NextTabStop(tkfont, x, tabOrigin) * is specified. * * Results: - * The return value is the number of characters from source + * The return value is the number of bytes from source * that fit in the span given by startX and maxX. *nextXPtr * is filled in with the x-coordinate at which the first * character that didn't fit would be drawn, if it were to @@ -4951,11 +4960,11 @@ NextTabStop(tkfont, x, tabOrigin) */ static int -MeasureChars(tkfont, source, maxChars, startX, maxX, tabOrigin, nextXPtr) +MeasureChars(tkfont, source, maxBytes, startX, maxX, tabOrigin, nextXPtr) Tk_Font tkfont; /* Font in which to draw characters. */ CONST char *source; /* Characters to be displayed. Need not * be NULL-terminated. */ - int maxChars; /* Maximum # of characters to consider from + int maxBytes; /* Maximum # of bytes to consider from * source. */ int startX; /* X-position at which first character will * be drawn. */ @@ -4972,7 +4981,7 @@ MeasureChars(tkfont, source, maxChars, startX, maxX, tabOrigin, nextXPtr) ch = 0; /* lint. */ curX = startX; special = source; - end = source + maxChars; + end = source + maxBytes; for (start = source; start < end; ) { if (start >= special) { /* @@ -4992,7 +5001,7 @@ MeasureChars(tkfont, source, maxChars, startX, maxX, tabOrigin, nextXPtr) * string). Process characters between start and special. */ - if (curX >= maxX) { + if ((maxX >= 0) && (curX >= maxX)) { break; } start += Tk_MeasureChars(tkfont, start, special - start, maxX - curX, diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c index 06aff3c..b2d1923 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.c @@ -5,12 +5,12 @@ * nested inside text widgets. It also implements the "image" * widget command for texts. * - * Copyright (c) 1996 Sun Microsystems, Inc. + * Copyright (c) 1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextImage.c,v 1.2 1998/09/14 18:23:19 stanton Exp $ + * RCS: @(#) $Id: tkTextImage.c,v 1.3 1999/04/16 01:51:23 stanton Exp $ */ #include "tk.h" @@ -221,7 +221,7 @@ TkTextImageCmd(textPtr, interp, argc, argv) lineIndex = TkBTreeLineIndex(index.linePtr); if (lineIndex == TkBTreeNumLines(textPtr->tree)) { lineIndex--; - TkTextMakeIndex(textPtr->tree, lineIndex, 1000000, &index); + TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index); } /* @@ -288,7 +288,7 @@ TkTextImageCmd(textPtr, interp, argc, argv) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message.. + * returned, then the interp's result contains an error message.. * * Side effects: * Configuration information for the embedded image changes, @@ -384,7 +384,7 @@ EmbImageConfigure(textPtr, eiPtr, argc, argv) Tcl_DStringAppend(&newName,name, -1); if (conflict) { - char buf[10]; + char buf[4 + TCL_INTEGER_SPACE]; sprintf(buf, "#%d",count+1); Tcl_DStringAppend(&newName,buf, -1); } @@ -604,8 +604,8 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars, * many characters. */ int noCharsYet; /* Non-zero means no characters have been * assigned to this line yet. */ - Tk_Uid wrapMode; /* Wrap mode to use for line: tkTextCharUid, - * tkTextNoneUid, or tkTextWordUid. */ + Tk_Uid wrapMode; /* Wrap mode to use for line: char, + * text, or word. */ register TkTextDispChunk *chunkPtr; /* Structure to fill in with information * about this chunk. The x field has already @@ -630,7 +630,7 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars, height += 2*eiPtr->body.ei.padY; } if ((width > (maxX - chunkPtr->x)) - && !noCharsYet && (textPtr->wrapMode != tkTextNoneUid)) { + && !noCharsYet && (textPtr->wrapMode != Tk_GetUid("none"))) { return 0; } @@ -642,7 +642,7 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars, chunkPtr->undisplayProc = (Tk_ChunkUndisplayProc *) NULL; chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL; chunkPtr->bboxProc = EmbImageBboxProc; - chunkPtr->numChars = 1; + chunkPtr->numBytes = 1; if (eiPtr->body.ei.align == ALIGN_BASELINE) { chunkPtr->minAscent = height - eiPtr->body.ei.padY; chunkPtr->minDescent = eiPtr->body.ei.padY; @@ -857,7 +857,7 @@ TkTextImageIndex(textPtr, name, indexPtr) eiPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->tree; indexPtr->linePtr = eiPtr->body.ei.linePtr; - indexPtr->charIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr); + indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr); return 1; } @@ -893,6 +893,6 @@ EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight) index.tree = eiPtr->body.ei.textPtr->tree; index.linePtr = eiPtr->body.ei.linePtr; - index.charIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr); + index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr); TkTextChanged(eiPtr->body.ei.textPtr, &index, &index); } diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 4d2ac8e..8376419 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -5,12 +5,12 @@ * text widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextIndex.c,v 1.2 1998/09/14 18:23:19 stanton Exp $ + * RCS: @(#) $Id: tkTextIndex.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include "default.h" @@ -34,27 +34,118 @@ static char * StartEnd _ANSI_ARGS_(( char *string, TkTextIndex *indexPtr)); /* - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- * - * TkTextMakeIndex -- + * TkTextMakeByteIndex -- * - * Given a line index and a character index, look things up - * in the B-tree and fill in a TkTextIndex structure. + * Given a line index and a byte index, look things up in the B-tree + * and fill in a TkTextIndex structure. * * Results: - * The structure at *indexPtr is filled in with information - * about the character at lineIndex and charIndex (or the - * closest existing character, if the specified one doesn't - * exist), and indexPtr is returned as result. + * The structure at *indexPtr is filled in with information about the + * character at lineIndex and byteIndex (or the closest existing + * character, if the specified one doesn't exist), and indexPtr is + * returned as result. * * Side effects: * None. * - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- */ TkTextIndex * -TkTextMakeIndex(tree, lineIndex, charIndex, indexPtr) +TkTextMakeByteIndex(tree, lineIndex, byteIndex, indexPtr) + TkTextBTree tree; /* Tree that lineIndex and charIndex refer + * to. */ + int lineIndex; /* Index of desired line (0 means first + * line of text). */ + int byteIndex; /* Byte index of desired character. */ + TkTextIndex *indexPtr; /* Structure to fill in. */ +{ + TkTextSegment *segPtr; + int index; + char *p, *start; + Tcl_UniChar ch; + + indexPtr->tree = tree; + if (lineIndex < 0) { + lineIndex = 0; + byteIndex = 0; + } + if (byteIndex < 0) { + byteIndex = 0; + } + indexPtr->linePtr = TkBTreeFindLine(tree, lineIndex); + if (indexPtr->linePtr == NULL) { + indexPtr->linePtr = TkBTreeFindLine(tree, TkBTreeNumLines(tree)); + byteIndex = 0; + } + if (byteIndex == 0) { + indexPtr->byteIndex = byteIndex; + return indexPtr; + } + + /* + * Verify that the index is within the range of the line and points + * to a valid character boundary. + */ + + index = 0; + for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { + if (segPtr == NULL) { + /* + * Use the index of the last character in the line. Since + * the last character on the line is guaranteed to be a '\n', + * we can back up a constant sizeof(char) bytes. + */ + + indexPtr->byteIndex = index - sizeof(char); + break; + } + if (index + segPtr->size > byteIndex) { + indexPtr->byteIndex = byteIndex; + if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) { + /* + * Prevent UTF-8 character from being split up by ensuring + * that byteIndex falls on a character boundary. If index + * falls in the middle of a UTF-8 character, it will be + * adjusted to the end of that UTF-8 character. + */ + + start = segPtr->body.chars + (byteIndex - index); + p = Tcl_UtfPrev(start, segPtr->body.chars); + p += Tcl_UtfToUniChar(p, &ch); + indexPtr->byteIndex += p - start; + } + break; + } + index += segPtr->size; + } + return indexPtr; +} + +/* + *--------------------------------------------------------------------------- + * + * TkTextMakeCharIndex -- + * + * Given a line index and a character index, look things up in the + * B-tree and fill in a TkTextIndex structure. + * + * Results: + * The structure at *indexPtr is filled in with information about the + * character at lineIndex and charIndex (or the closest existing + * character, if the specified one doesn't exist), and indexPtr is + * returned as result. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +TkTextIndex * +TkTextMakeCharIndex(tree, lineIndex, charIndex, indexPtr) TkTextBTree tree; /* Tree that lineIndex and charIndex refer * to. */ int lineIndex; /* Index of desired line (0 means first @@ -63,7 +154,9 @@ TkTextMakeIndex(tree, lineIndex, charIndex, indexPtr) TkTextIndex *indexPtr; /* Structure to fill in. */ { register TkTextSegment *segPtr; - int index; + char *p, *start, *end; + int index, offset; + Tcl_UniChar ch; indexPtr->tree = tree; if (lineIndex < 0) { @@ -84,53 +177,76 @@ TkTextMakeIndex(tree, lineIndex, charIndex, indexPtr) * If not, just use the index of the last character in the line. */ - for (index = 0, segPtr = indexPtr->linePtr->segPtr; ; - segPtr = segPtr->nextPtr) { + index = 0; + for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { if (segPtr == NULL) { - indexPtr->charIndex = index-1; + /* + * Use the index of the last character in the line. Since + * the last character on the line is guaranteed to be a '\n', + * we can back up a constant sizeof(char) bytes. + */ + + indexPtr->byteIndex = index - sizeof(char); break; } - index += segPtr->size; - if (index > charIndex) { - indexPtr->charIndex = charIndex; - break; + if (segPtr->typePtr == &tkTextCharType) { + /* + * Turn character offset into a byte offset. + */ + + start = segPtr->body.chars; + end = start + segPtr->size; + for (p = start; p < end; p += offset) { + if (charIndex == 0) { + indexPtr->byteIndex = index; + return indexPtr; + } + charIndex--; + offset = Tcl_UtfToUniChar(p, &ch); + index += offset; + } + } else { + if (charIndex < segPtr->size) { + indexPtr->byteIndex = index; + break; + } + charIndex -= segPtr->size; + index += segPtr->size; } } return indexPtr; } /* - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- * * TkTextIndexToSeg -- * - * Given an index, this procedure returns the segment and - * offset within segment for the index. + * Given an index, this procedure returns the segment and offset + * within segment for the index. * * Results: - * The return value is a pointer to the segment referred to - * by indexPtr; this will always be a segment with non-zero - * size. The variable at *offsetPtr is set to hold the - * integer offset within the segment of the character - * given by indexPtr. + * The return value is a pointer to the segment referred to by + * indexPtr; this will always be a segment with non-zero size. The + * variable at *offsetPtr is set to hold the integer offset within + * the segment of the character given by indexPtr. * * Side effects: * None. * - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- */ TkTextSegment * TkTextIndexToSeg(indexPtr, offsetPtr) - TkTextIndex *indexPtr; /* Text index. */ - int *offsetPtr; /* Where to store offset within - * segment, or NULL if offset isn't - * wanted. */ + CONST TkTextIndex *indexPtr;/* Text index. */ + int *offsetPtr; /* Where to store offset within segment, or + * NULL if offset isn't wanted. */ { - register TkTextSegment *segPtr; + TkTextSegment *segPtr; int offset; - for (offset = indexPtr->charIndex, segPtr = indexPtr->linePtr->segPtr; + for (offset = indexPtr->byteIndex, segPtr = indexPtr->linePtr->segPtr; offset >= segPtr->size; offset -= segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body. */ @@ -142,30 +258,29 @@ TkTextIndexToSeg(indexPtr, offsetPtr) } /* - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- * * TkTextSegToOffset -- * - * Given a segment pointer and the line containing it, this - * procedure returns the offset of the segment within its - * line. + * Given a segment pointer and the line containing it, this procedure + * returns the offset of the segment within its line. * * Results: - * The return value is the offset (within its line) of the - * first character in segPtr. + * The return value is the offset (within its line) of the first + * character in segPtr. * * Side effects: * None. * - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- */ int TkTextSegToOffset(segPtr, linePtr) - TkTextSegment *segPtr; /* Segment whose offset is desired. */ - TkTextLine *linePtr; /* Line containing segPtr. */ + CONST TkTextSegment *segPtr;/* Segment whose offset is desired. */ + CONST TkTextLine *linePtr; /* Line containing segPtr. */ { - TkTextSegment *segPtr2; + CONST TkTextSegment *segPtr2; int offset; offset = 0; @@ -177,23 +292,22 @@ TkTextSegToOffset(segPtr, linePtr) } /* - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- * * TkTextGetIndex -- * - * Given a string, return the line and character indices that - * it describes. + * Given a string, return the index that is described. * * Results: - * The return value is a standard Tcl return result. If - * TCL_OK is returned, then everything went well and the index - * at *indexPtr is filled in; otherwise TCL_ERROR is returned - * and an error message is left in interp->result. + * The return value is a standard Tcl return result. If TCL_OK is + * returned, then everything went well and the index at *indexPtr is + * filled in; otherwise TCL_ERROR is returned and an error message + * is left in the interp's result. * * Side effects: * None. * - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ int @@ -203,8 +317,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) char *string; /* Textual description of position. */ TkTextIndex *indexPtr; /* Index structure to fill in. */ { - register char *p; - char *end, *endOfBase; + char *p, *end, *endOfBase; Tcl_HashEntry *hPtr; TkTextTag *tagPtr; TkTextSearch search; @@ -259,8 +372,8 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) goto tryxy; } tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); - TkTextMakeIndex(textPtr->tree, 0, 0, &first); - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, + TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &last); TkBTreeStartSearch(&first, &last, tagPtr, &search); if (!TkBTreeCharTagged(&first, tagPtr) && !TkBTreeNextTag(&search)) { @@ -324,7 +437,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) } endOfBase = end; } - TkTextMakeIndex(textPtr->tree, lineIndex, charIndex, indexPtr); + TkTextMakeCharIndex(textPtr->tree, lineIndex, charIndex, indexPtr); goto gotBase; } @@ -353,7 +466,7 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) * Base position is end of text. */ - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, indexPtr); goto gotBase; } else { @@ -420,13 +533,12 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) } /* - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- * * TkTextPrintIndex -- - * * - * This procedure generates a string description of an index, - * suitable for reading in again later. + * This procedure generates a string description of an index, suitable + * for reading in again later. * * Results: * The characters pointed to by string are modified. @@ -434,49 +546,69 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) * Side effects: * None. * - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ void TkTextPrintIndex(indexPtr, string) - TkTextIndex *indexPtr; /* Pointer to index. */ + CONST TkTextIndex *indexPtr;/* Pointer to index. */ char *string; /* Place to store the position. Must have * at least TK_POS_CHARS characters. */ { + TkTextSegment *segPtr; + int numBytes, charIndex; + + numBytes = indexPtr->byteIndex; + charIndex = 0; + for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { + if (numBytes <= segPtr->size) { + break; + } + if (segPtr->typePtr == &tkTextCharType) { + charIndex += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size); + } else { + charIndex += segPtr->size; + } + numBytes -= segPtr->size; + } + if (segPtr->typePtr == &tkTextCharType) { + charIndex += Tcl_NumUtfChars(segPtr->body.chars, numBytes); + } else { + charIndex += numBytes; + } sprintf(string, "%d.%d", TkBTreeLineIndex(indexPtr->linePtr) + 1, - indexPtr->charIndex); + charIndex); } /* - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- * * TkTextIndexCmp -- * - * Compare two indices to see which one is earlier in - * the text. + * Compare two indices to see which one is earlier in the text. * * Results: - * The return value is 0 if index1Ptr and index2Ptr refer - * to the same position in the file, -1 if index1Ptr refers - * to an earlier position than index2Ptr, and 1 otherwise. + * The return value is 0 if index1Ptr and index2Ptr refer to the same + * position in the file, -1 if index1Ptr refers to an earlier position + * than index2Ptr, and 1 otherwise. * * Side effects: * None. * - *-------------------------------------------------------------- + *--------------------------------------------------------------------------- */ int TkTextIndexCmp(index1Ptr, index2Ptr) - TkTextIndex *index1Ptr; /* First index. */ - TkTextIndex *index2Ptr; /* Second index. */ + CONST TkTextIndex *index1Ptr; /* First index. */ + CONST TkTextIndex *index2Ptr; /* Second index. */ { int line1, line2; if (index1Ptr->linePtr == index2Ptr->linePtr) { - if (index1Ptr->charIndex < index2Ptr->charIndex) { + if (index1Ptr->byteIndex < index2Ptr->byteIndex) { return -1; - } else if (index1Ptr->charIndex > index2Ptr->charIndex) { + } else if (index1Ptr->byteIndex > index2Ptr->byteIndex) { return 1; } else { return 0; @@ -494,23 +626,23 @@ TkTextIndexCmp(index1Ptr, index2Ptr) } /* - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- * * ForwBack -- * - * This procedure handles +/- modifiers for indices to adjust - * the index forwards or backwards. + * This procedure handles +/- modifiers for indices to adjust the + * index forwards or backwards. * * Results: - * If the modifier in string is successfully parsed then the - * return value is the address of the first character after the - * modifier, and *indexPtr is updated to reflect the modifier. - * If there is a syntax error in the modifier then NULL is returned. + * If the modifier in string is successfully parsed then the return + * value is the address of the first character after the modifier, + * and *indexPtr is updated to reflect the modifier. If there is a + * syntax error in the modifier then NULL is returned. * * Side effects: * None. * - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ static char * @@ -550,7 +682,7 @@ ForwBack(string, indexPtr) */ units = p; - while ((*p != 0) && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { + while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { p++; } length = p - units; @@ -578,7 +710,18 @@ ForwBack(string, indexPtr) lineIndex = 0; } } - TkTextMakeIndex(indexPtr->tree, lineIndex, indexPtr->charIndex, + /* + * This doesn't work quite right if using a proportional font or + * UTF-8 characters with varying numbers of bytes. The cursor will + * bop around, keeping a constant number of bytes (not characters) + * from the left edge (but making sure not to split any UTF-8 + * characters), regardless of the x-position the index corresponds + * to. The proper way to do this is to get the x-position of the + * index and then pick the character at the same x-position in the + * new line. + */ + + TkTextMakeByteIndex(indexPtr->tree, lineIndex, indexPtr->byteIndex, indexPtr); } else { return NULL; @@ -587,44 +730,42 @@ ForwBack(string, indexPtr) } /* - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- * - * TkTextIndexForwChars -- + * TkTextIndexForwBytes -- * - * Given an index for a text widget, this procedure creates a - * new index that points "count" characters ahead of the source - * index. + * Given an index for a text widget, this procedure creates a new + * index that points "count" bytes ahead of the source index. * * Results: - * *dstPtr is modified to refer to the character "count" characters - * after srcPtr, or to the last character in the file if there aren't - * "count" characters left in the file. + * *dstPtr is modified to refer to the character "count" bytes after + * srcPtr, or to the last character in the TkText if there aren't + * "count" bytes left. * * Side effects: * None. * - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ - /* ARGSUSED */ void -TkTextIndexForwChars(srcPtr, count, dstPtr) - TkTextIndex *srcPtr; /* Source index. */ - int count; /* How many characters forward to - * move. May be negative. */ - TkTextIndex *dstPtr; /* Destination index: gets modified. */ +TkTextIndexForwBytes(srcPtr, byteCount, dstPtr) + CONST TkTextIndex *srcPtr; /* Source index. */ + int byteCount; /* How many bytes forward to move. May be + * negative. */ + TkTextIndex *dstPtr; /* Destination index: gets modified. */ { TkTextLine *linePtr; TkTextSegment *segPtr; int lineLength; - if (count < 0) { - TkTextIndexBackChars(srcPtr, -count, dstPtr); + if (byteCount < 0) { + TkTextIndexBackBytes(srcPtr, -byteCount, dstPtr); return; } *dstPtr = *srcPtr; - dstPtr->charIndex += count; + dstPtr->byteIndex += byteCount; while (1) { /* * Compute the length of the current line. @@ -641,13 +782,13 @@ TkTextIndexForwChars(srcPtr, count, dstPtr) * Otherwise go on to the next line. */ - if (dstPtr->charIndex < lineLength) { + if (dstPtr->byteIndex < lineLength) { return; } - dstPtr->charIndex -= lineLength; + dstPtr->byteIndex -= lineLength; linePtr = TkBTreeNextLine(dstPtr->linePtr); if (linePtr == NULL) { - dstPtr->charIndex = lineLength - 1; + dstPtr->byteIndex = lineLength - 1; return; } dstPtr->linePtr = linePtr; @@ -655,44 +796,133 @@ TkTextIndexForwChars(srcPtr, count, dstPtr) } /* - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- * - * TkTextIndexBackChars -- + * TkTextIndexForwChars -- * - * Given an index for a text widget, this procedure creates a - * new index that points "count" characters earlier than the - * source index. + * Given an index for a text widget, this procedure creates a new + * index that points "count" characters ahead of the source index. * * Results: * *dstPtr is modified to refer to the character "count" characters - * before srcPtr, or to the first character in the file if there aren't - * "count" characters earlier than srcPtr. + * after srcPtr, or to the last character in the TkText if there + * aren't "count" characters left in the file. * * Side effects: * None. * - *---------------------------------------------------------------------- + *--------------------------------------------------------------------------- + */ + +void +TkTextIndexForwChars(srcPtr, charCount, dstPtr) + CONST TkTextIndex *srcPtr; /* Source index. */ + int charCount; /* How many characters forward to move. + * May be negative. */ + TkTextIndex *dstPtr; /* Destination index: gets modified. */ +{ + TkTextLine *linePtr; + TkTextSegment *segPtr; + int byteOffset; + char *start, *end, *p; + Tcl_UniChar ch; + + if (charCount < 0) { + TkTextIndexBackChars(srcPtr, -charCount, dstPtr); + return; + } + + *dstPtr = *srcPtr; + + /* + * Find seg that contains src byteIndex. + * Move forward specified number of chars. + */ + + segPtr = TkTextIndexToSeg(dstPtr, &byteOffset); + while (1) { + /* + * Go through each segment in line looking for specified character + * index. + */ + + for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) { + if (segPtr->typePtr == &tkTextCharType) { + start = segPtr->body.chars + byteOffset; + end = segPtr->body.chars + segPtr->size; + for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { + if (charCount == 0) { + dstPtr->byteIndex += (p - start); + return; + } + charCount--; + } + } else { + if (charCount < segPtr->size - byteOffset) { + dstPtr->byteIndex += charCount; + return; + } + charCount -= segPtr->size - byteOffset; + } + dstPtr->byteIndex += segPtr->size - byteOffset; + byteOffset = 0; + } + + /* + * Go to the next line. If we are at the end of the text item, + * back up one byte (for the terminal '\n' character) and return + * that index. + */ + + linePtr = TkBTreeNextLine(dstPtr->linePtr); + if (linePtr == NULL) { + dstPtr->byteIndex -= sizeof(char); + return; + } + dstPtr->linePtr = linePtr; + dstPtr->byteIndex = 0; + segPtr = dstPtr->linePtr->segPtr; + } +} + +/* + *--------------------------------------------------------------------------- + * + * TkTextIndexBackBytes -- + * + * Given an index for a text widget, this procedure creates a new + * index that points "count" bytes earlier than the source index. + * + * Results: + * *dstPtr is modified to refer to the character "count" bytes before + * srcPtr, or to the first character in the TkText if there aren't + * "count" bytes earlier than srcPtr. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- */ void -TkTextIndexBackChars(srcPtr, count, dstPtr) - TkTextIndex *srcPtr; /* Source index. */ - int count; /* How many characters backward to - * move. May be negative. */ - TkTextIndex *dstPtr; /* Destination index: gets modified. */ +TkTextIndexBackBytes(srcPtr, byteCount, dstPtr) + CONST TkTextIndex *srcPtr; /* Source index. */ + int byteCount; /* How many bytes backward to move. May be + * negative. */ + TkTextIndex *dstPtr; /* Destination index: gets modified. */ { TkTextSegment *segPtr; int lineIndex; - if (count < 0) { - TkTextIndexForwChars(srcPtr, -count, dstPtr); + if (byteCount < 0) { + TkTextIndexForwBytes(srcPtr, -byteCount, dstPtr); return; } *dstPtr = *srcPtr; - dstPtr->charIndex -= count; + dstPtr->byteIndex -= byteCount; lineIndex = -1; - while (dstPtr->charIndex < 0) { + while (dstPtr->byteIndex < 0) { /* * Move back one line in the text. If we run off the beginning * of the file then just return the first character in the text. @@ -702,7 +932,7 @@ TkTextIndexBackChars(srcPtr, count, dstPtr) lineIndex = TkBTreeLineIndex(dstPtr->linePtr); } if (lineIndex == 0) { - dstPtr->charIndex = 0; + dstPtr->byteIndex = 0; return; } lineIndex--; @@ -714,8 +944,124 @@ TkTextIndexBackChars(srcPtr, count, dstPtr) for (segPtr = dstPtr->linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { - dstPtr->charIndex += segPtr->size; + dstPtr->byteIndex += segPtr->size; + } + } +} + +/* + *--------------------------------------------------------------------------- + * + * TkTextIndexBackChars -- + * + * Given an index for a text widget, this procedure creates a new + * index that points "count" characters earlier than the source index. + * + * Results: + * *dstPtr is modified to refer to the character "count" characters + * before srcPtr, or to the first character in the file if there + * aren't "count" characters earlier than srcPtr. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +void +TkTextIndexBackChars(srcPtr, charCount, dstPtr) + CONST TkTextIndex *srcPtr; /* Source index. */ + int charCount; /* How many characters backward to move. + * May be negative. */ + TkTextIndex *dstPtr; /* Destination index: gets modified. */ +{ + TkTextSegment *segPtr, *oldPtr; + int lineIndex, segSize; + char *p, *start, *end; + + if (charCount <= 0) { + TkTextIndexForwChars(srcPtr, -charCount, dstPtr); + return; + } + + *dstPtr = *srcPtr; + + /* + * Find offset within seg that contains byteIndex. + * Move backward specified number of chars. + */ + + lineIndex = -1; + + segSize = dstPtr->byteIndex; + for (segPtr = dstPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { + if (segSize <= segPtr->size) { + break; + } + segSize -= segPtr->size; + } + while (1) { + if (segPtr->typePtr == &tkTextCharType) { + start = segPtr->body.chars; + end = segPtr->body.chars + segSize; + for (p = end; ; p = Tcl_UtfPrev(p, start)) { + if (charCount == 0) { + dstPtr->byteIndex -= (end - p); + return; + } + if (p == start) { + break; + } + charCount--; + } + } else { + if (charCount <= segSize) { + dstPtr->byteIndex -= charCount; + return; + } + charCount -= segSize; + } + dstPtr->byteIndex -= segSize; + + /* + * Move back into previous segment. + */ + + oldPtr = segPtr; + segPtr = dstPtr->linePtr->segPtr; + if (segPtr != oldPtr) { + for ( ; segPtr->nextPtr != oldPtr; segPtr = segPtr->nextPtr) { + /* Empty body. */ + } + segSize = segPtr->size; + continue; + } + + /* + * Move back to previous line. + */ + + if (lineIndex < 0) { + lineIndex = TkBTreeLineIndex(dstPtr->linePtr); + } + if (lineIndex == 0) { + dstPtr->byteIndex = 0; + return; + } + lineIndex--; + dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, lineIndex); + + /* + * Compute the length of the line and add that to dstPtr->byteIndex. + */ + + oldPtr = dstPtr->linePtr->segPtr; + for (segPtr = oldPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { + dstPtr->byteIndex += segPtr->size; + oldPtr = segPtr; } + segPtr = oldPtr; + segSize = segPtr->size; } } @@ -762,15 +1108,15 @@ StartEnd(string, indexPtr) length = p-string; if ((*string == 'l') && (strncmp(string, "lineend", length) == 0) && (length >= 5)) { - indexPtr->charIndex = 0; + indexPtr->byteIndex = 0; for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { - indexPtr->charIndex += segPtr->size; + indexPtr->byteIndex += segPtr->size; } - indexPtr->charIndex -= 1; + indexPtr->byteIndex -= sizeof(char); } else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0) && (length >= 5)) { - indexPtr->charIndex = 0; + indexPtr->byteIndex = 0; } else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0) && (length >= 5)) { int firstChar = 1; @@ -791,7 +1137,7 @@ StartEnd(string, indexPtr) firstChar = 0; } offset += 1; - indexPtr->charIndex += 1; + indexPtr->byteIndex += sizeof(char); if (offset >= segPtr->size) { segPtr = TkTextIndexToSeg(indexPtr, &offset); } @@ -820,10 +1166,10 @@ StartEnd(string, indexPtr) firstChar = 0; } offset -= 1; - indexPtr->charIndex -= 1; + indexPtr->byteIndex -= sizeof(char); if (offset < 0) { - if (indexPtr->charIndex < 0) { - indexPtr->charIndex = 0; + if (indexPtr->byteIndex < 0) { + indexPtr->byteIndex = 0; goto done; } segPtr = TkTextIndexToSeg(indexPtr, &offset); diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c index 07094f1..209a33b 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextMark.c,v 1.2 1998/09/14 18:23:19 stanton Exp $ + * RCS: @(#) $Id: tkTextMark.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include "tkInt.h" @@ -134,9 +134,9 @@ TkTextMarkCmd(textPtr, interp, argc, argv) markPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); if (argc == 4) { if (markPtr->typePtr == &tkTextRightMarkType) { - interp->result = "right"; + Tcl_SetResult(interp, "right", TCL_STATIC); } else { - interp->result = "left"; + Tcl_SetResult(interp, "left", TCL_STATIC); } return TCL_OK; } @@ -319,10 +319,10 @@ TkTextMarkSegToIndex(textPtr, markPtr, indexPtr) indexPtr->tree = textPtr->tree; indexPtr->linePtr = markPtr->body.mark.linePtr; - indexPtr->charIndex = 0; + indexPtr->byteIndex = 0; for (segPtr = indexPtr->linePtr->segPtr; segPtr != markPtr; segPtr = segPtr->nextPtr) { - indexPtr->charIndex += segPtr->size; + indexPtr->byteIndex += segPtr->size; } } @@ -468,7 +468,7 @@ MarkLayoutProc(textPtr, indexPtr, segPtr, offset, maxX, maxChars, chunkPtr->undisplayProc = InsertUndisplayProc; chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL; chunkPtr->bboxProc = (Tk_ChunkBboxProc *) NULL; - chunkPtr->numChars = 0; + chunkPtr->numBytes = 0; chunkPtr->minAscent = 0; chunkPtr->minDescent = 0; chunkPtr->minHeight = 0; @@ -669,7 +669,7 @@ MarkFindNext(interp, textPtr, string) return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; - segPtr != NULL && offset < index.charIndex; + segPtr != NULL && offset < index.byteIndex; offset += segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body */ ; } @@ -692,7 +692,7 @@ MarkFindNext(interp, textPtr, string) if (index.linePtr == (TkTextLine *) NULL) { return TCL_OK; } - index.charIndex = 0; + index.byteIndex = 0; segPtr = index.linePtr->segPtr; } } @@ -742,7 +742,7 @@ MarkFindPrev(interp, textPtr, string) return TCL_ERROR; } for (offset = 0, segPtr = index.linePtr->segPtr; - segPtr != NULL && offset < index.charIndex; + segPtr != NULL && offset < index.byteIndex; offset += segPtr->size, segPtr = segPtr->nextPtr) { /* Empty loop body */ ; } diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index c3e1c5d..9827f92 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -6,12 +6,12 @@ * related to tags. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextTag.c,v 1.2 1998/09/14 18:23:19 stanton Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include "default.h" @@ -235,9 +235,22 @@ TkTextTagCmd(textPtr, interp, argc, argv) command = Tk_GetBinding(interp, textPtr->bindingTable, (ClientData) tagPtr, argv[4]); if (command == NULL) { - return TCL_ERROR; + char *string = Tcl_GetStringResult(interp); + + /* + * Ignore missing binding errors. This is a special hack + * that relies on the error message returned by FindSequence + * in tkBind.c. + */ + + if (string[0] != '\0') { + return TCL_ERROR; + } else { + Tcl_ResetResult(interp); + } + } else { + Tcl_SetResult(interp, command, TCL_STATIC); } - interp->result = command; } else { Tk_GetAllBindings(interp, textPtr->bindingTable, (ClientData) tagPtr); @@ -379,9 +392,9 @@ TkTextTagCmd(textPtr, interp, argc, argv) } } if ((tagPtr->wrapMode != NULL) - && (tagPtr->wrapMode != tkTextCharUid) - && (tagPtr->wrapMode != tkTextNoneUid) - && (tagPtr->wrapMode != tkTextWordUid)) { + && (tagPtr->wrapMode != Tk_GetUid("char")) + && (tagPtr->wrapMode != Tk_GetUid("none")) + && (tagPtr->wrapMode != Tk_GetUid("word"))) { Tcl_AppendResult(interp, "bad wrap mode \"", tagPtr->wrapMode, "\": must be char, none, or word", (char *) NULL); tagPtr->wrapMode = NULL; @@ -448,10 +461,10 @@ TkTextTagCmd(textPtr, interp, argc, argv) TkTextRedrawTag(textPtr, (TkTextIndex *) NULL, (TkTextIndex *) NULL, tagPtr, 1); } - TkBTreeTag(TkTextMakeIndex(textPtr->tree, 0, 0, &first), - TkTextMakeIndex(textPtr->tree, - TkBTreeNumLines(textPtr->tree), 0, &last), - tagPtr, 0); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), + 0, &last), + TkBTreeTag(&first, &last, tagPtr, 0); Tcl_DeleteHashEntry(hPtr); if (textPtr->bindingTable != NULL) { Tk_DeleteAllBindings(textPtr->bindingTable, @@ -552,7 +565,7 @@ TkTextTagCmd(textPtr, interp, argc, argv) if (TkTextGetIndex(interp, textPtr, argv[4], &index1) != TCL_OK) { return TCL_ERROR; } - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &last); if (argc == 5) { index2 = last; @@ -582,7 +595,7 @@ TkTextTagCmd(textPtr, interp, argc, argv) * skip to the end of this tagged range. */ - for (segPtr = index1.linePtr->segPtr, offset = index1.charIndex; + for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex; offset >= 0; offset -= segPtr->size, segPtr = segPtr->nextPtr) { if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType) @@ -631,7 +644,7 @@ TkTextTagCmd(textPtr, interp, argc, argv) return TCL_ERROR; } if (argc == 5) { - TkTextMakeIndex(textPtr->tree, 0, 0, &index2); + TkTextMakeByteIndex(textPtr->tree, 0, 0, &index2); } else if (TkTextGetIndex(interp, textPtr, argv[5], &index2) != TCL_OK) { return TCL_ERROR; @@ -651,7 +664,7 @@ TkTextTagCmd(textPtr, interp, argc, argv) } if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { TkTextPrintIndex(&tSearch.curIndex, position1); - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &last); TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); TkBTreeNextTag(&tSearch); @@ -711,8 +724,8 @@ TkTextTagCmd(textPtr, interp, argc, argv) if (tagPtr == NULL) { return TCL_OK; } - TkTextMakeIndex(textPtr->tree, 0, 0, &first); - TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), + TkTextMakeByteIndex(textPtr->tree, 0, 0, &first); + TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &last); TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); if (TkBTreeCharTagged(&first, tagPtr)) { @@ -828,7 +841,7 @@ TkTextCreateTag(textPtr, tagName) * Results: * If tagName is defined in textPtr, a pointer to its TkTextTag * structure is returned. Otherwise NULL is returned and an - * error message is recorded in interp->result unless interp + * error message is recorded in the interp's result unless interp * is NULL. * * Side effects: diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index a799da4..ef28b44 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -6,12 +6,12 @@ * widget command for texts. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * 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.2 1998/09/14 18:23:19 stanton Exp $ + * RCS: @(#) $Id: tkTextWind.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include "tk.h" @@ -244,7 +244,7 @@ TkTextWindowCmd(textPtr, interp, argc, argv) lineIndex = TkBTreeLineIndex(index.linePtr); if (lineIndex == TkBTreeNumLines(textPtr->tree)) { lineIndex--; - TkTextMakeIndex(textPtr->tree, lineIndex, 1000000, &index); + TkTextMakeByteIndex(textPtr->tree, lineIndex, 1000000, &index); } /* @@ -311,7 +311,7 @@ TkTextWindowCmd(textPtr, interp, argc, argv) * * Results: * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then interp->result contains an error message.. + * returned, then the interp's result contains an error message.. * * Side effects: * Configuration information for the embedded window changes, @@ -541,7 +541,7 @@ EmbWinStructureProc(clientData, eventPtr) ewPtr->body.ew.tkwin = NULL; index.tree = ewPtr->body.ew.textPtr->tree; index.linePtr = ewPtr->body.ew.linePtr; - index.charIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); + index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); TkTextChanged(ewPtr->body.ew.textPtr, &index, &index); } @@ -575,7 +575,7 @@ EmbWinRequestProc(clientData, tkwin) index.tree = ewPtr->body.ew.textPtr->tree; index.linePtr = ewPtr->body.ew.linePtr; - index.charIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); + index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); TkTextChanged(ewPtr->body.ew.textPtr, &index, &index); } @@ -620,7 +620,7 @@ EmbWinLostSlaveProc(clientData, tkwin) ewPtr->body.ew.tkwin = NULL; index.tree = ewPtr->body.ew.textPtr->tree; index.linePtr = ewPtr->body.ew.linePtr; - index.charIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); + index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr); TkTextChanged(ewPtr->body.ew.textPtr, &index, &index); } @@ -778,7 +778,7 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars, goto gotWindow; } Tcl_DStringInit(&name); - Tcl_DStringAppend(&name, textPtr->interp->result, -1); + Tcl_DStringAppend(&name, Tcl_GetStringResult(textPtr->interp), -1); Tcl_ResetResult(textPtr->interp); ewPtr->body.ew.tkwin = Tk_NameToWindow(textPtr->interp, Tcl_DStringValue(&name), textPtr->tkwin); @@ -835,7 +835,7 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars, height = Tk_ReqHeight(ewPtr->body.ew.tkwin) + 2*ewPtr->body.ew.padY; } if ((width > (maxX - chunkPtr->x)) - && !noCharsYet && (textPtr->wrapMode != tkTextNoneUid)) { + && !noCharsYet && (textPtr->wrapMode != Tk_GetUid("none"))) { return 0; } @@ -847,7 +847,7 @@ EmbWinLayoutProc(textPtr, indexPtr, ewPtr, offset, maxX, maxChars, chunkPtr->undisplayProc = EmbWinUndisplayProc; chunkPtr->measureProc = (Tk_ChunkMeasureProc *) NULL; chunkPtr->bboxProc = EmbWinBboxProc; - chunkPtr->numChars = 1; + chunkPtr->numBytes = 1; if (ewPtr->body.ew.align == ALIGN_BASELINE) { chunkPtr->minAscent = height - ewPtr->body.ew.padY; chunkPtr->minDescent = ewPtr->body.ew.padY; @@ -1171,6 +1171,6 @@ TkTextWindowIndex(textPtr, name, indexPtr) ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->tree; indexPtr->linePtr = ewPtr->body.ew.linePtr; - indexPtr->charIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr); + indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr); return 1; } diff --git a/generic/tkTrig.c b/generic/tkTrig.c index 920bcc0..d0afe90 100644 --- a/generic/tkTrig.c +++ b/generic/tkTrig.c @@ -7,12 +7,12 @@ * used by canvases. * * Copyright (c) 1992-1994 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTrig.c,v 1.2 1998/09/14 18:23:20 stanton Exp $ + * RCS: @(#) $Id: tkTrig.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include <stdio.h> @@ -1195,7 +1195,7 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) * * Results: * None. Postscript commands to generate the path are appended - * to interp->result. + * to the interp's result. * * Side effects: * None. diff --git a/generic/tkUtil.c b/generic/tkUtil.c index 547fd16..3124f68 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -6,16 +6,30 @@ * a focus highlight. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUtil.c,v 1.2 1998/09/14 18:23:20 stanton Exp $ + * RCS: @(#) $Id: tkUtil.c,v 1.3 1999/04/16 01:51:24 stanton Exp $ */ #include "tkInt.h" #include "tkPort.h" + +/* + * The structure below defines the implementation of the "statekey" + * Tcl object, used for quickly finding a mapping in a TkStateMap. + */ + +static Tcl_ObjType stateKeyType = { + "statekey", /* name */ + (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ + (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */ + (Tcl_UpdateStringProc *) NULL, /* updateStringProc */ + (Tcl_SetFromAnyProc *) NULL /* setFromAnyProc */ +}; + /* *---------------------------------------------------------------------- @@ -132,7 +146,7 @@ Tk_DrawFocusHighlight(tkwin, gc, width, drawable) * took. If TK_SCROLL_MOVETO, *dblPtr is filled in with the * desired position; if TK_SCROLL_PAGES or TK_SCROLL_UNITS, * *intPtr is filled in with the number of lines to move (may be - * negative); if TK_SCROLL_ERROR, interp->result contains an + * negative); if TK_SCROLL_ERROR, the interp's result contains an * error message. * * Side effects: @@ -197,6 +211,85 @@ Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr) } /* + *---------------------------------------------------------------------- + * + * Tk_GetScrollInfoObj -- + * + * This procedure is invoked to parse "xview" and "yview" + * scrolling commands for widgets using the new scrolling + * command syntax ("moveto" or "scroll" options). + * + * Results: + * The return value is either TK_SCROLL_MOVETO, TK_SCROLL_PAGES, + * TK_SCROLL_UNITS, or TK_SCROLL_ERROR. This indicates whether + * the command was successfully parsed and what form the command + * took. If TK_SCROLL_MOVETO, *dblPtr is filled in with the + * desired position; if TK_SCROLL_PAGES or TK_SCROLL_UNITS, + * *intPtr is filled in with the number of lines to move (may be + * negative); if TK_SCROLL_ERROR, the interp's result contains an + * error message. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Tk_GetScrollInfoObj(interp, objc, objv, dblPtr, intPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + int objc; /* # arguments for command. */ + Tcl_Obj *CONST objv[]; /* Arguments for command. */ + double *dblPtr; /* Filled in with argument "moveto" + * option, if any. */ + int *intPtr; /* Filled in with number of pages + * or lines to scroll, if any. */ +{ + int c; + size_t length; + char *arg2, *arg4; + + arg2 = Tcl_GetString(objv[2]); + length = strlen(arg2); + c = arg2[0]; + if ((c == 'm') && (strncmp(arg2, "moveto", length) == 0)) { + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction"); + return TK_SCROLL_ERROR; + } + if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) { + return TK_SCROLL_ERROR; + } + return TK_SCROLL_MOVETO; + } else if ((c == 's') + && (strncmp(arg2, "scroll", length) == 0)) { + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "scroll number units|pages"); + return TK_SCROLL_ERROR; + } + if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) { + return TK_SCROLL_ERROR; + } + arg4 = Tcl_GetString(objv[4]); + length = (strlen(arg4)); + c = arg4[0]; + if ((c == 'p') && (strncmp(arg4, "pages", length) == 0)) { + return TK_SCROLL_PAGES; + } else if ((c == 'u') + && (strncmp(arg4, "units", length) == 0)) { + return TK_SCROLL_UNITS; + } else { + Tcl_AppendResult(interp, "bad argument \"", arg4, + "\": must be units or pages", (char *) NULL); + return TK_SCROLL_ERROR; + } + } + Tcl_AppendResult(interp, "unknown option \"", arg2, + "\": must be moveto or scroll", (char *) NULL); + return TK_SCROLL_ERROR; +} + +/* *--------------------------------------------------------------------------- * * TkComputeAnchor -- @@ -310,7 +403,7 @@ TkFindStateString(mapPtr, numKey) * Returns the numKey associated with the last element (the NULL * string one) in the table if strKey was not equal to any of the * string keys in the table. In that case, an error message is - * also left in interp->result (if interp is not NULL). + * also left in the interp's result (if interp is not NULL). * * Side effects. * None. @@ -319,29 +412,70 @@ TkFindStateString(mapPtr, numKey) */ int -TkFindStateNum(interp, field, mapPtr, strKey) +TkFindStateNum(interp, option, mapPtr, strKey) Tcl_Interp *interp; /* Interp for error reporting. */ - CONST char *field; /* String to use when constructing error. */ + CONST char *option; /* String to use when constructing error. */ CONST TkStateMap *mapPtr; /* Lookup table. */ CONST char *strKey; /* String to try to find in lookup table. */ { CONST TkStateMap *mPtr; - if (mapPtr->strKey == NULL) { - panic("TkFindStateNum: no choices in lookup table"); + for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) { + if (strcmp(strKey, mPtr->strKey) == 0) { + return mPtr->numKey; + } + } + if (interp != NULL) { + mPtr = mapPtr; + Tcl_AppendResult(interp, "bad ", option, " value \"", strKey, + "\": must be ", mPtr->strKey, (char *) NULL); + for (mPtr++; mPtr->strKey != NULL; mPtr++) { + Tcl_AppendResult(interp, + ((mPtr[1].strKey != NULL) ? ", " : ", or "), + mPtr->strKey, (char *) NULL); + } + } + return mPtr->numKey; +} + +int +TkFindStateNumObj(interp, optionPtr, mapPtr, keyPtr) + Tcl_Interp *interp; /* Interp for error reporting. */ + Tcl_Obj *optionPtr; /* String to use when constructing error. */ + CONST TkStateMap *mapPtr; /* Lookup table. */ + Tcl_Obj *keyPtr; /* String key to find in lookup table. */ +{ + CONST TkStateMap *mPtr; + CONST char *key; + CONST Tcl_ObjType *typePtr; + + if ((keyPtr->typePtr == &stateKeyType) + && (keyPtr->internalRep.twoPtrValue.ptr1 == (VOID *) mapPtr)) { + return (int) keyPtr->internalRep.twoPtrValue.ptr2; } + key = Tcl_GetStringFromObj(keyPtr, NULL); for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) { - if (strcmp(strKey, mPtr->strKey) == 0) { + if (strcmp(key, mPtr->strKey) == 0) { + typePtr = keyPtr->typePtr; + if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { + (*typePtr->freeIntRepProc)(keyPtr); + } + keyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) mapPtr; + keyPtr->internalRep.twoPtrValue.ptr2 = (VOID *) mPtr->numKey; + keyPtr->typePtr = &stateKeyType; return mPtr->numKey; } } if (interp != NULL) { mPtr = mapPtr; - Tcl_AppendResult(interp, "bad ", field, " value \"", strKey, + Tcl_AppendResult(interp, "bad ", + Tcl_GetStringFromObj(optionPtr, NULL), " value \"", key, "\": must be ", mPtr->strKey, (char *) NULL); for (mPtr++; mPtr->strKey != NULL; mPtr++) { - Tcl_AppendResult(interp, ", ", mPtr->strKey, (char *) NULL); + Tcl_AppendResult(interp, + ((mPtr[1].strKey != NULL) ? ", " : ", or "), + mPtr->strKey, (char *) NULL); } } return mPtr->numKey; diff --git a/generic/tkVisual.c b/generic/tkVisual.c index 96a2979..39b627a 100644 --- a/generic/tkVisual.c +++ b/generic/tkVisual.c @@ -6,12 +6,12 @@ * prototype implementation by Paul Mackerras. * * Copyright (c) 1994 The Regents of the University of California. - * Copyright (c) 1994-1995 Sun Microsystems, Inc. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkVisual.c,v 1.2 1998/09/14 18:23:20 stanton Exp $ + * RCS: @(#) $Id: tkVisual.c,v 1.3 1999/04/16 01:51:25 stanton Exp $ */ #include "tkInt.h" @@ -74,7 +74,7 @@ struct TkColormap { * Results: * The return value is normally a pointer to a visual. If an * error occurred in looking up the visual, NULL is returned and - * an error message is left in interp->result. The depth of the + * an error message is left in the interp's result. The depth of the * visual is returned to *depthPtr under normal returns. If * colormapPtr is non-NULL, then this procedure also finds a * suitable colormap for use with the visual in tkwin, and it @@ -243,7 +243,8 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr) visInfoList = XGetVisualInfo(Tk_Display(tkwin), mask, &template, &numVisuals); if (visInfoList == NULL) { - interp->result = "couldn't find an appropriate visual"; + Tcl_SetResult(interp, "couldn't find an appropriate visual", + TCL_STATIC); return NULL; } @@ -352,7 +353,7 @@ Tk_GetVisual(interp, tkwin, string, depthPtr, colormapPtr) * Results: * The return value is normally the X resource identifier for the * colormap. If an error occurs, None is returned and an error - * message is placed in interp->result. + * message is placed in the interp's result. * * Side effects: * A reference count is incremented for the colormap, so diff --git a/generic/tkWindow.c b/generic/tkWindow.c index d904658..ad2e4e1 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWindow.c,v 1.5 1999/03/10 07:04:44 stanton Exp $ + * RCS: @(#) $Id: tkWindow.c,v 1.6 1999/04/16 01:51:25 stanton Exp $ */ #include "tkPort.h" @@ -22,38 +22,26 @@ #include "tkUnixInt.h" #endif -/* - * Count of number of main windows currently open in this process. - */ - -static int numMainWindows; - -/* - * First in list of all main windows managed by this process. - */ - -TkMainInfo *tkMainWindowList = NULL; - -/* - * List of all displays currently in use. - */ - -TkDisplay *tkDisplayList = NULL; - -/* - * Have statics in this module been initialized? - */ -static int initialized = 0; +typedef struct ThreadSpecificData { + int numMainWindows; /* Count of numver of main windows currently + * open in this thread. */ + TkMainInfo *mainWindowList; + /* First in list of all main windows managed + * by this thread. */ + TkDisplay *displayList; + /* List of all displays currently in use by + * the current thread. */ + int initialized; /* 0 means the structures above need + * initializing. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; -/* - * The variables below hold several uid's that are used in many places - * in the toolkit. +/* + * The Mutex below is used to lock access to the Tk_Uids above. */ -Tk_Uid tkDisabledUid = NULL; -Tk_Uid tkActiveUid = NULL; -Tk_Uid tkNormalUid = NULL; +TCL_DECLARE_MUTEX(windowMutex) /* * Default values for "changes" and "atts" fields of TkWindows. Note @@ -98,6 +86,10 @@ typedef struct { int isSafe; /* If !0, this command will be exposed in * a safe interpreter. Otherwise it will be * hidden in a safe interpreter. */ + int passMainWindow; /* 0 means provide NULL clientData to + * command procedure; 1 means pass main + * window as clientData to command + * procedure. */ } TkCmd; static TkCmd commands[] = { @@ -105,62 +97,67 @@ static TkCmd commands[] = { * Commands that are part of the intrinsics: */ - {"bell", NULL, Tk_BellObjCmd, 0}, - {"bind", Tk_BindCmd, NULL, 1}, - {"bindtags", Tk_BindtagsCmd, NULL, 1}, - {"clipboard", Tk_ClipboardCmd, NULL, 0}, - {"destroy", Tk_DestroyCmd, NULL, 1}, - {"event", Tk_EventCmd, NULL, 1}, - {"focus", Tk_FocusCmd, NULL, 1}, - {"font", NULL, Tk_FontObjCmd, 1}, - {"grab", Tk_GrabCmd, NULL, 0}, - {"grid", Tk_GridCmd, NULL, 1}, - {"image", Tk_ImageCmd, NULL, 1}, - {"lower", Tk_LowerCmd, NULL, 1}, - {"option", Tk_OptionCmd, NULL, 1}, - {"pack", Tk_PackCmd, NULL, 1}, - {"place", Tk_PlaceCmd, NULL, 1}, - {"raise", Tk_RaiseCmd, NULL, 1}, - {"selection", Tk_SelectionCmd, NULL, 0}, - {"tk", NULL, Tk_TkObjCmd, 0}, - {"tkwait", Tk_TkwaitCmd, NULL, 1}, - {"tk_chooseColor", Tk_ChooseColorCmd, NULL, 0}, - {"tk_getOpenFile", Tk_GetOpenFileCmd, NULL, 0}, - {"tk_getSaveFile", Tk_GetSaveFileCmd, NULL, 0}, - {"tk_messageBox", Tk_MessageBoxCmd, NULL, 0}, - {"update", Tk_UpdateCmd, NULL, 1}, - {"winfo", NULL, Tk_WinfoObjCmd, 1}, - {"wm", Tk_WmCmd, NULL, 0}, + {"bell", NULL, Tk_BellObjCmd, 0, 1}, + {"bind", Tk_BindCmd, NULL, 1, 1}, + {"bindtags", Tk_BindtagsCmd, NULL, 1, 1}, + {"clipboard", Tk_ClipboardCmd, NULL, 0, 1}, + {"destroy", Tk_DestroyCmd, NULL, 1, 1}, + {"event", NULL, Tk_EventObjCmd, 1, 1}, + {"focus", NULL, Tk_FocusObjCmd, 1, 1}, + {"font", NULL, Tk_FontObjCmd, 1, 1}, + {"grab", Tk_GrabCmd, NULL, 0, 1}, + {"grid", Tk_GridCmd, NULL, 1, 1}, + {"image", Tk_ImageCmd, NULL, 1, 1}, + {"lower", Tk_LowerCmd, NULL, 1, 1}, + {"option", Tk_OptionCmd, NULL, 1, 1}, + {"pack", Tk_PackCmd, NULL, 1, 1}, + {"place", Tk_PlaceCmd, NULL, 1, 1}, + {"raise", Tk_RaiseCmd, NULL, 1, 1}, + {"selection", Tk_SelectionCmd, NULL, 0, 1}, + {"tk", NULL, Tk_TkObjCmd, 0, 1}, + {"tkwait", Tk_TkwaitCmd, NULL, 1, 1}, +#if defined(__WIN32__) || defined(MAC_TCL) + {"tk_chooseColor", NULL, Tk_ChooseColorObjCmd, 0, 1}, + {"tk_chooseDirectory", NULL, Tk_ChooseDirectoryObjCmd, 0, 1}, + {"tk_getOpenFile", NULL, Tk_GetOpenFileObjCmd, 0, 1}, + {"tk_getSaveFile", NULL, Tk_GetSaveFileObjCmd, 0, 1}, +#endif +#ifdef __WIN32__ + {"tk_messageBox", NULL, Tk_MessageBoxObjCmd, 0, 1}, +#endif + {"update", NULL, Tk_UpdateObjCmd, 1, 1}, + {"winfo", NULL, Tk_WinfoObjCmd, 1, 1}, + {"wm", Tk_WmCmd, NULL, 0, 1}, /* * Widget class commands. */ - {"button", Tk_ButtonCmd, NULL, 1}, - {"canvas", Tk_CanvasCmd, NULL, 1}, - {"checkbutton", Tk_CheckbuttonCmd, NULL, 1}, - {"entry", Tk_EntryCmd, NULL, 1}, - {"frame", Tk_FrameCmd, NULL, 1}, - {"label", Tk_LabelCmd, NULL, 1}, - {"listbox", Tk_ListboxCmd, NULL, 1}, - {"menu", Tk_MenuCmd, NULL, 0}, - {"menubutton", Tk_MenubuttonCmd, NULL, 1}, - {"message", Tk_MessageCmd, NULL, 1}, - {"radiobutton", Tk_RadiobuttonCmd, NULL, 1}, - {"scale", Tk_ScaleCmd, NULL, 1}, - {"scrollbar", Tk_ScrollbarCmd, NULL, 1}, - {"text", Tk_TextCmd, NULL, 1}, - {"toplevel", Tk_ToplevelCmd, NULL, 0}, + + {"button", NULL, Tk_ButtonObjCmd, 1, 0}, + {"canvas", Tk_CanvasCmd, NULL, 1, 1}, + {"checkbutton", NULL, Tk_CheckbuttonObjCmd, 1, 0}, + {"entry", NULL, Tk_EntryObjCmd, 1, 0}, + {"frame", Tk_FrameCmd, NULL, 1, 1}, + {"label", NULL, Tk_LabelObjCmd, 1, 0}, + {"listbox", Tk_ListboxCmd, NULL, 1, 1}, + {"menubutton", NULL, Tk_MenubuttonObjCmd, 1, 0}, + {"message", Tk_MessageCmd, NULL, 1, 1}, + {"radiobutton", NULL, Tk_RadiobuttonObjCmd, 1, 0}, + {"scale", NULL, Tk_ScaleObjCmd, 1, 0}, + {"scrollbar", Tk_ScrollbarCmd, NULL, 1, 1}, + {"text", Tk_TextCmd, NULL, 1, 1}, + {"toplevel", Tk_ToplevelCmd, NULL, 0, 1}, /* * Misc. */ #ifdef MAC_TCL - {"unsupported1", TkUnsupported1Cmd, NULL, 1}, + {"unsupported1", TkUnsupported1Cmd, NULL, 1, 1}, #endif {(char *) NULL, (int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **))) NULL, NULL, 0} }; - + /* * The variables and table below are used to parse arguments from * the "argv" variable in Tk_Init. @@ -225,7 +222,7 @@ static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr)); * The return value is a token for the new window, or NULL if * an error prevented the new window from being created. If * NULL is returned, an error message will be left in - * interp->result. + * the interp's result. * * Side effects: * A new window structure is allocated locally. An X @@ -253,12 +250,11 @@ CreateTopLevelWindow(interp, parent, name, screenName) register TkWindow *winPtr; register TkDisplay *dispPtr; int screenId; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - if (!initialized) { - initialized = 1; - tkActiveUid = Tk_GetUid("active"); - tkDisabledUid = Tk_GetUid("disabled"); - tkNormalUid = Tk_GetUid("normal"); + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; /* * Create built-in image types. @@ -335,7 +331,7 @@ CreateTopLevelWindow(interp, parent, name, screenName) * Results: * The return value is a pointer to information about the display, * or NULL if the display couldn't be opened. In this case, an - * error message is left in interp->result. The location at + * error message is left in the interp's result. The location at * *screenPtr is overwritten with the screen number parsed from * screenName. * @@ -358,6 +354,8 @@ GetScreen(interp, screenName, screenPtr) char *p; int screenId; size_t length; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Separate the screen number from the rest of the display @@ -368,8 +366,9 @@ GetScreen(interp, screenName, screenPtr) screenName = TkGetDefaultScreenName(interp, screenName); if (screenName == NULL) { - interp->result = - "no display name and no $DISPLAY environment variable"; + Tcl_SetResult(interp, + "no display name and no $DISPLAY environment variable", + TCL_STATIC); return (TkDisplay *) NULL; } length = strlen(screenName); @@ -388,7 +387,7 @@ GetScreen(interp, screenName, screenPtr) * then open a new connection. */ - for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) { + for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { if (dispPtr == NULL) { dispPtr = TkpOpenDisplay(screenName); if (dispPtr == NULL) { @@ -396,29 +395,35 @@ GetScreen(interp, screenName, screenPtr) screenName, "\"", (char *) NULL); return (TkDisplay *) NULL; } - dispPtr->nextPtr = tkDisplayList; + dispPtr->nextPtr = TkGetDisplayList(); dispPtr->name = (char *) ckalloc((unsigned) (length+1)); dispPtr->lastEventTime = CurrentTime; - strncpy(dispPtr->name, screenName, length); - dispPtr->name[length] = '\0'; + dispPtr->borderInit = 0; + dispPtr->atomInit = 0; dispPtr->bindInfoStale = 1; dispPtr->modeModMask = 0; dispPtr->metaModMask = 0; dispPtr->altModMask = 0; dispPtr->numModKeyCodes = 0; dispPtr->modKeyCodes = NULL; - OpenIM(dispPtr); + dispPtr->bitmapInit = 0; + dispPtr->bitmapAutoNumber = 0; + dispPtr->numIdSearches = 0; + dispPtr->numSlowSearches = 0; + dispPtr->colorInit = 0; + dispPtr->stressPtr = NULL; + dispPtr->cursorInit = 0; + dispPtr->cursorString[0] = '\0'; + dispPtr->cursorFont = None; dispPtr->errorPtr = NULL; dispPtr->deleteCount = 0; - dispPtr->commTkwin = NULL; - dispPtr->selectionInfoPtr = NULL; - dispPtr->multipleAtom = None; - dispPtr->clipWindow = NULL; - dispPtr->clipboardActive = 0; - dispPtr->clipboardAppPtr = NULL; - dispPtr->clipTargetPtr = NULL; - dispPtr->atomInit = 0; - dispPtr->cursorFont = None; + dispPtr->delayedMotionPtr = NULL; + dispPtr->focusDebug = 0; + dispPtr->implicitWinPtr = NULL; + dispPtr->focusPtr = NULL; + dispPtr->gcInit = 0; + dispPtr->geomInit = 0; + dispPtr->uidInit = 0; dispPtr->grabWinPtr = NULL; dispPtr->eventualGrabWinPtr = NULL; dispPtr->buttonWinPtr = NULL; @@ -426,18 +431,32 @@ GetScreen(interp, screenName, screenPtr) dispPtr->firstGrabEventPtr = NULL; dispPtr->lastGrabEventPtr = NULL; dispPtr->grabFlags = 0; - TkInitXId(dispPtr); + dispPtr->gridInit = 0; + dispPtr->imageId = 0; + dispPtr->packInit = 0; + dispPtr->placeInit = 0; + dispPtr->selectionInfoPtr = NULL; + dispPtr->multipleAtom = None; + dispPtr->clipWindow = NULL; + dispPtr->clipboardActive = 0; + dispPtr->clipboardAppPtr = NULL; + dispPtr->clipTargetPtr = NULL; + dispPtr->commTkwin = NULL; + dispPtr->wmTracing = 0; + dispPtr->firstWmPtr = NULL; + dispPtr->foregroundWmPtr = NULL; dispPtr->destroyCount = 0; dispPtr->lastDestroyRequest = 0; dispPtr->cmapPtr = NULL; - dispPtr->implicitWinPtr = NULL; - dispPtr->focusPtr = NULL; - dispPtr->stressPtr = NULL; - dispPtr->delayedMotionPtr = NULL; Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS); + dispPtr->refCount = 0; - - tkDisplayList = dispPtr; + strncpy(dispPtr->name, screenName, length); + dispPtr->name[length] = '\0'; + OpenIM(dispPtr); + TkInitXId(dispPtr); + + tsdPtr->displayList = dispPtr; break; } if ((strncmp(dispPtr->name, screenName, length) == 0) @@ -446,7 +465,10 @@ GetScreen(interp, screenName, screenPtr) } } if (screenId >= ScreenCount(dispPtr->display)) { - sprintf(interp->result, "bad screen number \"%d\"", screenId); + char buf[32 + TCL_INTEGER_SPACE]; + + sprintf(buf, "bad screen number \"%d\"", screenId); + Tcl_SetResult(interp, buf, TCL_VOLATILE); return (TkDisplay *) NULL; } *screenPtr = screenId; @@ -476,8 +498,10 @@ TkGetDisplay(display) Display *display; /* X's display pointer */ { TkDisplay *dispPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - for (dispPtr = tkDisplayList; dispPtr != NULL; + for (dispPtr = tsdPtr->displayList; dispPtr != NULL; dispPtr = dispPtr->nextPtr) { if (dispPtr->display == display) { break; @@ -489,6 +513,58 @@ TkGetDisplay(display) /* *-------------------------------------------------------------- * + * TkGetDisplayList -- + * + * This procedure returns a pointer to the thread-local + * list of TkDisplays corresponding to the open displays. + * + * Results: + * The return value is a pointer to the first TkDisplay + * structure in thread-local-storage. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +TkDisplay * +TkGetDisplayList() +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + return tsdPtr->displayList; +} + +/* + *-------------------------------------------------------------- + * + * TkGetMainInfoList -- + * + * This procedure returns a pointer to the list of structures + * containing information about all main windows for the + * current thread. + * + * Results: + * The return value is a pointer to the first TkMainInfo + * structure in thread local storage. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +TkMainInfo * +TkGetMainInfoList() +{ + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + return tsdPtr->mainWindowList; +} +/* + *-------------------------------------------------------------- + * * TkAllocWindow -- * * This procedure creates and initializes a TkWindow structure. @@ -679,7 +755,7 @@ NameWindow(interp, winPtr, parentPtr, name) * The return value is a token for the new window, or NULL if * an error prevented the new window from being created. If * NULL is returned, an error message will be left in - * interp->result. + * the interp's result. * * Side effects: * A new window structure is allocated locally; "interp" is @@ -707,6 +783,9 @@ TkCreateMainWindow(interp, screenName, baseName) register TkMainInfo *mainPtr; register TkWindow *winPtr; register TkCmd *cmdPtr; + ClientData clientData; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Panic if someone updated the TkWindow structure without @@ -738,6 +817,7 @@ TkCreateMainWindow(interp, screenName, baseName) mainPtr->refCount = 1; mainPtr->interp = interp; Tcl_InitHashTable(&mainPtr->nameTable, TCL_STRING_KEYS); + TkEventInit(); TkBindInit(mainPtr); TkFontPkgInit(mainPtr); mainPtr->tlFocusPtr = NULL; @@ -749,8 +829,8 @@ TkCreateMainWindow(interp, screenName, baseName) TCL_LINK_BOOLEAN) != TCL_OK) { Tcl_ResetResult(interp); } - mainPtr->nextPtr = tkMainWindowList; - tkMainWindowList = mainPtr; + mainPtr->nextPtr = tsdPtr->mainWindowList; + tsdPtr->mainWindowList = mainPtr; winPtr->mainPtr = mainPtr; hPtr = Tcl_CreateHashEntry(&mainPtr->nameTable, ".", &dummy); Tcl_SetHashValue(hPtr, winPtr); @@ -778,12 +858,17 @@ TkCreateMainWindow(interp, screenName, baseName) if ((cmdPtr->cmdProc == NULL) && (cmdPtr->objProc == NULL)) { panic("TkCreateMainWindow: builtin command with NULL string and object procs"); } + if (cmdPtr->passMainWindow) { + clientData = (ClientData) tkwin; + } else { + clientData = (ClientData) NULL; + } if (cmdPtr->cmdProc != NULL) { Tcl_CreateCommand(interp, cmdPtr->name, cmdPtr->cmdProc, - (ClientData) tkwin, (void (*) _ANSI_ARGS_((ClientData))) NULL); + clientData, (void (*) _ANSI_ARGS_((ClientData))) NULL); } else { Tcl_CreateObjCommand(interp, cmdPtr->name, cmdPtr->objProc, - (ClientData) tkwin, NULL); + clientData, NULL); } if (isSafe) { if (!(cmdPtr->isSafe)) { @@ -792,6 +877,8 @@ TkCreateMainWindow(interp, screenName, baseName) } } + TkCreateMenuCmd(interp); + /* * Set variables for the intepreter. */ @@ -799,7 +886,7 @@ TkCreateMainWindow(interp, screenName, baseName) Tcl_SetVar(interp, "tk_patchLevel", TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tk_version", TK_VERSION, TCL_GLOBAL_ONLY); - numMainWindows++; + tsdPtr->numMainWindows++; return tkwin; } @@ -815,7 +902,7 @@ TkCreateMainWindow(interp, screenName, baseName) * The return value is a token for the new window. This * is not the same as X's token for the window. If an error * occurred in creating the window (e.g. no such display or - * screen), then an error message is left in interp->result and + * screen), then an error message is left in the interp's result and * NULL is returned. * * Side effects: @@ -829,7 +916,7 @@ TkCreateMainWindow(interp, screenName, baseName) Tk_Window Tk_CreateWindow(interp, parent, name, screenName) Tcl_Interp *interp; /* Interpreter to use for error reporting. - * Interp->result is assumed to be + * the interp's result is assumed to be * initialized by the caller. */ Tk_Window parent; /* Token for parent of new window. */ char *name; /* Name for new window. Must be unique @@ -882,7 +969,7 @@ Tk_CreateWindow(interp, parent, name, screenName) * The return value is a token for the new window. This * is not the same as X's token for the window. If an error * occurred in creating the window (e.g. no such display or - * screen), then an error message is left in interp->result and + * screen), then an error message is left in the interp's result and * NULL is returned. * * Side effects: @@ -896,7 +983,7 @@ Tk_CreateWindow(interp, parent, name, screenName) Tk_Window Tk_CreateWindowFromPath(interp, tkwin, pathName, screenName) Tcl_Interp *interp; /* Interpreter to use for error reporting. - * Interp->result is assumed to be + * the interp's result is assumed to be * initialized by the caller. */ Tk_Window tkwin; /* Token for any window in application * that is to contain new window. */ @@ -1015,6 +1102,8 @@ Tk_DestroyWindow(tkwin) TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; XEvent event; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->flags & TK_ALREADY_DEAD) { /* @@ -1058,19 +1147,19 @@ Tk_DestroyWindow(tkwin) if (winPtr->mainPtr->winPtr == winPtr) { dispPtr->refCount--; - if (tkMainWindowList == winPtr->mainPtr) { - tkMainWindowList = winPtr->mainPtr->nextPtr; + if (tsdPtr->mainWindowList == winPtr->mainPtr) { + tsdPtr->mainWindowList = winPtr->mainPtr->nextPtr; } else { TkMainInfo *prevPtr; - for (prevPtr = tkMainWindowList; + for (prevPtr = tsdPtr->mainWindowList; prevPtr->nextPtr != winPtr->mainPtr; prevPtr = prevPtr->nextPtr) { /* Empty loop body. */ } prevPtr->nextPtr = winPtr->mainPtr->nextPtr; } - numMainWindows--; + tsdPtr->numMainWindows--; } /* @@ -1226,8 +1315,8 @@ Tk_DestroyWindow(tkwin) Tcl_DeleteHashTable(&winPtr->mainPtr->nameTable); TkBindFree(winPtr->mainPtr); - TkFontPkgFree(winPtr->mainPtr); TkDeleteAllImages(winPtr->mainPtr); + TkFontPkgFree(winPtr->mainPtr); /* * When embedding Tk into other applications, make sure @@ -1261,7 +1350,7 @@ Tk_DestroyWindow(tkwin) * Splice this display out of the list of displays. */ - for (theDispPtr = tkDisplayList, backDispPtr = NULL; + for (theDispPtr = displayList, backDispPtr = NULL; (theDispPtr != winPtr->dispPtr) && (theDispPtr != NULL); theDispPtr = theDispPtr->nextPtr) { @@ -1271,7 +1360,7 @@ Tk_DestroyWindow(tkwin) panic("could not find display to close!"); } if (backDispPtr == NULL) { - tkDisplayList = theDispPtr->nextPtr; + displayList = theDispPtr->nextPtr; } else { backDispPtr->nextPtr = theDispPtr->nextPtr; } @@ -1997,7 +2086,7 @@ TkSetClassProcs(tkwin, procs, instanceData) * Results: * The return result is either a token for the window corresponding * to "name", or else NULL to indicate that there is no such - * window. In this case, an error message is left in interp->result. + * window. In this case, an error message is left in the interp's result. * * Side effects: * None. @@ -2052,7 +2141,7 @@ Tk_IdToWindow(display, window) TkDisplay *dispPtr; Tcl_HashEntry *hPtr; - for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) { + for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) { if (dispPtr == NULL) { return NULL; } @@ -2278,7 +2367,7 @@ Tk_RestackWindow(tkwin, aboveBelow, other) * Results: * If interp has a Tk application associated with it, the main * window for the application is returned. Otherwise NULL is - * returned and an error message is left in interp->result. + * returned and an error message is left in the interp's result. * * Side effects: * None. @@ -2293,14 +2382,16 @@ Tk_MainWindow(interp) * reporting also. */ { TkMainInfo *mainPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - for (mainPtr = tkMainWindowList; mainPtr != NULL; + for (mainPtr = tsdPtr->mainWindowList; mainPtr != NULL; mainPtr = mainPtr->nextPtr) { if (mainPtr->interp == interp) { return (Tk_Window) mainPtr->winPtr; } } - interp->result = "this isn't a Tk application"; + Tcl_SetResult(interp, "this isn't a Tk application", TCL_STATIC); return NULL; } @@ -2411,7 +2502,10 @@ OpenIM(dispPtr) int Tk_GetNumMainWindows() { - return numMainWindows; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + return tsdPtr->numMainWindows; } /* @@ -2437,8 +2531,10 @@ DeleteWindowsExitProc(clientData) { TkDisplay *displayPtr, *nextPtr; Tcl_Interp *interp; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); - while (tkMainWindowList != NULL) { + while (tsdPtr->mainWindowList != NULL) { /* * We must protect the interpreter while deleting the window, * because of <Destroy> bindings which could destroy the interpreter @@ -2446,14 +2542,14 @@ DeleteWindowsExitProc(clientData) * the call stack pointing at deleted memory, causing core dumps. */ - interp = tkMainWindowList->winPtr->mainPtr->interp; + interp = tsdPtr->mainWindowList->winPtr->mainPtr->interp; Tcl_Preserve((ClientData) interp); - Tk_DestroyWindow((Tk_Window) tkMainWindowList->winPtr); + Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); Tcl_Release((ClientData) interp); } - displayPtr = tkDisplayList; - tkDisplayList = NULL; + displayPtr = tsdPtr->displayList; + tsdPtr->displayList = NULL; /* * Iterate destroying the displays until no more displays remain. @@ -2462,9 +2558,9 @@ DeleteWindowsExitProc(clientData) * as well as the old ones. */ - for (displayPtr = tkDisplayList; + for (displayPtr = tsdPtr->displayList; displayPtr != NULL; - displayPtr = tkDisplayList) { + displayPtr = tsdPtr->displayList) { /* * Now iterate over the current list of open displays, and first @@ -2475,7 +2571,8 @@ DeleteWindowsExitProc(clientData) * if it needs to dispatch a message. */ - for (tkDisplayList = NULL; displayPtr != NULL; displayPtr = nextPtr) { + for (tsdPtr->displayList = NULL; displayPtr != NULL; + displayPtr = nextPtr) { nextPtr = displayPtr->nextPtr; if (displayPtr->name != (char *) NULL) { ckfree(displayPtr->name); @@ -2485,12 +2582,9 @@ DeleteWindowsExitProc(clientData) } } - numMainWindows = 0; - tkMainWindowList = NULL; - initialized = 0; - tkDisabledUid = NULL; - tkActiveUid = NULL; - tkNormalUid = NULL; + tsdPtr->numMainWindows = 0; + tsdPtr->mainWindowList = NULL; + tsdPtr->initialized = 0; } /* @@ -2508,7 +2602,7 @@ DeleteWindowsExitProc(clientData) * the arguments that are extracted). * * Results: - * Returns a standard Tcl completion code and sets interp->result + * Returns a standard Tcl completion code and sets the interp's result * if there is an error. * * Side effects: @@ -2533,7 +2627,7 @@ Tk_Init(interp) * invokes the internal procedure that does the real work. * * Results: - * Returns a standard Tcl completion code and sets interp->result + * Returns a standard Tcl completion code and sets the interp's result * if there is an error. * * Side effects: @@ -2586,6 +2680,9 @@ Tk_SafeInit(interp) return Initialize(interp); } + +extern TkStubs tkStubs; + /* *---------------------------------------------------------------------- * @@ -2593,8 +2690,8 @@ Tk_SafeInit(interp) * * * Results: - * A standard Tcl result. Also leaves an error message in interp->result - * if there was an error. + * A standard Tcl result. Also leaves an error message in the interp's + * result if there was an error. * * Side effects: * Depends on the initialization scripts that are invoked. @@ -2610,8 +2707,8 @@ Initialize(interp) int argc, code; char **argv, *args[20]; Tcl_DString class; - char buffer[30]; - + ThreadSpecificData *tsdPtr; + /* * Ensure that we are getting the matching version of Tcl. This is * really only an issue when Tk is loaded dynamically. @@ -2620,13 +2717,17 @@ Initialize(interp) if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL) { return TCL_ERROR; } - + + tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + /* * Start by initializing all the static variables to default acceptable * values so that no information is leaked from a previous run of this * code. */ + Tcl_MutexLock(&windowMutex); synchronize = 0; name = NULL; display = NULL; @@ -2661,6 +2762,7 @@ Initialize(interp) if (master == NULL) { Tcl_DStringFree(&ds); Tcl_AppendResult(interp, "NULL master", (char *) NULL); + Tcl_MutexUnlock(&windowMutex); return TCL_ERROR; } if (!Tcl_IsSafe(master)) { @@ -2674,6 +2776,7 @@ Initialize(interp) if (Tcl_GetInterpPath(master, interp) != TCL_OK) { Tcl_AppendResult(interp, "error in Tcl_GetInterpPath", (char *) NULL); + Tcl_MutexUnlock(&windowMutex); return TCL_ERROR; } /* @@ -2697,6 +2800,7 @@ Initialize(interp) Tcl_AppendResult(interp, "not allowed to start Tk by master's safe::TkInit", (char *) NULL); + Tcl_MutexUnlock(&windowMutex); return TCL_ERROR; } Tcl_DStringFree(&ds); @@ -2718,10 +2822,13 @@ Initialize(interp) } argv = NULL; if (p != NULL) { + char buffer[TCL_INTEGER_SPACE]; + if (Tcl_SplitList(interp, p, &argc, &argv) != TCL_OK) { argError: Tcl_AddErrorInfo(interp, "\n (processing arguments in argv variable)"); + Tcl_MutexUnlock(&windowMutex); return TCL_ERROR; } if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, @@ -2754,8 +2861,8 @@ Initialize(interp) } p = Tcl_DStringValue(&class); - if (islower(UCHAR(*p))) { - *p = toupper(UCHAR(*p)); + if (*p) { + Tcl_UtfToTitle(p); } /* @@ -2779,7 +2886,7 @@ Initialize(interp) * that it will be available to subprocesses created by us. */ - if (numMainWindows == 0) { + if (tsdPtr->numMainWindows == 0) { Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY); } } @@ -2826,6 +2933,8 @@ Initialize(interp) } geometry = NULL; } + Tcl_MutexUnlock(&windowMutex); + if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) { code = TCL_ERROR; goto done; @@ -2835,11 +2944,17 @@ Initialize(interp) * Provide Tk and its stub table. */ - code = Tcl_PkgProvideEx(interp, "Tk", TK_VERSION, (ClientData) tkStubsPtr); + code = Tcl_PkgProvideEx(interp, "Tk", TK_VERSION, (ClientData) &tkStubs); if (code != TCL_OK) { goto done; } +#ifdef Tk_InitStubs +#undef Tk_InitStubs +#endif + + Tk_InitStubs(interp, TK_VERSION, 1); + /* * Invoke platform-specific initialization. */ |